#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <RTClib.h>
// Initialize the LCD, adjust the I2C address (0x27 is common for LCD2004)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Define DHT22 sensor settings
#define DHTPIN 13 // DHT22 data pin connected to GPIO 13
#define DHTTYPE DHT22 // DHT22 (AM2302) sensor type
DHT dht(DHTPIN, DHTTYPE);
// Initialize the DS1307 RTC
RTC_DS1307 rtc;
// Relay pin definitions
const int fanPin = 12; // Fan relay on pin 12
const int pumpPin = 14; // Pump relay on pin 14
const int lampPin = 27; // Lamp relay on pin 27
const int buttonPin = 26; // Button pin for toggling display modes
// Thresholds
const float tempThreshold = 30.0;
const float humThreshold = 80.0;
// Variables to track button state and display mode
int displayMode = 0;
bool lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 200; // 200 ms debounce delay
// Variables to track time using millis
unsigned long lastUpdateTime = 0; // Tracks last time the display was updated
unsigned long updateInterval = 1000; // 1 second update interval
void setup() {
// Initialize the LCD
lcd.init();
lcd.backlight();
// Initialize DHT22 sensor
dht.begin();
// Initialize DS1307 RTC
if (!rtc.begin()) {
lcd.setCursor(0, 0);
lcd.print("Couldn't find RTC");
while (1); // Halt if RTC is not found
}
if (!rtc.isrunning()) {
lcd.setCursor(0, 0);
lcd.print("RTC is not running");
// Uncomment the next line to set the RTC to the current time
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Initialize relays
pinMode(fanPin, OUTPUT);
pinMode(pumpPin, OUTPUT);
pinMode(lampPin, OUTPUT);
// Initialize button
pinMode(buttonPin, INPUT_PULLUP);
// Ensure relays are off at start
digitalWrite(fanPin, LOW); // Assume LOW turns the relay off
digitalWrite(pumpPin, LOW);
digitalWrite(lampPin, LOW);
// Initial message
lcd.setCursor(0, 0);
lcd.print("Temp & Humidity");
delay(2000);
}
void loop() {
unsigned long currentMillis = millis(); // Get the current time
// Button state and debouncing using millis
bool buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
lastDebounceTime = currentMillis; // Reset debounce timer
}
if ((currentMillis - lastDebounceTime) > debounceDelay) {
if (buttonState == LOW && lastButtonState == HIGH) {
// Switch between display modes
displayMode = 1;
}
}
lastButtonState = buttonState;
// Only update the LCD and relays every 1 second
if (currentMillis - lastUpdateTime >= updateInterval) {
lastUpdateTime = currentMillis; // Update the last update time
// Read temperature and humidity from DHT22
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
// Check if any readings failed and exit early
if (isnan(humidity) || isnan(temperature)) {
lcd.setCursor(0, 0);
lcd.print("Error reading data");
return;
}
// Get current date and time from RTC
DateTime now = rtc.now();
// Clear LCD and display based on the current mode
lcd.clear();
if (displayMode == 0) {
// Display temperature, humidity, date, and time
lcd.setCursor(0, 0);
lcd.print(now.day(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.year(), DEC);
lcd.setCursor(0, 1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.setCursor(0, 2);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 3);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print(" %");
} else {
// Display the status of fan, pump, and lamp
lcd.setCursor(0, 0);
lcd.print("Fan: ");
lcd.print(digitalRead(fanPin) == HIGH ? "ON" : "OFF");
lcd.setCursor(0, 1);
lcd.print("Pump: ");
lcd.print(digitalRead(pumpPin) == HIGH ? "ON" : "OFF");
lcd.setCursor(0, 2);
lcd.print("Lamp: ");
lcd.print(digitalRead(lampPin) == HIGH ? "ON" : "OFF");
}
// Control Fan based on temperature (Active High Logic)
if (temperature > tempThreshold) {
digitalWrite(fanPin, HIGH); // Turn fan ON
} else {
digitalWrite(fanPin, LOW); // Turn fan OFF
}
// Control Pump based on humidity (Active High Logic)
if (humidity < humThreshold) {
digitalWrite(pumpPin, HIGH); // Turn pump ON
} else {
digitalWrite(pumpPin, LOW); // Turn pump OFF
}
// Control Lamp based on time (14:20 ON, 14:22 OFF)
if (now.hour() == 14 && now.minute() == 20) {
digitalWrite(lampPin, HIGH); // Turn lamp ON
} else if (now.hour() == 14 && now.minute() == 22) {
digitalWrite(lampPin, LOW); // Turn lamp OFF
}
}
}