#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// OpenWeather API configuration
const char* openWeatherApiKey = "93b45c2bb433107bdf418fa17ed520bc";
// Define hardware type and pins for the dot matrix display
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 16
#define CLK_PIN 18
#define DATA_PIN 23
#define CS_PIN 5
// Initialize Parola library
MD_Parola display = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
// 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);
display.begin();
display.setIntensity(0); // Set brightness (0-15)
display.displayClear();
display.displayText("Connecting to WiFi...", PA_CENTER, 10, 1000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
while (!display.displayAnimate());
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to WiFi");
display.displayText("WiFi Connected!", PA_CENTER, 10, 1000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
while (!display.displayAnimate());
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);
// Display 1: Time, Temp, Humidity
display.displayClear();
display.displayText(("Time: " + ampmTime + " Temp: " + String(temperature, 1) + "C Humidity: " + String(humidity) + "%").c_str(), PA_CENTER, 10, 1000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
// Display 2: Pressure, Wind, Clouds
display.displayClear();
display.displayText(("Pressure: " + String(pressure, 0) + "hPa Wind: " + String(windSpeed, 1) + "m/s Clouds: " + String(cloudCover) + "%").c_str(), PA_CENTER, 10, 1000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
// Display 3: Feels Like, Dew Point
display.displayClear();
display.displayText(("Feels Like: " + String(feelsLike, 1) + "C DewPoint: " + String(dewPoint, 1) + "C Desc: " + weatherDescription).c_str(), PA_CENTER, 10, 1000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
while (!display.displayAnimate());
}