// -------- LIBRARIES -------- #include #include #include #include #include #include // -------- PIN DEFINITIONS -------- #define DHTPIN 4 #define DHTTYPE DHT11 #define LDR_PIN 35 // input only pin (good choice) #define RAIN_PIN 34 // analog pin #define LED_PIN 2 // -------- OBJECTS -------- LiquidCrystal_I2C lcd(0x27, 16, 2); DHT dht(DHTPIN, DHTTYPE); SFE_BMP180 bmp; WiFiClient espClient; PubSubClient client(espClient); // -------- WIFI & MQTT CREDENTIALS -------- const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; const char* mqtt_server = "YOUR_MQTT_BROKER"; const int mqtt_port = 1883; const char* mqtt_topic = "weather/station"; // -------- VARIABLES -------- double T, P; unsigned long lastSensorRead = 0; const long sensorInterval = 2000; // Read sensors every 2 seconds unsigned long lastMQTTSend = 0; const long mqttInterval = 30000; // Send data every 30 seconds struct WeatherData { float temperature; float humidity; float pressure; int rainLevel; bool lightDetected; bool valid; }; WeatherData currentData; // -------- FUNCTIONS -------- // DHT SENSOR void readDHT() { float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println("DHT Error!"); currentData.valid = false; return; } currentData.temperature = t; currentData.humidity = h; } // RAIN SENSOR void readRain() { int value = analogRead(RAIN_PIN); value = map(value, 0, 4095, 0, 100); value = 100 - value; currentData.rainLevel = value; } // PRESSURE SENSOR void readPressure() { if (bmp.startTemperature()) { delay(100); if (bmp.getTemperature(T)) { if (bmp.startPressure(3)) { delay(100); if (bmp.getPressure(P, T)) { currentData.pressure = P; } } } } else { Serial.println("BMP180 Error"); currentData.valid = false; } } // LDR SENSOR void readLDR() { int value = digitalRead(LDR_PIN); currentData.lightDetected = (value == HIGH); digitalWrite(LED_PIN, currentData.lightDetected ? HIGH : LOW); } // READ ALL SENSORS void readSensors() { currentData.valid = true; readDHT(); readRain(); readPressure(); readLDR(); if (currentData.valid) { Serial.print("Temp: "); Serial.print(currentData.temperature); Serial.print("°C, Humidity: "); Serial.print(currentData.humidity); Serial.print("%, Rain: "); Serial.print(currentData.rainLevel); Serial.print("%, Pressure: "); Serial.print(currentData.pressure); Serial.print(" hPa, Light: "); Serial.println(currentData.lightDetected ? "YES" : "NO"); } } // UPDATE LCD DISPLAY void updateDisplay() { if (!currentData.valid) { lcd.setCursor(0, 0); lcd.print("Sensor Error! "); lcd.setCursor(0, 1); lcd.print("Check wiring "); return; } // Display temperature and humidity on first line lcd.setCursor(0, 0); lcd.print("T:"); lcd.print(currentData.temperature, 1); lcd.print("C H:"); lcd.print(currentData.humidity, 0); lcd.print("%"); // Display rain and pressure on second line lcd.setCursor(0, 1); lcd.print("R:"); lcd.print(currentData.rainLevel); lcd.print("% P:"); lcd.print(currentData.pressure, 0); lcd.print(" "); } // SETUP WIFI void setupWiFi() { Serial.println("Connecting to WiFi..."); lcd.setCursor(0, 0); lcd.print("WiFi connecting"); WiFi.begin(ssid, password); int attempts = 0; while (WiFi.status() != WL_CONNECTED && attempts < 20) { delay(500); Serial.print("."); attempts++; } if (WiFi.status() == WL_CONNECTED) { Serial.println("\nWiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); lcd.setCursor(0, 0); lcd.print("WiFi connected "); } else { Serial.println("Failed to connect to WiFi"); lcd.setCursor(0, 0); lcd.print("WiFi failed! "); } delay(2000); } // RECONNECT MQTT void reconnectMQTT() { while (!client.connected()) { Serial.print("Attempting MQTT connection..."); String clientId = "ESP32WeatherStation-"; clientId += String(random(0xffff), HEX); if (client.connect(clientId.c_str())) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } // SEND MQTT DATA void sendMQTTData() { if (!currentData.valid || !client.connected()) { return; } String payload = "{"; payload += "\"temperature\":" + String(currentData.temperature, 2) + ","; payload += "\"humidity\":" + String(currentData.humidity, 2) + ","; payload += "\"pressure\":" + String(currentData.pressure, 2) + ","; payload += "\"rainLevel\":" + String(currentData.rainLevel) + ","; payload += "\"lightDetected\":" + String(currentData.lightDetected ? "true" : "false"); payload += "}"; if (client.publish(mqtt_topic, payload.c_str())) { Serial.println("MQTT data sent successfully"); } else { Serial.println("Failed to send MQTT data"); } } // -------- SETUP -------- void setup() { Serial.begin(115200); // Initialize pins pinMode(LDR_PIN, INPUT); pinMode(RAIN_PIN, INPUT); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); // Initialize I2C and sensors Wire.begin(21, 22); // SDA, SCL lcd.init(); lcd.backlight(); dht.begin(); if (!bmp.begin()) { Serial.println("BMP180 not detected!"); } // Initialize WiFi setupWiFi(); // Initialize MQTT client.setServer(mqtt_server, mqtt_port); // Initial sensor reading readSensors(); updateDisplay(); lcd.setCursor(0, 0); lcd.print("System Ready"); delay(2000); lcd.clear(); } // -------- LOOP -------- void loop() { unsigned long currentMillis = millis(); // Reconnect MQTT if needed if (!client.connected()) { reconnectMQTT(); } client.loop(); // Read sensors at regular interval if (currentMillis - lastSensorRead >= sensorInterval) { lastSensorRead = currentMillis; readSensors(); updateDisplay(); } // Send MQTT data at regular interval if (currentMillis - lastMQTTSend >= mqttInterval) { lastMQTTSend = currentMillis; sendMQTTData(); } delay(100); }