/*
* SmartDrain Chennai - FIXED LED Control Version
* LEDs now work exactly as described
*/
// Pin definitions (matching your diagram.json)
#define TRIG_PIN 26 // Ultrasonic TRIG
#define ECHO_PIN 25 // Ultrasonic ECHO
#define RELAY_PIN 27 // Motor/pump relay
#define GAS_PIN 36 // Gas sensor (VP pin)
#define BUTTON_PIN 34 // Tamper button
// LEDs
#define LED_GREEN 18 // Normal (led3)
#define LED_YELLOW1 19 // Warning 1 (led4)
#define LED_YELLOW2 21 // Warning 2 (led2)
#define LED_BLUE 2 // Gas/Status LED (status_led)
// Water level thresholds (distance in cm)
#define DISTANCE_NORMAL 100 // >100cm = Normal
#define DISTANCE_WARNING1 50 // 50-100cm = Warning 1
#define DISTANCE_WARNING2 20 // 20-50cm = Warning 2
#define DISTANCE_CRITICAL 10 // <10cm = Critical
// Gas thresholds (raw analog values)
#define GAS_NORMAL 800 // Normal gas level
#define GAS_WARNING 1500 // Warning gas level
#define GAS_CRITICAL 2500 // Critical gas level
// Global variables
float distance;
int gasRaw;
int gasPPM;
bool tamperDetected;
String waterStatus;
String gasStatus;
String overallAlert;
unsigned long lastReading = 0;
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("\n");
Serial.println("๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐");
Serial.println(" SMARTDRAIN CHENNAI MONITORING SYSTEM ");
Serial.println(" Urban Flood Prevention - FIXED LED VERSION ");
Serial.println("๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐");
// Initialize pins
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW1, OUTPUT);
pinMode(LED_YELLOW2, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
// Turn off all outputs initially
digitalWrite(RELAY_PIN, LOW);
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW1, LOW);
digitalWrite(LED_YELLOW2, LOW);
digitalWrite(LED_BLUE, LOW);
// System initialization
Serial.println("๐ง INITIALIZING SYSTEM COMPONENTS...");
testAllComponents();
Serial.println("๐ WATER LEVEL THRESHOLDS:");
Serial.println(" ๐ข NORMAL: > " + String(DISTANCE_NORMAL) + " cm (Low Water)");
Serial.println(" ๐ก WARNING 1: " + String(DISTANCE_WARNING1) + "-" + String(DISTANCE_NORMAL) + " cm (Medium Water)");
Serial.println(" ๐ WARNING 2: " + String(DISTANCE_WARNING2) + "-" + String(DISTANCE_WARNING1) + " cm (High Water)");
Serial.println(" ๐ด CRITICAL: < " + String(DISTANCE_CRITICAL) + " cm (Flood Level!)");
Serial.println("\n๐งช GAS DETECTION THRESHOLDS:");
Serial.println(" ๐ข NORMAL: < " + String(GAS_NORMAL) + " (Safe Air)");
Serial.println(" ๐ก WARNING: " + String(GAS_NORMAL) + "-" + String(GAS_WARNING) + " (Elevated)");
Serial.println(" ๐ด CRITICAL: > " + String(GAS_CRITICAL) + " (Dangerous!)");
Serial.println("\nโ
SMARTDRAIN SYSTEM READY!");
Serial.println("๐ Starting continuous monitoring...");
Serial.println("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ");
}
void loop() {
// Read sensors every 3 seconds
if (millis() - lastReading >= 3000) {
readAllSensors();
processAlertsFixed(); // Using fixed version
displayDetailedStatus();
lastReading = millis();
}
delay(100);
}
void testAllComponents() {
Serial.println(" ๐ฆ Testing LED indicators...");
Serial.println(" ๐ข Green LED (Normal Status)");
digitalWrite(LED_GREEN, HIGH); delay(800); digitalWrite(LED_GREEN, LOW);
Serial.println(" ๐ก Yellow LED 1 (Warning Level 1)");
digitalWrite(LED_YELLOW1, HIGH); delay(800); digitalWrite(LED_YELLOW1, LOW);
Serial.println(" ๐ Yellow LED 2 (Warning Level 2)");
digitalWrite(LED_YELLOW2, HIGH); delay(800); digitalWrite(LED_YELLOW2, LOW);
Serial.println(" ๐ต Blue LED (Gas Detection Status)");
digitalWrite(LED_BLUE, HIGH); delay(800); digitalWrite(LED_BLUE, LOW);
// Test sensors
Serial.println(" ๐ก Testing sensor readings...");
for(int i = 0; i < 3; i++) {
float testDistance = readDistanceSensor();
int testGas = analogRead(GAS_PIN);
Serial.println(" Test " + String(i+1) + ": Distance=" + String(testDistance, 1) + "cm, Gas=" + String(testGas));
delay(500);
}
Serial.println(" โ
All components tested successfully!");
Serial.println("");
}
void readAllSensors() {
// Read ultrasonic distance sensor
distance = readDistanceSensor();
// Read gas sensor
gasRaw = analogRead(GAS_PIN);
gasPPM = map(gasRaw, 0, 4095, 50, 1000); // Convert to estimated PPM
// Add realistic gas variation for demo
if (random(100) < 10) { // 10% chance of gas spike
gasRaw += random(500, 1500);
gasPPM = map(gasRaw, 0, 4095, 50, 1000);
}
// Read tamper detection
tamperDetected = (digitalRead(BUTTON_PIN) == LOW);
// Determine status levels
determineWaterStatus();
determineGasStatus();
determineOverallAlert();
}
float readDistanceSensor() {
// Send ultrasonic pulse
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Read echo
float duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
if (duration == 0) {
Serial.println("โ ๏ธ SENSOR ERROR: Ultrasonic timeout");
return -1; // Error value
}
// Convert to distance
float dist = duration * 0.034 / 2;
// Add realistic variation (ยฑ2cm)
dist += random(-20, 21) / 10.0;
return constrain(dist, 0, 400);
}
void determineWaterStatus() {
if (distance < 0) {
waterStatus = "SENSOR_ERROR";
} else if (distance > DISTANCE_NORMAL) {
waterStatus = "NORMAL";
} else if (distance > DISTANCE_WARNING1) {
waterStatus = "WARNING_1";
} else if (distance > DISTANCE_WARNING2) {
waterStatus = "WARNING_2";
} else {
waterStatus = "CRITICAL_FLOOD";
}
}
void determineGasStatus() {
if (gasRaw < GAS_NORMAL) {
gasStatus = "SAFE";
} else if (gasRaw < GAS_WARNING) {
gasStatus = "ELEVATED";
} else if (gasRaw < GAS_CRITICAL) {
gasStatus = "WARNING";
} else {
gasStatus = "DANGEROUS";
}
}
void determineOverallAlert() {
if (waterStatus == "CRITICAL_FLOOD" || gasStatus == "DANGEROUS" || tamperDetected) {
overallAlert = "๐จ CRITICAL EMERGENCY";
} else if (waterStatus == "WARNING_2" || gasStatus == "WARNING") {
overallAlert = "โ ๏ธ HIGH ALERT";
} else if (waterStatus == "WARNING_1" || gasStatus == "ELEVATED") {
overallAlert = "โ ๏ธ LOW ALERT";
} else if (waterStatus == "SENSOR_ERROR") {
overallAlert = "๐ง SYSTEM ERROR";
} else {
overallAlert = "โ
ALL NORMAL";
}
}
// FIXED LED CONTROL FUNCTION
void processAlertsFixed() {
// Turn off all LEDs first
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW1, LOW);
digitalWrite(LED_YELLOW2, LOW);
digitalWrite(LED_BLUE, LOW);
// === WATER LEVEL LED CONTROL (FIXED) ===
if (tamperDetected) {
// TAMPER DETECTED - Flash all water LEDs
bool fastFlash = (millis() / 300) % 2;
digitalWrite(LED_GREEN, fastFlash);
digitalWrite(LED_YELLOW1, fastFlash);
digitalWrite(LED_YELLOW2, fastFlash);
} else if (waterStatus == "CRITICAL_FLOOD") {
// FLOOD EMERGENCY - Flash all water LEDs
bool emergencyFlash = (millis() / 400) % 2;
digitalWrite(LED_GREEN, emergencyFlash);
digitalWrite(LED_YELLOW1, emergencyFlash);
digitalWrite(LED_YELLOW2, emergencyFlash);
} else if (waterStatus == "WARNING_2") {
// HIGH WATER - Only Yellow LED 2
digitalWrite(LED_YELLOW2, HIGH);
} else if (waterStatus == "WARNING_1") {
// MEDIUM WATER - Only Yellow LED 1
digitalWrite(LED_YELLOW1, HIGH);
} else if (waterStatus == "NORMAL") {
// LOW WATER - Only Green LED
digitalWrite(LED_GREEN, HIGH);
}
// If SENSOR_ERROR, all water LEDs stay OFF
// === GAS LEVEL BLUE LED CONTROL (FIXED) ===
if (tamperDetected) {
// TAMPER - Fast flash blue LED
digitalWrite(LED_BLUE, (millis() / 200) % 2);
} else if (gasStatus == "DANGEROUS") {
// TOXIC GAS - Fast flash
digitalWrite(LED_BLUE, (millis() / 200) % 2);
} else if (gasStatus == "WARNING") {
// GAS WARNING - Slow flash
digitalWrite(LED_BLUE, (millis() / 800) % 2);
} else if (gasStatus == "ELEVATED") {
// ELEVATED GAS - Steady on
digitalWrite(LED_BLUE, HIGH);
}
// If SAFE gas, blue LED stays OFF
// === RELAY CONTROL ===
bool activateRelay = (waterStatus == "CRITICAL_FLOOD" ||
gasStatus == "DANGEROUS" ||
tamperDetected);
digitalWrite(RELAY_PIN, activateRelay);
}
void displayDetailedStatus() {
Serial.println("\n");
Serial.println("๐ โโโโโโโโโโโโโโโ SENSOR STATUS REPORT โโโโโโโโโโโโโโโ");
Serial.println("โฐ Timestamp: " + String(millis()/1000) + " seconds");
Serial.println("๐ Location: Marina Beach Drainage Node, Chennai");
Serial.println("");
// Water level status
Serial.println("๐ WATER LEVEL MONITORING:");
Serial.println(" ๐ Distance Reading: " + String(distance, 1) + " cm");
Serial.println(" ๐ง Water Level: " + waterStatus);
String waterIcon = "๐ข";
if (waterStatus == "WARNING_1") waterIcon = "๐ก";
else if (waterStatus == "WARNING_2") waterIcon = "๐ ";
else if (waterStatus == "CRITICAL_FLOOD") waterIcon = "๐ด";
Serial.println(" " + waterIcon + " Status Indicator: " + getWaterDescription());
// Gas detection status
Serial.println("\n๐งช GAS DETECTION SYSTEM:");
Serial.println(" ๐ Raw Sensor Value: " + String(gasRaw) + " (0-4095 range)");
Serial.println(" ๐จ Estimated PPM: " + String(gasPPM));
Serial.println(" โ ๏ธ Gas Level: " + gasStatus);
String gasIcon = "๐ข";
if (gasStatus == "ELEVATED") gasIcon = "๐ก";
else if (gasStatus == "WARNING") gasIcon = "๐ ";
else if (gasStatus == "DANGEROUS") gasIcon = "๐ด";
Serial.println(" " + gasIcon + " Status Indicator: " + getGasDescription());
// Security status
Serial.println("\n๐ SECURITY MONITORING:");
Serial.println(" ๐ช Tamper Detection: " + String(tamperDetected ? "โ ๏ธ BREACH DETECTED!" : "โ
Secure"));
// System outputs - REAL-TIME LED STATUS
Serial.println("\nโก SYSTEM RESPONSES (LIVE LED STATUS):");
Serial.println(" ๐ข Green LED (Normal): " + String(digitalRead(LED_GREEN) ? "ON" : "OFF"));
Serial.println(" ๐ก Yellow LED 1 (Warn1): " + String(digitalRead(LED_YELLOW1) ? "ON" : "OFF"));
Serial.println(" ๐ Yellow LED 2 (Warn2): " + String(digitalRead(LED_YELLOW2) ? "ON" : "OFF"));
Serial.println(" ๐ต Blue LED (Gas): " + String(digitalRead(LED_BLUE) ? "ON" : "OFF"));
Serial.println(" ๐ Pump Relay: " + String(digitalRead(RELAY_PIN) ? "ACTIVE" : "STANDBY"));
// LED behavior explanation
Serial.println("\n๐ก LED BEHAVIOR LOGIC:");
Serial.println(" Water LEDs: " + getWaterLEDStatus());
Serial.println(" Gas LED: " + getGasLEDStatus());
// Overall system status
Serial.println("\n๐จ OVERALL SYSTEM ALERT LEVEL:");
Serial.println(" " + overallAlert);
// Emergency messages
if (waterStatus == "CRITICAL_FLOOD") {
Serial.println("\n๐จ๐ FLOOD EMERGENCY: Critical water level detected!");
Serial.println(" โค Immediate evacuation may be required");
Serial.println(" โค Emergency pump activated");
}
if (gasStatus == "DANGEROUS") {
Serial.println("\n๐จโ ๏ธ GAS EMERGENCY: Dangerous gas levels detected!");
Serial.println(" โค Area evacuation required immediately");
Serial.println(" โค Do not enter confined spaces");
}
if (tamperDetected) {
Serial.println("\n๐จ๐ SECURITY ALERT: Unauthorized access detected!");
Serial.println(" โค Possible equipment tampering");
Serial.println(" โค Security response required");
}
Serial.println("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ");
// Add some spacing for readability
delay(500);
}
String getWaterLEDStatus() {
if (tamperDetected || waterStatus == "CRITICAL_FLOOD") {
return "All flashing (Emergency)";
} else if (waterStatus == "WARNING_2") {
return "Yellow 2 only (High water)";
} else if (waterStatus == "WARNING_1") {
return "Yellow 1 only (Medium water)";
} else if (waterStatus == "NORMAL") {
return "Green only (Normal water)";
} else {
return "All off (Sensor error)";
}
}
String getGasLEDStatus() {
if (tamperDetected || gasStatus == "DANGEROUS") {
return "Fast flash (Emergency)";
} else if (gasStatus == "WARNING") {
return "Slow flash (Warning)";
} else if (gasStatus == "ELEVATED") {
return "Steady on (Elevated)";
} else {
return "Off (Safe)";
}
}
String getWaterDescription() {
if (waterStatus == "NORMAL") return "Low water, normal drainage";
else if (waterStatus == "WARNING_1") return "Medium water level, monitor closely";
else if (waterStatus == "WARNING_2") return "High water level, flood risk increasing";
else if (waterStatus == "CRITICAL_FLOOD") return "FLOOD CONDITIONS - Emergency response!";
else return "Sensor malfunction detected";
}
String getGasDescription() {
if (gasStatus == "SAFE") return "Air quality normal, safe environment";
else if (gasStatus == "ELEVATED") return "Slightly elevated gas levels detected";
else if (gasStatus == "WARNING") return "Concerning gas levels, caution advised";
else if (gasStatus == "DANGEROUS") return "TOXIC LEVELS - Evacuate immediately!";
else return "Unknown gas status";
}