#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"
#define PIN_TRIG 16
#define PIN_ECHO 19
#define ON_LED 5
#define ALERT_LED 18
#define TANK_HEIGHT_CM 300 // Total height of the tank in cm
#define BUZZER_ALARM 13
#define BUZZER_DURATION_MS 30000 // Duration to keep the buzzer on (30 seconds)
// Use the correct address here (0x27 or 0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int DHT_PIN = 17;
DHTesp dhtSensor;
unsigned long buzzerStartTime = 0; // Variable to store the time when the buzzer was turned on
bool buzzerActive = false; // To track the buzzer state
void setup() {
Serial.begin(115200);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
pinMode(ON_LED, OUTPUT);
pinMode(ALERT_LED, OUTPUT);
pinMode(BUZZER_ALARM, OUTPUT);
digitalWrite(ON_LED, HIGH); // Ensure ON_LED is always on
digitalWrite(ALERT_LED, LOW); // Ensure ALERT_LED is initially off
digitalWrite(BUZZER_ALARM, LOW); // Ensure Buzzer is initially off
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
displayInitialMessage();
}
void displayInitialMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WATER LEVEL");
lcd.setCursor(0, 1);
lcd.print("MEASUREMENT");
delay(3000); // Display for 3 seconds
}
void triggerMeasurement() {
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
}
int readDistance() {
int duration = pulseIn(PIN_ECHO, HIGH);
return duration / 58; // Convert duration to distance in cm
}
int calculateWaterLevel(int distanceCM) {
return TANK_HEIGHT_CM - distanceCM; // Calculate water level
}
void handleCriticalLowLevel() {
digitalWrite(ALERT_LED, HIGH); // Turn on ALERT_LED
digitalWrite(BUZZER_ALARM, HIGH); // Turn on Buzzer
tone(BUZZER_ALARM, 1000); // Generate a tone of 1000 Hz
buzzerStartTime = millis(); // Record the time when the buzzer was turned on
buzzerActive = true; // Set buzzer as active
}
void handleWarningLevel() {
digitalWrite(ALERT_LED, HIGH); // Turn on ALERT_LED
delay(500); // ON for 0.5 seconds
digitalWrite(ALERT_LED, LOW); // Turn off ALERT_LED
digitalWrite(BUZZER_ALARM, LOW); // Turn off Buzzer
noTone(BUZZER_ALARM); // Ensure Buzzer is off
buzzerActive = false; // Set buzzer as inactive
delay(1500); // OFF for 1.5 seconds
}
void handleNormalLevel() {
digitalWrite(ALERT_LED, LOW); // Ensure ALERT_LED is off
digitalWrite(BUZZER_ALARM, LOW); // Ensure Buzzer is off
noTone(BUZZER_ALARM); // Ensure Buzzer is off
buzzerActive = false; // Set buzzer as inactive
}
void checkBuzzer() {
if (buzzerActive && (millis() - buzzerStartTime >= BUZZER_DURATION_MS)) { // Duration to keep buzzer on
noTone(BUZZER_ALARM); // Turn off the Buzzer
buzzerActive = false; // Set buzzer as inactive
}
}
String getWaterLevelStatus(int waterLevel) {
if (waterLevel <= 60) { // Critical low level
return "CRITICAL";
} else if (waterLevel <= 150) { // Warning level
return "WARNING";
} else {
return "NORMAL";
}
}
String getTemperatureStatus(float temperature) {
if (temperature < 5.0 || temperature > 45.0) {
return "WARNING";
} else {
return "NORMAL";
}
}
String getHumidityStatus(float humidity) {
if (humidity < 20.0 || humidity > 80.0) {
return "WARNING";
} else {
return "NORMAL";
}
}
void displayWaterLevel(int waterLevel) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WaterLvl: ");
lcd.print(waterLevel);
lcd.print("cm");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(getWaterLevelStatus(waterLevel));
delay(2000); // Wait 2 seconds
}
void displayTemperature(float temperature) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature, 1);
lcd.print("°C");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(getTemperatureStatus(temperature));
delay(2000); // Wait 2 seconds
}
void displayHumidity(float humidity) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hum: ");
lcd.print(humidity, 1);
lcd.print(" %RH");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(getHumidityStatus(humidity));
delay(2000); // Wait 2 seconds
}
void loop() {
triggerMeasurement();
int distanceCM = readDistance();
int waterLevel = calculateWaterLevel(distanceCM);
// Read temperature and humidity
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float temperature = data.temperature;
float humidity = data.humidity;
// Display Water Level
displayWaterLevel(waterLevel);
// Display Temperature
displayTemperature(temperature);
// Display Humidity
displayHumidity(humidity);
// Handle alarm and LED
if (waterLevel <= 60) { // Critical low level
handleCriticalLowLevel();
} else if (waterLevel <= 150) { // Warning level
handleWarningLevel();
} else {
handleNormalLevel();
}
checkBuzzer();
// delay(2000); // Delay before the next cycle
}