amc:ss2023:group-u:start
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
amc:ss2023:group-u:start [2023/07/23 22:06] – daniel-jose.centeno-gonzalez | amc:ss2023:group-u:start [2023/07/23 22:15] (current) – daniel-jose.centeno-gonzalez | ||
---|---|---|---|
Line 7: | Line 7: | ||
- | ^{{: | + | ^{{: |
| **Fig.:** HSRW Portable Weather Station | | **Fig.:** HSRW Portable Weather Station | ||
Line 55: | Line 55: | ||
The countPulse() function is responsible for measuring the wind speed using an anemometer. The anemometer is designed to generate pulses when driven by the wind. Each time a pulse is detected, a counter representing the number of pulses generated by the anemometer in a specified time interval is incremented. The loop() function then calculates the wind speed from the number of pulses and a scale factor based on the anemometer' | The countPulse() function is responsible for measuring the wind speed using an anemometer. The anemometer is designed to generate pulses when driven by the wind. Each time a pulse is detected, a counter representing the number of pulses generated by the anemometer in a specified time interval is incremented. The loop() function then calculates the wind speed from the number of pulses and a scale factor based on the anemometer' | ||
- | **Data Logging:** Every five minutes, the sensor readings are saved to a CSV file on the SD card. The data includes the timestamp, temperature, | + | **Data Logging:** |
+ | |||
+ | **SaveFun()** Every five minutes, the sensor readings are saved to a CSV file on the SD card. The data includes the timestamp, temperature, | ||
======Raw Code====== | ======Raw Code====== | ||
- | {{ :amc:ss2023:group-u:ultimateprogram_weatherstation.rar|}} | + | <code C++> |
+ | /* Tittle: Portable Weather Station | ||
+ | * Autors: Daniel Centeno | ||
+ | | ||
+ | * | ||
+ | * Version: 2.7.9 | ||
+ | */ | ||
+ | |||
+ | // | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // | ||
+ | File dataFile; | ||
+ | const int chipSelect = 15; // Chip select pin connected to SD card breakout board | ||
+ | |||
+ | // | ||
+ | Adafruit_ADS1115 ads; | ||
+ | |||
+ | // | ||
+ | // | ||
+ | |||
+ | #define DHTPIN 2 // Pin connected to the DHT22 sensor D4 | ||
+ | #define DHTTYPE DHT22 // DHT sensor type | ||
+ | DHT dht(DHTPIN, DHTTYPE); | ||
+ | |||
+ | float temperature = 0; | ||
+ | float humidity = 0; | ||
+ | float heatIndex = 0; | ||
+ | |||
+ | // | ||
+ | //Variables for the UV sensor | ||
+ | int uvPercentage = 0; | ||
+ | |||
+ | |||
+ | // | ||
+ | //All WiFi configuration | ||
+ | // Replace with your network credentials | ||
+ | const char* ssid = " | ||
+ | const char* password = " | ||
+ | |||
+ | // Set web server port number to 80 | ||
+ | WiFiServer server(80); | ||
+ | |||
+ | // Variable to store the HTTP request | ||
+ | String header; | ||
+ | |||
+ | // Current time | ||
+ | unsigned long WiFicurrentTime = millis(); | ||
+ | // Previous time | ||
+ | unsigned long WiFipreviousTime = 0; | ||
+ | // Define timeout time in milliseconds (example: 2000ms = 2s) | ||
+ | const long WiFitimeoutTime = 2000; | ||
+ | |||
+ | // | ||
+ | //Pines kit Weater Station | ||
+ | #define PIN_RAIN 0 //D3 | ||
+ | #define SDA 4 // | ||
+ | #define SCL 5 //D1 | ||
+ | |||
+ | // | ||
+ | |||
+ | volatile int numRevsAnemometer = 0; | ||
+ | volatile int numTipsRain = 0; | ||
+ | float totalRain = 0; | ||
+ | |||
+ | // | ||
+ | |||
+ | unsigned long previousMillis = 0; // Stores the last time the sensor was read | ||
+ | const long interval = 1000; // Read sensor every 1 second | ||
+ | unsigned long currentMillis = 0; // Variable where will stores the current millis | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | void countRain(); | ||
+ | |||
+ | void ICACHE_RAM_ATTR countRain() | ||
+ | | ||
+ | } | ||
+ | |||
+ | // | ||
+ | |||
+ | unsigned long previousMillis2 = 0; // Stores the last time the sensor was read | ||
+ | const long interval2 = 1500; // Read sensor every 1 second | ||
+ | unsigned long currentMillis2 = 0; // Variable where will stores the current millis | ||
+ | |||
+ | //Wind Dir | ||
+ | char WinDirVariable[3]; | ||
+ | |||
+ | // | ||
+ | |||
+ | unsigned long lastWindCheck2 = 0; | ||
+ | unsigned long currentTime2 = 0; | ||
+ | int Tolerance = 300; | ||
+ | int ValuemV = 0; | ||
+ | |||
+ | // | ||
+ | |||
+ | unsigned long currentTimeSave = 0; | ||
+ | |||
+ | // | ||
+ | |||
+ | int anemometerPin = 3; | ||
+ | volatile unsigned long windCount = 0; | ||
+ | unsigned long lastWindCheckWind = 0; | ||
+ | float windSpeed = 0; | ||
+ | |||
+ | void ICACHE_RAM_ATTR countPulse() | ||
+ | windCount++; | ||
+ | } | ||
+ | |||
+ | // | ||
+ | |||
+ | void setup() { | ||
+ | // put your setup code here, to run once: | ||
+ | Serial.begin(9600); | ||
+ | dht.begin(); | ||
+ | ads.begin(); | ||
+ | |||
+ | pinMode(PIN_RAIN, | ||
+ | attachInterrupt(digitalPinToInterrupt(PIN_RAIN), | ||
+ | |||
+ | pinMode(anemometerPin, | ||
+ | attachInterrupt(digitalPinToInterrupt(anemometerPin), | ||
+ | |||
+ | bool status; | ||
+ | // Connect to Wi-Fi network with SSID and password | ||
+ | Serial.print(" | ||
+ | Serial.println(ssid); | ||
+ | WiFi.begin(ssid, | ||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | delay(500); | ||
+ | Serial.print(" | ||
+ | } | ||
+ | // Print local IP address and start web server | ||
+ | Serial.println("" | ||
+ | Serial.println(" | ||
+ | Serial.println(" | ||
+ | Serial.println(WiFi.localIP()); | ||
+ | server.begin(); | ||
+ | |||
+ | // Initialize SD card | ||
+ | if (!SD.begin(chipSelect)) { | ||
+ | Serial.println(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // Open the data file in append mode | ||
+ | dataFile = SD.open(" | ||
+ | |||
+ | if (dataFile) { | ||
+ | // Write headers to the file | ||
+ | dataFile.println(" | ||
+ | dataFile.close(); | ||
+ | Serial.println(" | ||
+ | } else { | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // put your main code here, to run repeatedly: | ||
+ | |||
+ | // | ||
+ | |||
+ | WiFiClient client = server.available(); | ||
+ | |||
+ | if (client) { // If a new client connects, | ||
+ | WiFicurrentTime = millis(); | ||
+ | WiFipreviousTime = WiFicurrentTime; | ||
+ | Serial.println(" | ||
+ | String currentLine = ""; | ||
+ | while (client.connected() && WiFicurrentTime | ||
+ | WiFicurrentTime = millis(); | ||
+ | if (client.available()) { // if there' | ||
+ | char c = client.read(); | ||
+ | Serial.write(c); | ||
+ | header += c; | ||
+ | if (c == ' | ||
+ | // if the current line is blank, you got two newline characters in a row. | ||
+ | // that's the end of the client HTTP request, so send a response: | ||
+ | if (currentLine.length() == 0) { | ||
+ | // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) | ||
+ | // and a content-type so the client knows what's coming, then a blank line: | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(); | ||
+ | |||
+ | // Display the HTML web page | ||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println("< | ||
+ | // CSS to style the table | ||
+ | client.println("< | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | client.println(" | ||
+ | |||
+ | // Web Page Heading | ||
+ | client.println("</ | ||
+ | client.println("< | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(temperature); | ||
+ | client.println(" | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(humidity); | ||
+ | client.println(" | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(heatIndex); | ||
+ | client.println(" | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(totalRain); | ||
+ | client.println(" | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(windSpeed); | ||
+ | client.println(" | ||
+ | |||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(WinDirVariable); | ||
+ | client.println("</ | ||
+ | |||
+ | client.println("< | ||
+ | client.println("< | ||
+ | client.println(uvPercentage); | ||
+ | client.println("</ | ||
+ | client.println("</ | ||
+ | |||
+ | // The HTTP response ends with another blank line | ||
+ | client.println(); | ||
+ | // Break out of the while loop | ||
+ | break; | ||
+ | } else { // if you got a newline, then clear currentLine | ||
+ | currentLine = ""; | ||
+ | } | ||
+ | } else if (c != ' | ||
+ | currentLine += c; // add it to the end of the currentLine | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // Clear the header variable | ||
+ | header = ""; | ||
+ | // Close the connection | ||
+ | client.stop(); | ||
+ | Serial.println(" | ||
+ | Serial.println("" | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | |||
+ | currentMillis = millis(); | ||
+ | if (currentMillis - previousMillis >= interval) { | ||
+ | previousMillis = currentMillis; | ||
+ | |||
+ | read_Temp_Humi(); | ||
+ | } | ||
+ | |||
+ | getRainfall(); | ||
+ | |||
+ | |||
+ | unsigned long currentTimeWind = millis(); | ||
+ | |||
+ | if (currentTimeWind - lastWindCheckWind >= 1000) { | ||
+ | detachInterrupt(digitalPinToInterrupt(anemometerPin)); | ||
+ | |||
+ | // Calculate the Wind Speed | ||
+ | windSpeed = (float)windCount / 2.4; // Sets the scale factor based on the anemometer calibration | ||
+ | windCount = 0; // Reset pulse counter | ||
+ | lastWindCheckWind = currentTimeWind; | ||
+ | |||
+ | attachInterrupt(digitalPinToInterrupt(anemometerPin), | ||
+ | } | ||
+ | |||
+ | currentMillis2 = millis(); | ||
+ | if (currentMillis2 - previousMillis2 >= interval2) { | ||
+ | previousMillis2 = currentMillis2; | ||
+ | |||
+ | UV_WindDir(); | ||
+ | } | ||
+ | |||
+ | |||
+ | //Uncomment to see the values through the serial port | ||
+ | //unsigned long currentTime2 = millis(); | ||
+ | //if (currentTime2 - lastWindCheck2 >= 2000) { | ||
+ | // lastWindCheck2 = currentTime2; | ||
+ | // FunPrint(); | ||
+ | //} | ||
+ | |||
+ | // Get current timestamp | ||
+ | currentTimeSave = millis(); | ||
+ | |||
+ | // Check if 5 minutes have passed | ||
+ | if (currentTimeSave % (5 * 60 * 1000) == 0) { | ||
+ | |||
+ | SaveFun(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | void getRainfall(){ | ||
+ | int tips = numTipsRain; | ||
+ | numTipsRain = 0; | ||
+ | |||
+ | float rainfall = tips * 0.2794; | ||
+ | totalRain += rainfall; | ||
+ | } | ||
+ | |||
+ | void read_Temp_Humi(){ | ||
+ | |||
+ | humidity = dht.readHumidity(); | ||
+ | temperature = dht.readTemperature(); | ||
+ | |||
+ | if (isnan(humidity) | ||
+ | Serial.println(" | ||
+ | return; | ||
+ | | ||
+ | |||
+ | heatIndex = calculateHeatIndex(temperature, | ||
+ | } | ||
+ | |||
+ | float calculateHeatIndex(float temperature, | ||
+ | // Heat index calculation (Steadman' | ||
+ | float hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (humidity * 0.094)); | ||
+ | |||
+ | if (hi > temperature) { | ||
+ | return hi; | ||
+ | } else { | ||
+ | return temperature; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void UV_WindDir(){ | ||
+ | |||
+ | int16_t UVSensor, WindDir; | ||
+ | |||
+ | UVSensor = ads.readADC_SingleEnded(0); | ||
+ | // Map the analog value to a scale from 0 to 11 | ||
+ | uvPercentage = map(UVSensor, | ||
+ | |||
+ | WindDir = ads.readADC_SingleEnded(1); | ||
+ | ValuemV = ads.readADC_SingleEnded(1); | ||
+ | if(WindDir >= (4960-600) && WindDir <= (4960+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (10860-600) && WindDir <= (10860+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (16693-550) && WindDir <= (16693+550)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (15686-350) && WindDir <= (15686+350)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (13590-600) && WindDir <= (13590+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (7960-600) && WindDir <= (7960+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (1600-600) && WindDir <= (1600+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | else if(WindDir >= (3170-600) && WindDir <= (3170+600)){ | ||
+ | strcpy(WinDirVariable, | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | void FunPrint(){ | ||
+ | |||
+ | //Imprimir Relativity Tem and Hum | ||
+ | Serial.print(" | ||
+ | Serial.print(" | ||
+ | |||
+ | //Total RainFall | ||
+ | Serial.print(" | ||
+ | |||
+ | //Wind speed | ||
+ | Serial.print(" | ||
+ | |||
+ | //Wind direction | ||
+ | Serial.print(" | ||
+ | |||
+ | Serial.print(" | ||
+ | |||
+ | } | ||
+ | |||
+ | void SaveFun(){ | ||
+ | |||
+ | dataFile = SD.open(" | ||
+ | if (dataFile) { | ||
+ | // Write timestamp and sensor value to the file | ||
+ | dataFile.print(currentTimeSave); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(temperature); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(humidity); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(heatIndex); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(totalRain); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(windSpeed); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(WinDirVariable); | ||
+ | dataFile.print(", | ||
+ | dataFile.print(uvPercentage); | ||
+ | dataFile.println("" | ||
+ | dataFile.close(); | ||
+ | | ||
+ | Serial.println(" | ||
+ | } else { | ||
+ | Serial.println(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | You can freely download and use the code here --> {{ : | ||
+ | ======Conclusion====== | ||
+ | The " |
amc/ss2023/group-u/start.1690142772.txt.gz · Last modified: 2023/07/23 22:06 by daniel-jose.centeno-gonzalez