/*
ESP32-S3 Flood Detector - Wokwi Simulation
Components:
- ESP32-S3 DevKitC-1
- HC-SR04 ultrasonic sensor
- I2C LCD 16x2
- SG90 servo motor
- Piezo buzzer
- 4 LEDs:
Red = DANGER
Orange = MEDIUM
Yellow = LOW
Green = SAFE
Water height formula:
waterHeight = 335 - distanceInCm
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// ---------- ESP32-S3 GPIO PINS ----------
const int TRIG_PIN = 4;
const int ECHO_PIN = 5;
const int BUZZER_PIN = 6;
const int SERVO_PIN = 7;
const int LCD_SDA_PIN = 8;
const int LCD_SCL_PIN = 9;
const int RED_LED_PIN = 10;
const int ORANGE_LED_PIN = 11;
const int YELLOW_LED_PIN = 12;
const int GREEN_LED_PIN = 13;
// ---------- OBJECTS ----------
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo floodServo;
// ---------- VARIABLES ----------
float distanceInCm = -1;
float waterHeight = 0;
String currentStatus = "";
String previousStatus = "";
// Used to make the danger buzzer beep continuously
unsigned long lastBuzzerChange = 0;
bool buzzerOn = false;
// ---------- FUNCTION DECLARATIONS ----------
float readDistanceCM();
void turnOffAllLEDs();
void updateOutputs();
void updateLCD();
void updateBuzzer();
void telegramSimulation();
// ---------- SETUP ----------
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(ORANGE_LED_PIN, OUTPUT);
pinMode(YELLOW_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
digitalWrite(TRIG_PIN, LOW);
turnOffAllLEDs();
noTone(BUZZER_PIN);
// LCD I2C pins
Wire.begin(LCD_SDA_PIN, LCD_SCL_PIN);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Flood Detector");
lcd.setCursor(0, 1);
lcd.print("ESP32-S3 Ready");
// SG90 servo configuration
floodServo.setPeriodHertz(50);
floodServo.attach(SERVO_PIN, 500, 2400);
floodServo.write(0);
delay(1500);
Serial.println();
Serial.println("=================================");
Serial.println("ESP32-S3 FLOOD DETECTOR STARTED");
Serial.println("Change HC-SR04 distance in Wokwi");
Serial.println("300 cm = SAFE");
Serial.println("200 cm = LOW");
Serial.println("120 cm = MEDIUM");
Serial.println("50 cm = DANGER");
Serial.println("=================================");
}
// ---------- LOOP ----------
void loop() {
// Read ultrasonic distance
distanceInCm = readDistanceCM();
// Handle sensor errors
if (distanceInCm < 0) {
currentStatus = "SENSOR ERROR";
turnOffAllLEDs();
floodServo.write(0);
noTone(BUZZER_PIN);
buzzerOn = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SENSOR ERROR");
lcd.setCursor(0, 1);
lcd.print("Check HC-SR04");
Serial.println("Sensor Error: No valid reading.");
if (currentStatus != previousStatus) {
telegramSimulation();
previousStatus = currentStatus;
}
delay(500);
return;
}
// Calculate water height using your original formula
waterHeight = 335 - distanceInCm;
// Decide flood status
if (distanceInCm > 240) {
currentStatus = "SAFE";
}
else if (distanceInCm > 160) {
currentStatus = "LOW";
}
else if (distanceInCm > 80) {
currentStatus = "MEDIUM";
}
else {
currentStatus = "DANGER";
}
// Control all outputs
updateOutputs();
updateBuzzer();
updateLCD();
// Print information in the Wokwi Serial Monitor
Serial.print("Distance: ");
Serial.print(distanceInCm, 1);
Serial.print(" cm | Height: ");
Serial.print(waterHeight, 1);
Serial.print(" cm | Status: ");
Serial.println(currentStatus);
// Simulated Telegram alert when status changes
if (currentStatus != previousStatus) {
telegramSimulation();
previousStatus = currentStatus;
}
delay(250);
}
// ---------- HC-SR04 FUNCTION ----------
float readDistanceCM() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) {
return -1;
}
float distance = duration * 0.0343 / 2.0;
if (distance < 2 || distance > 400) {
return -1;
}
return distance;
}
// ---------- LED FUNCTION ----------
void turnOffAllLEDs() {
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(ORANGE_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, LOW);
}
// ---------- LED AND SERVO CONTROL ----------
void updateOutputs() {
turnOffAllLEDs();
if (currentStatus == "SAFE") {
digitalWrite(GREEN_LED_PIN, HIGH);
floodServo.write(0);
}
else if (currentStatus == "LOW") {
digitalWrite(YELLOW_LED_PIN, HIGH);
floodServo.write(30);
}
else if (currentStatus == "MEDIUM") {
digitalWrite(ORANGE_LED_PIN, HIGH);
floodServo.write(60);
}
else if (currentStatus == "DANGER") {
digitalWrite(RED_LED_PIN, HIGH);
floodServo.write(90);
}
}
// ---------- BUZZER CONTROL ----------
void updateBuzzer() {
// Buzzer only operates in DANGER status
if (currentStatus != "DANGER") {
noTone(BUZZER_PIN);
buzzerOn = false;
return;
}
// Danger alarm pattern:
// 250 ms sound, 250 ms silence, repeat.
if (millis() - lastBuzzerChange >= 250) {
lastBuzzerChange = millis();
if (buzzerOn) {
noTone(BUZZER_PIN);
buzzerOn = false;
} else {
tone(BUZZER_PIN, 2000);
buzzerOn = true;
}
}
}
// ---------- LCD DISPLAY ----------
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Height:");
lcd.print(waterHeight, 1);
lcd.print("cm");
lcd.setCursor(0, 1);
if (currentStatus == "SAFE") {
lcd.print("Status: SAFE");
}
else if (currentStatus == "LOW") {
lcd.print("Status: LOW");
}
else if (currentStatus == "MEDIUM") {
lcd.print("Status: MEDIUM");
}
else if (currentStatus == "DANGER") {
lcd.print("Status: DANGER!");
}
}
// ---------- TELEGRAM SIMULATION ----------
void telegramSimulation() {
Serial.println();
Serial.println("------ TELEGRAM SIMULATION ------");
if (currentStatus == "SAFE") {
Serial.println("SAFE: Water level is normal.");
Serial.println("Green LED ON | Servo: 0 degrees");
}
else if (currentStatus == "LOW") {
Serial.println("LOW: Water level is increasing.");
Serial.println("Yellow LED ON | Servo: 30 degrees");
}
else if (currentStatus == "MEDIUM") {
Serial.println("MEDIUM: Water level is rising.");
Serial.println("Orange LED ON | Servo: 60 degrees");
}
else if (currentStatus == "DANGER") {
Serial.println("DANGER! FLOOD RISK DETECTED!");
Serial.println("Red LED ON | Servo: 90 degrees");
Serial.println("Buzzer alarm: ON (beep-beep pattern)");
Serial.println("Take action immediately.");
}
else {
Serial.println("SYSTEM ERROR: Ultrasonic sensor issue.");
}
Serial.println("---------------------------------");
Serial.println();
}Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1