#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHTesp.h>
#define PIN_TRIG 5
#define PIN_ECHO 18
#define ON_LED 0
#define ALERT_LED 17
#define TANK_HEIGHT_CM 300 // total height of the tank in cm
#define BUZZER_ALARM 23
#define BUZZER_DURATION_MS 5000 // Duration to keep the buzzer on in ms
// LCD i2c address for 16x2
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int DHT_PIN = 33;
DHTesp dhtSensor;
unsigned long buzzerStartTime = 0; // Store the time when the buzzer was turned on
bool buzzerActive = false; // To track the buzzer state
bool warningOrNormalDetected = false; // To track if warning or normal level was detected
unsigned long lastBlinkTime = 0; // Timer for LED blinking
bool isLedOn = false; // To track the LED state
void setup() {
Serial.begin(115200); // Baud rate of ESP32
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 LCD
lcd.backlight(); // Turn on the backlight
displayMsg("System Initializing", "Please Wait...");
}
void displayMsg(String message1, String message2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(message1);
lcd.setCursor(0, 1);
lcd.print(message2);
delay(3000); // Display for 3 seconds
}
int measureWaterLvl() {
digitalWrite(PIN_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
int duration = pulseIn(PIN_ECHO, HIGH);
Serial.print("Duration: "); // Debugging line
Serial.println(duration); // Debugging line
return duration * 0.0343 / 2; // Convert duration to distance in cm
}
int calcWaterLevel(int distanceCM) {
return distanceCM; // Calculate water level (refer code bfore)
}
void handleCriticalLevel() {
digitalWrite(ALERT_LED, HIGH);
if (!buzzerActive && warningOrNormalDetected) {
digitalWrite(BUZZER_ALARM, HIGH);
tone(BUZZER_ALARM, 1000);
buzzerStartTime = millis();
buzzerActive = true; // Set buzzer as active
warningOrNormalDetected = false; // Reset warning/normal detection flag
}
}
void handleWarningLevel() {
unsigned long currentMillis = millis();
if (currentMillis - lastBlinkTime >= 2000) { // Check if 2 seconds have passed
lastBlinkTime = currentMillis; // Reset the timer
isLedOn = !isLedOn; // Toggle the LED state
digitalWrite(ALERT_LED, isLedOn ? HIGH : LOW); // Blink the LED
}
handleNormalLevel(); // Ensure buzzer off
}
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
warningOrNormalDetected = true; // Set warning/normal detection flag
}
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 waterLvlStatus(int waterLevel) {
if (waterLevel <= 30) { // Critical low level
return "CRITICAL";
} else if (waterLevel <= 70) { // Warning level
return "WARNING";
} else {
return "NORMAL";
}
}
String tempStatus(float temperature) {
if (temperature < 5.0 || temperature > 45.0) {
return "WARNING";
} else {
return "NORMAL";
}
}
String humStatus(float humidity) {
if (humidity < 20.0 || humidity > 80.0) {
return "WARNING";
} else {
return "NORMAL";
}
}
void displayLCD(int waterLevel, float temperature, float humidity) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WaterLvl: ");
lcd.print(waterLevel);
lcd.print("cm");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(waterLvlStatus(waterLevel));
delay(1500); // Wait 2 seconds
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature, 1);
lcd.print("degC");
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.print(tempStatus(temperature));
delay(1500); // Wait 2 seconds
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(humStatus(humidity));
delay(1500); // Wait 2 seconds
}
void loop() {
unsigned long startMillis = millis(); // Start the measurement cycle
while (millis() - startMillis < 60000) { // Run for 1 minute
int distanceCM = measureWaterLvl();
int waterLevel = calcWaterLevel(distanceCM);
// Read temperature and humidity
TempAndHumidity data = dhtSensor.getTempAndHumidity();
float temperature = data.temperature;
float humidity = data.humidity;
displayLCD(waterLevel, temperature, humidity);
// Handle alarm and LED
if (waterLevel <= 30) { // Critical low level
handleCriticalLevel();
} else if (waterLevel <= 70) { // Warning level
handleWarningLevel();
} else { // Normal level
handleNormalLevel();
}
checkBuzzer();
delay(1000); // Short delay to allow other tasks to run smoothly
}
}