/*
Weather Station & Clock with DHT11/DHT22, DS3231 RTC, and I2C LCD
For Arduino Uno
Displays: Time (HH:MM:SS), Date (DD/MM), Temperature (°C), Humidity (%)
Works with both DHT11 and DHT22.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <DHT.h>
// ---------- LCD Configuration ----------
// Common I2C addresses: 0x27 or 0x3F. Change if your LCD does not work.
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ---------- RTC Configuration ----------
RTC_DS3231 rtc;
// ---------- DHT Configuration ----------
#define DHTPIN 2 // Digital pin connected to DHT data pin
// ===== CHOOSE YOUR SENSOR: Uncomment ONE of the following lines =====
// #define DHTTYPE DHT11 // For DHT11 (cheaper, less accurate, NOT supported in Wokwi)
#define DHTTYPE DHT22 // For DHT22 (more accurate, Wokwi-compatible)
DHT dht(DHTPIN, DHTTYPE);
// ---------- Timing ----------
unsigned long lastDisplayUpdate = 0;
const unsigned long displayUpdateInterval = 1000; // update every 1000 ms (1 sec)
void setup() {
Serial.begin(9600);
Serial.println("Weather Station & Clock starting...");
// --- LCD Initialization ---
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Weather Station");
lcd.setCursor(0, 1);
lcd.print(" v2.0 (DHT11/22)");
delay(2000);
lcd.clear();
// --- DHT Initialization ---
dht.begin();
// --- RTC Initialization ---
if (!rtc.begin()) {
lcd.setCursor(0, 0);
lcd.print("RTC Error!");
Serial.println("Could not find RTC module. Check wiring.");
while (1); // halt program
}
// --- RTC Time Setting (DO THIS ONLY ONCE) ---
// Uncomment the line below, upload the code, then re-comment and upload again.
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Optional: manual set (year, month, day, hour, minute, second)
// rtc.adjust(DateTime(2026, 6, 4, 14, 30, 0));
}
void loop() {
// Update display exactly once per second (non-blocking)
if (millis() - lastDisplayUpdate >= displayUpdateInterval) {
lastDisplayUpdate = millis();
// --- Read DHT sensor ---
float humidity = dht.readHumidity(); // in %
float temperatureC = dht.readTemperature(); // in Celsius
// Check if reading failed (sensor disconnected or timing issue)
if (isnan(humidity) || isnan(temperatureC)) {
Serial.println("DHT read error!");
lcd.setCursor(0, 0);
lcd.print("Sensor Error! ");
lcd.setCursor(0, 1);
lcd.print("Check wiring ");
return; // skip the rest of this loop iteration
}
// --- Read RTC ---
DateTime now = rtc.now();
// --- Display on LCD ---
// Row 0: Time and Humidity
lcd.setCursor(0, 0);
lcd.print("Time:");
if (now.hour() < 10) lcd.print("0");
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) lcd.print("0");
lcd.print(now.minute());
lcd.print(":");
if (now.second() < 10) lcd.print("0");
lcd.print(now.second());
lcd.setCursor(13, 0);
lcd.print((int)humidity); // integer part only
lcd.print("%");
// Row 1: Date and Temperature
lcd.setCursor(0, 1);
lcd.print("Date: ");
if (now.day() < 10) lcd.print("0");
lcd.print(now.day());
lcd.print("/");
if (now.month() < 10) lcd.print("0");
lcd.print(now.month());
lcd.setCursor(12, 1);
lcd.print(temperatureC, 1); // one decimal place
lcd.print("C");
}
}