#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <LiquidCrystal_I2C.h>
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// OpenWeather API configuration
const char* openWeatherApiKey = "93b45c2bb433107bdf418fa17ed520bc";
// LCD configuration
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Define I2C pins for ESP32
#define I2C_SDA 21
#define I2C_SCL 22
// NTP configuration
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
// Variables to store weather data
float temperature;
int humidity;
float pressure;
float windSpeed;
float dewPoint;
String weatherDescription;
int cloudCover;
float feelsLike;
unsigned long lastWeatherUpdate = 0;
const unsigned long weatherUpdateInterval = 600000;
int currentDisplay = 0; // To cycle through different displays
const int maxDisplays = 3; // Number of different display screens
void setup() {
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
lcd.clear();
lcd.print("WiFi Connected!");
delay(1000);
timeClient.begin();
timeClient.setTimeOffset(3600); // GMT+1 for Nigeria
updateWeather();
}
void loop() {
timeClient.update();
if (millis() - lastWeatherUpdate >= weatherUpdateInterval) {
updateWeather();
}
displayData();
// Cycle through different displays every 5 seconds
if (millis() % 5000 == 0) {
currentDisplay = (currentDisplay + 1) % maxDisplays;
}
delay(1000);
}
String getAmPmTime(int hour, int minute, int second) {
String ampm = hour >= 12 ? "PM" : "AM";
hour = hour % 12;
hour = hour ? hour : 12; // Convert 0 to 12
String hourStr = hour < 10 ? "0" + String(hour) : String(hour);
String minStr = minute < 10 ? "0" + String(minute) : String(minute);
String secStr = second < 10 ? "0" + String(second) : String(second);
return hourStr + ":" + minStr + ":" + secStr + " " + ampm;
}
// Calculate dew point
float calculateDewPoint(float temp, float humidity) {
float a = 17.27;
float b = 237.7;
float alpha = ((a * temp) / (b + temp)) + log(humidity / 100.0);
return (b * alpha) / (a - alpha);
}
void updateWeather() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "https://api.openweathermap.org/data/2.5/weather?q=Ikotun,NG&appid=" + String(openWeatherApiKey) + "&units=metric";
Serial.println("Requesting URL: " + url);
http.begin(url.c_str());
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
if (doc.containsKey("main")) {
JsonObject main = doc["main"];
temperature = main["temp"].as<float>();
humidity = main["humidity"].as<int>();
pressure = main["pressure"].as<float>();
feelsLike = main["feels_like"].as<float>();
windSpeed = doc["wind"]["speed"].as<float>();
cloudCover = doc["clouds"]["all"].as<int>();
if (doc["weather"][0].containsKey("description")) {
weatherDescription = doc["weather"][0]["description"].as<String>();
}
// Calculate dew point
dewPoint = calculateDewPoint(temperature, humidity);
Serial.println("Weather data updated successfully");
}
}
}
http.end();
lastWeatherUpdate = millis();
}
}
void displayData() {
timeClient.update();
int hours = timeClient.getHours();
int minutes = timeClient.getMinutes();
int seconds = timeClient.getSeconds();
String ampmTime = getAmPmTime(hours, minutes, seconds);
lcd.clear();
// Display 1: Time, Temp, Humidity
lcd.setCursor(0, 0);
lcd.print(ampmTime);
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
lcd.setCursor(0, 3);
lcd.print(weatherDescription);
delay(2000);
lcd.clear();
// Display 2: Pressure, Wind, Clouds
lcd.setCursor(0, 0);
lcd.print("Pressure:");
lcd.print(pressure, 0);
lcd.print("hPa");
lcd.setCursor(0, 1);
lcd.print("Wind: ");
lcd.print(windSpeed, 1);
lcd.print("m/s");
lcd.setCursor(0, 2);
lcd.print("Clouds: ");
lcd.print(cloudCover);
lcd.print("%");
lcd.setCursor(0, 3);
lcd.print("DewPoint:");
lcd.print(dewPoint, 1);
lcd.print((char)223);
lcd.print("C");
delay(2000);
lcd.clear();
// Display 3: Additional Info
lcd.setCursor(0, 0);
lcd.print("Feels Like: ");
lcd.print(feelsLike, 1);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print(weatherDescription);
lcd.setCursor(0, 3);
lcd.print(ampmTime);
delay(2000);
lcd.clear();
}