#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <WiFi.h>
#include <WebServer.h>
#define DHTPIN 4
#define DHTTYPE DHT22
#define RAINPIN 5
const char* ssid = "Olfa";
const char* password = "olfa123+";
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
WebServer server(80);
void WiFiEvent(WiFiEvent_t event) {
Serial.print("WiFi Event: ");
switch (event) {
case WIFI_EVENT_STA_DISCONNECTED:
Serial.println("Disconnected from WiFi");
break;
case IP_EVENT_STA_GOT_IP:
Serial.print("Got IP Address: ");
Serial.println(WiFi.localIP());
break;
default:
Serial.println(event);
break;
}
}
void handleRoot() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
int rain = digitalRead(RAINPIN);
String webpage = "<!DOCTYPE html><html><head>";
webpage += "<meta http-equiv='refresh' content='5'>";
webpage += "<title>Weather Station</title>";
webpage += "<style>body {font-family: Arial; text-align: center; margin-top: 50px;}";
webpage += "h1 {color: #0066cc;}";
webpage += ".reading {font-size: 24px; margin: 20px;}</style></head>";
webpage += "<body><h1>Weather Station Readings</h1>";
webpage += "<div class='reading'>Temperature: " + String(temperature, 1) + " °C</div>";
webpage += "<div class='reading'>Humidity: " + String(humidity, 0) + "%</div>";
webpage += "<div class='reading'>Rain Detected: " + String(rain == HIGH ? "No" : "Yes") + "</div>";
webpage += "<p>Refresh every 5 seconds</p></body></html>";
server.send(200, "text/html", webpage);
}
void scanNetworks() {
Serial.println("Scanning for WiFi networks...");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
int n = WiFi.scanNetworks();
Serial.println("Scan complete");
if (n == 0) {
Serial.println("No networks found");
lcd.setCursor(0, 0);
lcd.print("No WiFi found!");
delay(2000);
lcd.clear();
} else {
Serial.print(n);
Serial.println(" networks found:");
for (int i = 0; i < n; ++i) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(" dBm) ");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? "Open" : "Secured");
}
}
}
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
lcd.setCursor(0, 0);
lcd.print("Connecting to");
lcd.setCursor(0, 1);
lcd.print("WiFi... ");
WiFi.mode(WIFI_STA);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
int timeout = 30; // Increased timeout
int count = 0;
while (WiFi.status() != WL_CONNECTED && count < timeout) {
delay(500);
Serial.print(".");
count++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
lcd.setCursor(0, 0);
lcd.print("WiFi Connected ");
lcd.setCursor(0, 1);
lcd.print("IP:");
lcd.print(WiFi.localIP());
delay(3000);
lcd.clear();
} else {
Serial.println("\nFailed to connect to WiFi");
Serial.println("Status: " + String(WiFi.status()));
lcd.setCursor(0, 0);
lcd.print("WiFi Failed! ");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(WiFi.status());
delay(3000);
lcd.clear();
// Optional: Add fallback to AP mode here
}
}
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
dht.begin();
pinMode(RAINPIN, INPUT_PULLUP); // Changed to INPUT_PULLUP for better rain detection
lcd.setCursor(0, 0);
lcd.print("Weather Station");
lcd.setCursor(0, 1);
lcd.print("Initializing...");
delay(2000);
lcd.clear();
scanNetworks();
connectToWiFi();
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
static unsigned long lastReconnectAttempt = 0;
const unsigned long reconnectInterval = 30000; // 30 seconds
server.handleClient();
// Attempt reconnect if disconnected
if (WiFi.status() != WL_CONNECTED && millis() - lastReconnectAttempt > reconnectInterval) {
Serial.println("WiFi disconnected. Attempting to reconnect...");
lastReconnectAttempt = millis();
WiFi.disconnect();
delay(100);
connectToWiFi();
}
// Read and display sensor data
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
int rain = digitalRead(RAINPIN);
if (isnan(humidity) || isnan(temperature)) {
lcd.setCursor(0, 0);
lcd.print("Sensor Error! ");
lcd.setCursor(0, 1);
lcd.print("Rain: ");
lcd.print(rain == HIGH ? "No " : "Yes");
delay(2000);
return;
}
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperature, 1);
lcd.print("C H:");
lcd.print(humidity, 0);
lcd.print("% ");
lcd.setCursor(0, 1);
lcd.print("Rain: ");
lcd.print(rain == HIGH ? "No " : "Yes");
lcd.print(" ");
delay(2000); // Update every 2 seconds
}