#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Include the LCD I2C library
#include <DHT.h>
// Define pins and components
#define DHTPIN 4
#define DHTTYPE DHT22
#define TRIGPIN 18
#define ECHOPIN 19
#define RELAYPIN 25
#define BUZZERPIN 26
// Initialize DHT22
DHT dht(DHTPIN, DHTTYPE);
// Initialize LCD (20x4) with address 0x3F for Wokwi
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Set the LCD address to 0x3F (common in Wokwi) and size to 20x4
// Variables for water level
const float tankHeight = 20.0; // Tank height in cm for 2L
float waterLevel = 0; // Water level in liters
// Temperature thresholds
const float tempThresholdOn = 30.0; // Temperature to turn pump ON
const float tempThresholdOff = 25.0; // Temperature to turn pump OFF
// Buzzer control
bool buzzerState = false; // To track the buzzer state
// Water level thresholds for pump control
const float waterLevelThresholdLow = 0.3; // Water level to turn pump off (if below this) 300 mL
const float waterLevelThresholdOn = 1.0; // Water level to turn pump on (if above this) 1 Liter
void setup() {
// Initialize serial monitor
Serial.begin(115200);
// Initialize DHT sensor
dht.begin();
// Initialize LCD
lcd.begin(20, 4); // Set up the LCD's number of columns and rows
lcd.backlight(); // Turn on the LCD backlight
// Initialize relay and buzzer
pinMode(RELAYPIN, OUTPUT);
pinMode(BUZZERPIN, OUTPUT);
digitalWrite(RELAYPIN, LOW);
digitalWrite(BUZZERPIN, LOW);
// Initialize ultrasonic sensor
pinMode(TRIGPIN, OUTPUT);
pinMode(ECHOPIN, INPUT);
}
void loop() {
// Read temperature and humidity
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Read water level
waterLevel = readWaterLevel();
// Control pump based on water level and temperature
static bool pumpOn = false;
// If water level is below 300mL or temperature is below 25°C, turn off pump
if (waterLevel <= waterLevelThresholdLow || temperature <= tempThresholdOff) {
pumpOn = false; // Turn off pump
digitalWrite(RELAYPIN, LOW); // Turn off pump
}
// If water level is above 1L and temperature is above 30°C, turn pump on
else if (waterLevel >= waterLevelThresholdOn && temperature >= tempThresholdOn && !buzzerState) {
pumpOn = true;
digitalWrite(RELAYPIN, HIGH); // Turn on pump
}
// Handle water tank alert
if (waterLevel <= waterLevelThresholdLow) {
// Trigger buzzer if water level is low
buzzerState = true;
tone(BUZZERPIN, 1500); // Start buzzer at 1500 Hz
} else if (waterLevel >= waterLevelThresholdOn) {
// Stop buzzer if water level is 1L or more
buzzerState = false;
noTone(BUZZERPIN); // Stop buzzer
}
// Control buzzer based on buzzerState
if (buzzerState) {
digitalWrite(BUZZERPIN, HIGH); // Turn on buzzer
} else {
digitalWrite(BUZZERPIN, LOW); // Turn off buzzer
}
// Update LCD display
lcd.clear(); // Clear previous screen content
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Pump: ");
lcd.print(pumpOn ? "ON" : "OFF");
lcd.setCursor(0, 2);
lcd.print("Level: ");
lcd.print(waterLevel, 1);
lcd.print(" L");
if (waterLevel <= waterLevelThresholdLow) {
lcd.setCursor(0, 3);
lcd.print("Alert: Low Tank!");
}
// Delay for next update
delay(1000);
}
// Function to calculate water level
float readWaterLevel() {
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN, LOW);
float duration = pulseIn(ECHOPIN, HIGH);
float distance = (duration / 2) * 0.0343; // Convert to cm
if (distance > tankHeight) distance = tankHeight;
return 2.0 * (tankHeight - distance) / tankHeight; // Convert to liters
}