Devices & Components
16x2 LCD display with I²C interface
DHT11 Temperature & Humidity Sensor (4 pins)
Bmp 180
4GB or Larger Micro SD Card
esp8266 NodeMCU
Air Quality sensor (MQ135)
SD card reader/writer
rtc DS1307
5V Power Supply Module
Hardware & Tools
Soldering kit
Wire cutter
Software & Tools
Arduino IDE
Project description
Code
Weather
weather
1#include <Wire.h> 2#include <LiquidCrystal_I2C.h> 3#include "uRTCLib.h" 4#include <DHT.h> 5#include <Adafruit_BMP085.h> // Library handles both BMP085 and BMP180 6#include <SPI.h> 7#include <SD.h> 8#include <ESP8266WiFi.h> 9#include <ESP8266WebServer.h> 10 11// ----------- Configuration ----------- 12#define SDA_PIN D2 13#define SCL_PIN D1 14#define MQ135_PIN A0 15#define DHTPIN D4 16#define DHTTYPE DHT11 17#define LCD_ADDR 0x27 18#define SD_CS D8 // Corrected SD_CS pin for ESP8266 (e.g., D8/GPIO15 often used with default SPI) 19 20// <-- Add your WiFi SSID and Password here 21const char* ssid = ""; 22const char* password = ""; 23 24// Threshold for pressure change (in Pa, or 0.1 hPa) 25// A common rule of thumb for "significant change" is around 2-3 hPa over a few hours. 26// Adjust this value based on how sensitive you want the pressure trend detection to be. 27#define PRESSURE_CHANGE_THRESHOLD 200 // 200 Pa = 2 hPa 28 29// ----------- Objects ----------- 30LiquidCrystal_I2C lcd(LCD_ADDR, 16, 2); 31uRTCLib rtc; 32DHT dht(DHTPIN, DHTTYPE); 33Adafruit_BMP085 bmp; 34ESP8266WebServer server(80); 35File myFile; 36 37// ----------- Globals ----------- 38float temp, hum, airQuality; 39float bmpTemp, pressure, altitude, seaLevelPressure; 40float previousPressure = 0.0; // To store the last pressure reading for trend analysis 41String tempStatus, humStatus, airStatus, prediction; 42String currentDate, currentTime; 43String predictionMessage; 44char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 45String pressureTrendStatus; // "Rising", "Falling", "Stable" 46 47// ----------- Helper Functions ----------- 48 49void updateDateTime() { 50 rtc.refresh(); 51 currentDate = String(rtc.day()) + "-" + String(rtc.month()) + "-" + String(rtc.year()); 52 currentTime = String(rtc.hour()) + ":" + String(rtc.minute()) + ":" + String(rtc.second()); 53} 54 55void displayLCD(const String& line1, const String& line2) { 56 lcd.clear(); 57 lcd.setCursor(0, 0); lcd.print(line1); 58 lcd.setCursor(0, 1); lcd.print(line2); 59} 60 61void readSensors() { 62 airQuality = analogRead(MQ135_PIN); 63 temp = dht.readTemperature(); 64 hum = dht.readHumidity(); 65 66 // Store current pressure as previous for next cycle 67 previousPressure = pressure; 68 69 // Read BMP085 sensor data 70 bmpTemp = bmp.readTemperature(); 71 pressure = bmp.readPressure(); 72 altitude = bmp.readAltitude(); 73 seaLevelPressure = bmp.readSealevelPressure(); 74 75 // Determine pressure trend 76 if (abs(pressure - previousPressure) < PRESSURE_CHANGE_THRESHOLD || previousPressure == 0.0) { 77 pressureTrendStatus = "Stable"; 78 } else if (pressure > previousPressure) { 79 pressureTrendStatus = "Rising"; 80 } else { 81 pressureTrendStatus = "Falling"; 82 } 83} 84 85String generatePrediction() { 86 if (temp > 35) tempStatus = "Hot"; 87 else if (temp > 25) tempStatus = "Warm"; 88 else if (temp > 15) tempStatus = "Cool"; 89 else tempStatus = "Cold"; 90 91 if (hum > 80) humStatus = "Very Humid"; 92 else if (hum > 60) humStatus = "Humid"; 93 else if (hum < 30) humStatus = "Dry"; 94 else humStatus = "Normal"; 95 96 if (airQuality > 900) airStatus = "Hazardous"; 97 else if (airQuality > 700) airStatus = "Poor"; 98 else if (airQuality > 500) airStatus = "Moderate"; 99 else airStatus = "Good"; 100 101 // --- Prediction logic including pressure trend --- 102 if (airStatus == "Hazardous") prediction = "Stay indoors!"; 103 else if (airStatus == "Poor") prediction = "Wear a mask!"; 104 else if (tempStatus == "Hot" && humStatus == "Humid") prediction = "Heat risk!"; 105 else if (tempStatus == "Cold" && humStatus == "Very Humid") prediction = "Cold & damp!"; 106 else if (tempStatus == "Cold" && airStatus == "Poor") prediction = "Cold+Pollution!"; 107 else if (pressureTrendStatus == "Falling" && hum > 70) prediction = "Rain likely!"; // Falling pressure + high humidity 108 else if (pressureTrendStatus == "Falling") prediction = "Expect change!"; // General falling pressure 109 else if (pressureTrendStatus == "Rising" && temp > 15) prediction = "Improving weather!"; // Rising pressure, not too cold 110 else if (pressureTrendStatus == "Rising") prediction = "Clearer skies!"; // General rising pressure 111 else if (tempStatus == "Warm" && humStatus == "Normal" && airStatus == "Good") prediction = "Perfect!"; 112 else if (tempStatus == "Cool" && humStatus == "Dry" && airStatus == "Good") prediction = "Pleasant!"; 113 else prediction = "Mild Weather"; // Default if no specific condition met 114 115 // --- Displaying ALL sensor data on LCD in a sequence --- 116 displayLCD("Temp: " + String(temp, 1) + (char)223 + "C", "(" + tempStatus + ")"); 117 delay(3000); 118 119 displayLCD("Humidity: " + String(hum, 1) + "%", "(" + humStatus + ")"); 120 delay(3000); 121 122 displayLCD("Air Qual: " + String((int)airQuality), "(" + airStatus + ")"); 123 delay(3000); 124 125 displayLCD("BMP Temp: " + String(bmpTemp, 1) + (char)223 + "C", ""); // BMP Temp 126 delay(3000); 127 128 displayLCD("Pressure: " + String(pressure / 100.0, 1) + "hPa", "(" + pressureTrendStatus.substring(0,10) + ")"); // Pressure in hPa with trend 129 delay(3000); 130 131 displayLCD("Altitude: " + String(altitude, 1) + "m", ""); // Altitude 132 delay(3000); 133 134 displayLCD("Prediction:", prediction.substring(0, 16)); 135 delay(4000); 136 // --- End of LCD display sequence --- 137 138 139 // Serial Monitor Output (all parameters, including BMP085 data) 140 Serial.println("\n--- Sensor Readings ---"); 141 Serial.println("Date: " + currentDate + ", Time: " + currentTime); 142 Serial.println("DHT Temp: " + String(temp, 1) + "C (" + tempStatus + ")"); 143 Serial.println("Humidity: " + String(hum, 1) + "% (" + humStatus + ")"); 144 Serial.println("Air Quality: " + String(airQuality) + " (" + airStatus + ")"); 145 Serial.println("BMP Temp: " + String(bmpTemp, 1) + "C"); 146 Serial.println("Pressure: " + String(pressure / 100.0, 2) + " hPa (" + pressureTrendStatus + ")"); // Convert Pa to hPa 147 Serial.println("Altitude: " + String(altitude, 2) + " m"); 148 Serial.println("Sea Level Pres: " + String(seaLevelPressure / 100.0, 2) + " hPa"); 149 Serial.println("Prediction: " + prediction); 150 Serial.println("-----------------------\n"); 151 152 return prediction; 153} 154 155void logToSDCard() { 156 String log = currentDate + "," + currentTime + "," + 157 String(hum, 2) + "," + String(temp, 2) + "," + String(airQuality, 0) + "," + 158 String(pressure, 2) + "," + String(bmpTemp, 2) + "," + String(altitude, 2) + "," + 159 String(seaLevelPressure, 2) + "," + pressureTrendStatus; // Added pressure trend to log 160 161 myFile = SD.open("Data.txt", FILE_WRITE); 162 if (myFile) { 163 myFile.println(log); 164 myFile.close(); 165 Serial.println("Logged to SD: " + log); 166 } else { 167 Serial.println("Error opening Data.txt for logging."); 168 } 169} 170 171void logPrediction(String pred) { 172 myFile = SD.open("Prediction.txt", FILE_WRITE); 173 if (myFile) { 174 myFile.println(currentDate + "," + currentTime + "," + pred); 175 myFile.close(); 176 Serial.println("Logged prediction to SD: " + pred); 177 } else { 178 Serial.println("Error opening Prediction.txt for logging."); 179 } 180} 181 182void handleRoot() { 183 String html = "<html><head><meta http-equiv='refresh' content='15'><style>body{font-family: Arial, sans-serif; text-align:center; background-color: #f0f0f0; margin-top: 50px;} h2{color:#333;} p{color:#666; font-size:1.1em;}</style></head><body>"; 184 html += "<h2>ESP8266 Weather Station</h2>"; 185 html += "<p>Date: <b>" + currentDate + "</b></p>"; 186 html += "<p>Time: <b>" + currentTime + "</b></p>"; 187 html += "<p>DHT Temperature: <b>" + String(temp, 1) + "°C</b> (" + tempStatus + ")</p>"; 188 html += "<p>Humidity: <b>" + String(hum, 1) + "%</b> (" + humStatus + ")</p>"; 189 html += "<p>Air Quality (MQ135): <b>" + String(airQuality, 0) + "</b> (" + airStatus + ")</p>"; 190 html += "<hr>"; 191 html += "<p>BMP Temperature: <b>" + String(bmpTemp, 1) + "°C</b></p>"; 192 html += "<p>Pressure: <b>" + String(pressure / 100.0, 2) + " hPa</b> (" + pressureTrendStatus + ")</p>"; 193 html += "<p>Altitude: <b>" + String(altitude, 2) + " m</b></p>"; 194 html += "<p>Sea Level Pressure: <b>" + String(seaLevelPressure / 100.0, 2) + " hPa</b></p>"; 195 html += "<hr>"; 196 html += "<p><strong>Weather Prediction:</strong> " + prediction + "</p>"; 197 html += "</body></html>"; 198 server.send(200, "text/html", html); 199} 200 201// ----------- Setup ----------- 202void setup() { 203 204// Uncomment this block to set RTC time once, then comment again after upload 205/* 206 rtc.set(2025, 5, 25, 0, 15, 30, 0); 207 // Format: rtc.set(YYYY, MM, DD, DayOfWeek, HH, MM, SS) 208 // DayOfWeek: 0 = Sunday, 1 = Monday, ..., 6 = Saturday 209 Serial.println("RTC time set."); 210 while (1); // Halt to prevent resetting repeatedly 211*/ 212 213 214 Serial.begin(9600); 215 Wire.begin(SDA_PIN, SCL_PIN); 216 URTCLIB_WIRE.begin(); 217 lcd.init(); lcd.backlight(); 218 lcd.setCursor(0, 0); lcd.print("Starting..."); 219 delay(2000); 220 dht.begin(); 221 222 if (!bmp.begin()) { 223 Serial.println("Could not find a valid BMP085/BMP180 sensor, check wiring!"); 224 displayLCD("BMP180 Error!", "Check Wiring!"); 225 while (1) {} // Halt if BMP085 is not found 226 } else { 227 Serial.println("BMP180 sensor found."); 228 } 229 230 // Initialize SD Card 231 if (!SD.begin(SD_CS)) { 232 Serial.println("SD Card init failed!"); 233 displayLCD("SD Card Error!", "Check Wiring!"); 234 // You might want to halt here or continue without SD logging 235 } else { 236 Serial.println("SD Card initialized."); 237 } 238 239 WiFi.begin(ssid, password); 240 Serial.print("Connecting to WiFi"); 241 while (WiFi.status() != WL_CONNECTED) { 242 delay(500); Serial.print("."); 243 } 244 245 IPAddress ip = WiFi.localIP(); 246 lcd.clear(); 247 lcd.setCursor(0, 0); lcd.print("WiFi Connected"); 248 lcd.setCursor(0, 1); lcd.print(ip.toString()); 249 delay(3000); 250 Serial.println("\nWiFi connected. IP: " + ip.toString()); 251 252 server.on("/", handleRoot); 253 server.begin(); 254 Serial.println("HTTP server started"); 255} 256 257// ----------- Loop ----------- 258void loop() { 259 updateDateTime(); 260 readSensors(); // This now updates previousPressure and calculates pressureTrendStatus 261 displayLCD("Date: " + currentDate, "Time: " + currentTime); 262 delay(3000); 263 predictionMessage = generatePrediction(); // This now uses pressureTrendStatus 264 logToSDCard(); 265 logPrediction(predictionMessage); 266 server.handleClient(); 267 delay(5000); // Add a small delay at the end of the loop 268}
Documentation
Project Report
Wire Connection, Algorithm, Block Diagram & List
Final_Report_Weather_Perdiction.pdf
Comments
Only logged in users can leave comments