#define BLYNK_TEMPLATE_ID "TMPL63K_hOSwQ"
#define BLYNK_TEMPLATE_NAME "Water Monitoring System ESP32"
#define BLYNK_AUTH_TOKEN "0h3yjd89g0NV8P1bJxRJZDMBTXCXwYph"
#define BLYNK_PRINT Serial
#include <Wire.h>
#include <DHT.h>
#include <BlynkSimpleEsp32.h>
#include <WiFi.h>
// WiFi credentials for Blynk connection
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST"; // Wi-Fi SSID
char pass[] = ""; // Wi-Fi password
// Ultrasonic sensor pins for water level measurement
#define TRIG_PIN 5
#define ECHO_PIN 27
#define MAX_DISTANCE 400 // Maximum measurable distance in cm
// DHT sensor for temperature and humidity monitoring
#define DHTPIN 12
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor
// Potentiometer to simulate water flow rate
#define POT_PIN 36
// Relay for controlling water flow
#define RELAY_PIN 14
// Global variables for water level, usage, and sensor readings
long duration;
float distanceCm = 0.0; // Current water level
float lastDistanceCm = 0.0; // Previous water level for leak detection
float waterUsed = 0.0; // Total water usage in liters
float temperature = 0.0; // Temperature reading in °C
float humidity = 0.0; // Humidity reading in %
float flowRate = 0.0; // Flow rate in liters per second
bool leakDetected = false; // Flag for detecting water leaks
const float LIMIT_LITERS = 180.0; // Maximum water usage threshold
const float LOW_WATER_THRESHOLD = 10.0; // Alert threshold for low water level
BlynkTimer timer; // Timer for scheduling updates
// Function declarations
void sendWaterUsage(); // Sends water usage data to Blynk
void sendTemperature(); // Reads and sends temperature data
void sendHumidity(); // Reads and sends humidity data
void sendDistance(); // Measures and sends water level data
void setup() {
Serial.begin(115200);
// Sensor initialization
dht.begin(); // Start DHT sensor
pinMode(TRIG_PIN, OUTPUT); // Ultrasonic sensor trigger pin
pinMode(ECHO_PIN, INPUT); // Ultrasonic sensor echo pin
pinMode(RELAY_PIN, OUTPUT); // Relay control pin
digitalWrite(RELAY_PIN, HIGH); // Set relay to active (default)
// Connect to Blynk platform
Blynk.begin(auth, ssid, pass);
// Schedule periodic updates for sensors and dashboard
timer.setInterval(2000L, sendWaterUsage); // Update water usage every 2 seconds
timer.setInterval(3000L, sendTempAndHumidity);// Update temp/humidity every 3 seconds
timer.setInterval(5000L, sendDistance); // Update water level every 5 seconds
}
void loop() {
Blynk.run(); // Maintain Blynk connection
timer.run(); // Execute scheduled tasks
}
// Simulates flow rate and sends cumulative water usage
void sendWaterUsage() {
int potValue = analogRead(POT_PIN); // Simulate water flow using potentiometer
const float MAX_FLOW_RATE = 500.0;
flowRate = map(potValue, 0, 4095, 0, MAX_FLOW_RATE) / 100.0; // Calculate flow rate
waterUsed += flowRate; // Update water usage
// Alert if usage exceeds the set limit
if (waterUsed > LIMIT_LITERS) {
Serial.println("WARNING: Water usage limit exceeded!");
Blynk.logEvent("water_usage_limit");
}
Blynk.virtualWrite(V1, waterUsed); // Send data to Blynk dashboard
Serial.print("Water Usage: ");
Serial.print(waterUsed, 1);
Serial.println(" Liter");
}
// Reads temperature and humidity from DHT22 sensor, sends data, and triggers alerts
void sendTempAndHumidity() {
temperature = dht.readTemperature(); // Temperature reading
humidity = dht.readHumidity(); // Humidity reading
// Validate readings and trigger alerts if necessary
if (!isnan(temperature) && !isnan(humidity)) {
if (temperature > 28.0) {
Serial.println("WARNING: Risk of microbial growth due to high temperature!");
Blynk.logEvent("t");
}
if (humidity > 80.0) {
Serial.println("WARNING: Risk of microbial growth due to high humidity!");
Blynk.logEvent("h");
}
Blynk.virtualWrite(V2, temperature); // Send temperature data
Blynk.virtualWrite(V3, humidity); // Send humidity data
Serial.print("Temperature: ");
Serial.print(temperature, 1);
Serial.print(" °C, Humidity: ");
Serial.print(humidity, 1);
Serial.println(" %");
} else {
Serial.println("Failed to read temperature or humidity!");
}
}
// Measures water level using ultrasonic sensor, sends data, and checks for alerts
void sendDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH, 30000); // Measure pulse duration
// Skip invalid measurements
if (duration == 0) {
Serial.println("Ultrasonic sensor failed to detect distance.");
return;
}
const float SOUND_SPEED_CM_PER_US = 0.034;
distanceCm = duration * SOUND_SPEED_CM_PER_US / 2; // Calculate water level
// Alert for low water level
bool lowWaterLevel = (distanceCm < LOW_WATER_THRESHOLD);
Blynk.virtualWrite(V5, lowWaterLevel ? "LOW WATER LEVEL ALERT" : "Water level is normal");
if (lowWaterLevel) Blynk.logEvent("low_water_level");
Serial.print(lowWaterLevel ? "WARNING: Water level is low! Distance is " : "Water level is normal. Distance: ");
Serial.println(distanceCm, 1);
// Leak detection logic
leakDetected = (flowRate > 0 && abs(distanceCm - lastDistanceCm) < 10.0);
if (leakDetected) {
Blynk.logEvent("leak_detection");
Serial.print("WARNING: Leak Detected! Distance difference is ");
} else {
Serial.print("No leak detected. Distance difference: ");
}
Serial.println(abs(distanceCm - lastDistanceCm), 1);
digitalWrite(RELAY_PIN, leakDetected ? LOW : HIGH); // Control relay based on leak status
lastDistanceCm = distanceCm; // Update last measured level
Blynk.virtualWrite(V4, distanceCm); // Send water level data
Serial.print("Water Level (Distance): ");
Serial.println(distanceCm, 1);
}