IoT-Based Fire Detection & Alert System

 




Build an advanced fire detection system with multiple sensors, instant alerts, and automatic response.

Key Features

  • Smoke & flame detection
  • Temperature monitoring
  • SMS/Email/App alerts
  • Automatic sprinkler activation
  • Multi-zone monitoring
Diagram.json:
{
  "version": 1,
  "author": "IoT Fire Detection System",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-esp32-devkit-v1",
      "id": "esp",
      "top": 0,
      "left": 0,
      "attrs": {}
    },
    {
      "type": "wokwi-dht22",
      "id": "dht1",
      "top": -86.4,
      "left": 124.8,
      "attrs": { "temperature": "30", "humidity": "50" }
    },
    {
      "type": "wokwi-potentiometer",
      "id": "smoke",
      "top": -19.2,
      "left": 297.6,
      "rotate": 180,
      "attrs": { "label": "Smoke Sensor (MQ-2)" }
    },
    {
      "type": "wokwi-potentiometer",
      "id": "flame",
      "top": 86.4,
      "left": 297.6,
      "rotate": 180,
      "attrs": { "label": "Flame Sensor" }
    },
    {
      "type": "wokwi-led",
      "id": "red_led",
      "top": -124.8,
      "left": 422.4,
      "attrs": { "color": "red", "lightColor": "red", "label": "DANGER" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": -67.2,
      "left": 422.4,
      "rotate": 90,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-led",
      "id": "green_led",
      "top": -124.8,
      "left": 499.2,
      "attrs": { "color": "green", "lightColor": "green", "label": "SAFE" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": -67.2,
      "left": 499.2,
      "rotate": 90,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-led",
      "id": "blue_led",
      "top": -124.8,
      "left": 576,
      "attrs": { "color": "blue", "lightColor": "blue", "label": "WARNING" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r3",
      "top": -67.2,
      "left": 576,
      "rotate": 90,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-led",
      "id": "sprinkler",
      "top": 38.4,
      "left": 422.4,
      "attrs": { "color": "cyan", "lightColor": "cyan", "label": "Sprinkler" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r4",
      "top": 96,
      "left": 422.4,
      "rotate": 90,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-led",
      "id": "fan",
      "top": 38.4,
      "left": 499.2,
      "attrs": { "color": "white", "lightColor": "white", "label": "Exhaust Fan" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r5",
      "top": 96,
      "left": 499.2,
      "rotate": 90,
      "attrs": { "value": "220" }
    },
    {
      "type": "wokwi-buzzer",
      "id": "bz1",
      "top": 172.8,
      "left": 470.4,
      "attrs": { "volume": "0.5" }
    },
    {
      "type": "wokwi-ssd1306",
      "id": "oled1",
      "top": 192,
      "left": 249.6,
      "attrs": { "i2cAddress": "0x3C" }
    }
  ],
  "connections": [
    [ "esp:TX0", "$serialMonitor:RX", "", [] ],
    [ "esp:RX0", "$serialMonitor:TX", "", [] ],
   
    [ "dht1:VCC", "esp:3V3", "red", [ "v0" ] ],
    [ "dht1:GND", "esp:GND.1", "black", [ "v0" ] ],
    [ "dht1:SDA", "esp:D15", "green", [ "v0" ] ],
   
    [ "smoke:GND", "esp:GND.1", "black", [ "v0" ] ],
    [ "smoke:VCC", "esp:3V3", "red", [ "v0" ] ],
    [ "smoke:SIG", "esp:D34", "orange", [ "v0" ] ],
   
    [ "flame:GND", "esp:GND.2", "black", [ "v0" ] ],
    [ "flame:VCC", "esp:3V3", "red", [ "v0" ] ],
    [ "flame:SIG", "esp:D35", "yellow", [ "v0" ] ],
   
    [ "red_led:A", "esp:D26", "red", [ "v0" ] ],
    [ "red_led:C", "r1:1", "red", [ "v0" ] ],
    [ "r1:2", "esp:GND.1", "black", [ "v0" ] ],
   
    [ "green_led:A", "esp:D27", "green", [ "v0" ] ],
    [ "green_led:C", "r2:1", "green", [ "v0" ] ],
    [ "r2:2", "esp:GND.1", "black", [ "v0" ] ],
   
    [ "blue_led:A", "esp:D14", "blue", [ "v0" ] ],
    [ "blue_led:C", "r3:1", "blue", [ "v0" ] ],
    [ "r3:2", "esp:GND.1", "black", [ "v0" ] ],
   
    [ "sprinkler:A", "esp:D12", "cyan", [ "v0" ] ],
    [ "sprinkler:C", "r4:1", "cyan", [ "v0" ] ],
    [ "r4:2", "esp:GND.2", "black", [ "v0" ] ],
   
    [ "fan:A", "esp:D13", "white", [ "v0" ] ],
    [ "fan:C", "r5:1", "white", [ "v0" ] ],
    [ "r5:2", "esp:GND.2", "black", [ "v0" ] ],
   
    [ "bz1:1", "esp:D25", "purple", [ "v0" ] ],
    [ "bz1:2", "esp:GND.2", "black", [ "v0" ] ],
   
    [ "oled1:VCC", "esp:3V3", "red", [ "h0" ] ],
    [ "oled1:GND", "esp:GND.2", "black", [ "h0" ] ],
    [ "oled1:SDA", "esp:D21", "blue", [ "h0" ] ],
    [ "oled1:SCL", "esp:D22", "yellow", [ "h0" ] ]
  ],
  "dependencies": {}
}


Components Required

  • ESP32 Board
  • MQ-2 Smoke Sensor
  • Flame Sensor (IR)
  • DHT22 Temperature Sensor
  • Buzzer & LED indicators
  • GSM Module (optional)
Code:
/*
 * IoT-Based Fire Detection & Alert System
 *
 * Features:
 * - MQ-2 Gas/Smoke Sensor detection
 * - DHT22 Temperature & Humidity monitoring
 * - Flame sensor detection
 * - Multi-level alert system (Warning, Danger, Critical)
 * - Buzzer alarm with different patterns
 * - RGB LED visual indicators
 * - OLED display for status
 * - Web dashboard for remote monitoring
 * - SMS/Email alert simulation
 * - Automatic fire suppression trigger
 * - Data logging
 * - Real-time notifications
 */

#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// WiFi Credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// Web Server
WebServer server(80);

// Pin Definitions
#define DHT_PIN 15           // Temperature & Humidity sensor
#define MQ2_PIN 34           // Gas/Smoke sensor (analog)
#define FLAME_PIN 35         // Flame sensor (analog)
#define BUZZER_PIN 25        // Alarm buzzer
#define RED_LED_PIN 26       // Red LED (Danger)
#define GREEN_LED_PIN 27     // Green LED (Safe)
#define BLUE_LED_PIN 14      // Blue LED (Warning)
#define SPRINKLER_PIN 12     // Fire suppression system
#define EXHAUST_FAN_PIN 13   // Exhaust fan

// DHT Sensor
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);

// OLED Display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Alert Levels
enum AlertLevel {
  SAFE,
  WARNING,
  DANGER,
  CRITICAL
};

// System State
struct SystemState {
  float temperature;
  float humidity;
  int smokeLevel;        // 0-100%
  int flameLevel;        // 0-100%
  AlertLevel alertLevel;
  bool sprinklerActive;
  bool exhaustFanActive;
  bool alarmActive;
  unsigned long lastAlert;
  int alertCount;
  String location;
};

SystemState fireSystem;

// Thresholds
const float TEMP_WARNING = 35.0;    // °C
const float TEMP_DANGER = 45.0;     // °C
const float TEMP_CRITICAL = 55.0;   // °C
const int SMOKE_WARNING = 30;       // %
const int SMOKE_DANGER = 50;        // %
const int SMOKE_CRITICAL = 70;      // %
const int FLAME_THRESHOLD = 40;     // %

// Timing
unsigned long lastSensorRead = 0;
unsigned long lastDisplayUpdate = 0;
unsigned long alarmStartTime = 0;
const long sensorInterval = 1000;
const long displayInterval = 500;

// Alert History
struct AlertLog {
  String timestamp;
  String level;
  float temp;
  int smoke;
  int flame;
};

AlertLog alertHistory[10];
int historyIndex = 0;

void setup() {
  Serial.begin(115200);
 
  // Initialize pins
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(BLUE_LED_PIN, OUTPUT);
  pinMode(SPRINKLER_PIN, OUTPUT);
  pinMode(EXHAUST_FAN_PIN, OUTPUT);
  pinMode(MQ2_PIN, INPUT);
  pinMode(FLAME_PIN, INPUT);
 
  // Initialize DHT
  dht.begin();
 
  // Initialize OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("OLED failed"));
  } else {
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 0);
    display.println("FIRE DETECTION");
    display.println("SYSTEM");
    display.println("");
    display.println("Initializing...");
    display.display();
    delay(2000);
  }
 
  // Initialize system state
  fireSystem.temperature = 0;
  fireSystem.humidity = 0;
  fireSystem.smokeLevel = 0;
  fireSystem.flameLevel = 0;
  fireSystem.alertLevel = SAFE;
  fireSystem.sprinklerActive = false;
  fireSystem.exhaustFanActive = false;
  fireSystem.alarmActive = false;
  fireSystem.lastAlert = 0;
  fireSystem.alertCount = 0;
  fireSystem.location = "Building A - Floor 3";
 
  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
 
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Connecting WiFi...");
  display.display();
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("\n✓ WiFi connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  // Setup web server routes
  server.on("/", handleRoot);
  server.on("/status", handleStatus);
  server.on("/history", handleHistory);
  server.on("/reset", handleReset);
  server.on("/test", handleTest);
  server.on("/silence", handleSilence);
 
  server.begin();
  Serial.println("✓ Web server started!");
 
  Serial.println("\n╔════════════════════════════════════╗");
  Serial.println("║  FIRE DETECTION SYSTEM ONLINE     ║");
  Serial.println("╚════════════════════════════════════╝");
  Serial.print("Access Dashboard: http://");
  Serial.println(WiFi.localIP());
  Serial.println();
 
  // System ready indicator
  setStatusLED(SAFE);
  playStartupTone();
}

void loop() {
  server.handleClient();
 
  unsigned long currentMillis = millis();
 
  // Read sensors
  if (currentMillis - lastSensorRead >= sensorInterval) {
    lastSensorRead = currentMillis;
    readSensors();
    evaluateFireRisk();
    controlSafetySystems();
  }
 
  // Update display
  if (currentMillis - lastDisplayUpdate >= displayInterval) {
    lastDisplayUpdate = currentMillis;
    updateDisplay();
  }
 
  // Handle alarm patterns
  if (fireSystem.alarmActive) {
    handleAlarm();
  }
}

void readSensors() {
  // Read temperature and humidity
  fireSystem.temperature = dht.readTemperature();
  fireSystem.humidity = dht.readHumidity();
 
  // Check for sensor errors
  if (isnan(fireSystem.temperature)) fireSystem.temperature = 0;
  if (isnan(fireSystem.humidity)) fireSystem.humidity = 0;
 
  // Read smoke sensor (MQ-2 simulation)
  int smokeRaw = analogRead(MQ2_PIN);
  fireSystem.smokeLevel = map(smokeRaw, 0, 4095, 0, 100);
 
  // Read flame sensor
  int flameRaw = analogRead(FLAME_PIN);
  fireSystem.flameLevel = map(flameRaw, 0, 4095, 100, 0); // Inverted
 
  // Print sensor readings
  if (fireSystem.alertLevel != SAFE) {
    Serial.println("┌─────────── SENSOR READINGS ───────────┐");
    Serial.print("│ Temperature: ");
    Serial.print(fireSystem.temperature, 1);
    Serial.println(" °C");
    Serial.print("│ Humidity: ");
    Serial.print(fireSystem.humidity, 1);
    Serial.println(" %");
    Serial.print("│ Smoke Level: ");
    Serial.print(fireSystem.smokeLevel);
    Serial.println(" %");
    Serial.print("│ Flame Detected: ");
    Serial.print(fireSystem.flameLevel);
    Serial.println(" %");
    Serial.println("└────────────────────────────────────────┘");
  }
}

void evaluateFireRisk() {
  AlertLevel previousLevel = fireSystem.alertLevel;
  AlertLevel newLevel = SAFE;
 
  // Critical conditions (immediate danger)
  if (fireSystem.temperature >= TEMP_CRITICAL ||
      fireSystem.smokeLevel >= SMOKE_CRITICAL ||
      fireSystem.flameLevel >= FLAME_THRESHOLD) {
    newLevel = CRITICAL;
  }
  // Danger conditions
  else if (fireSystem.temperature >= TEMP_DANGER ||
           fireSystem.smokeLevel >= SMOKE_DANGER) {
    newLevel = DANGER;
  }
  // Warning conditions
  else if (fireSystem.temperature >= TEMP_WARNING ||
           fireSystem.smokeLevel >= SMOKE_WARNING) {
    newLevel = WARNING;
  }
  // Safe
  else {
    newLevel = SAFE;
  }
 
  fireSystem.alertLevel = newLevel;
 
  // Alert level changed
  if (newLevel != previousLevel) {
    handleAlertChange(previousLevel, newLevel);
  }
}

void handleAlertChange(AlertLevel oldLevel, AlertLevel newLevel) {
  Serial.println("\n╔══════════════════════════════════════╗");
  Serial.print("║  ALERT LEVEL CHANGE: ");
  Serial.print(getAlertLevelName(oldLevel));
  Serial.print(" → ");
  Serial.println(getAlertLevelName(newLevel));
  Serial.println("╚══════════════════════════════════════╝");
 
  // Log alert
  logAlert();
 
  // Update visual indicators
  setStatusLED(newLevel);
 
  // Trigger alarm if danger detected
  if (newLevel >= DANGER && oldLevel < DANGER) {
    activateAlarm();
    sendAlert();
  }
 
  // Deactivate alarm if safe
  if (newLevel == SAFE && oldLevel != SAFE) {
    deactivateAlarm();
  }
}

void controlSafetySystems() {
  // Activate sprinkler for critical fire
  if (fireSystem.alertLevel == CRITICAL && !fireSystem.sprinklerActive) {
    activateSprinkler();
  } else if (fireSystem.alertLevel < CRITICAL && fireSystem.sprinklerActive) {
    deactivateSprinkler();
  }
 
  // Activate exhaust fan for smoke
  if (fireSystem.smokeLevel >= SMOKE_WARNING && !fireSystem.exhaustFanActive) {
    activateExhaustFan();
  } else if (fireSystem.smokeLevel < SMOKE_WARNING && fireSystem.exhaustFanActive) {
    deactivateExhaustFan();
  }
}

void activateSprinkler() {
  fireSystem.sprinklerActive = true;
  digitalWrite(SPRINKLER_PIN, HIGH);
  Serial.println("๐Ÿšฟ SPRINKLER SYSTEM ACTIVATED!");
}

void deactivateSprinkler() {
  fireSystem.sprinklerActive = false;
  digitalWrite(SPRINKLER_PIN, LOW);
  Serial.println("๐Ÿšฟ Sprinkler deactivated");
}

void activateExhaustFan() {
  fireSystem.exhaustFanActive = true;
  digitalWrite(EXHAUST_FAN_PIN, HIGH);
  Serial.println("๐Ÿ’จ EXHAUST FAN ACTIVATED!");
}

void deactivateExhaustFan() {
  fireSystem.exhaustFanActive = false;
  digitalWrite(EXHAUST_FAN_PIN, LOW);
  Serial.println("๐Ÿ’จ Exhaust fan deactivated");
}

void activateAlarm() {
  fireSystem.alarmActive = true;
  alarmStartTime = millis();
  Serial.println("๐Ÿšจ ALARM ACTIVATED! ๐Ÿšจ");
}

void deactivateAlarm() {
  fireSystem.alarmActive = false;
  digitalWrite(BUZZER_PIN, LOW);
  Serial.println("✓ Alarm deactivated - System safe");
}

void handleAlarm() {
  unsigned long elapsed = millis() - alarmStartTime;
  int pattern = (elapsed / 200) % 4;
 
  if (fireSystem.alertLevel == CRITICAL) {
    // Fast continuous beeping
    digitalWrite(BUZZER_PIN, pattern < 2 ? HIGH : LOW);
  } else if (fireSystem.alertLevel == DANGER) {
    // Medium beeping
    digitalWrite(BUZZER_PIN, pattern < 1 ? HIGH : LOW);
  }
}

void setStatusLED(AlertLevel level) {
  // Turn off all LEDs
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(GREEN_LED_PIN, LOW);
  digitalWrite(BLUE_LED_PIN, LOW);
 
  switch(level) {
    case SAFE:
      digitalWrite(GREEN_LED_PIN, HIGH);
      break;
    case WARNING:
      digitalWrite(BLUE_LED_PIN, HIGH);
      break;
    case DANGER:
      digitalWrite(RED_LED_PIN, HIGH);
      break;
    case CRITICAL:
      // Blink red rapidly
      digitalWrite(RED_LED_PIN, (millis() / 200) % 2);
      break;
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
 
  // Title
  display.println("FIRE DETECTION");
  display.drawLine(0, 9, 128, 9, SSD1306_WHITE);
 
  // Alert Status
  display.setCursor(0, 12);
  display.print("Status: ");
  display.println(getAlertLevelName(fireSystem.alertLevel));
 
  // Temperature
  display.setCursor(0, 22);
  display.print("Temp: ");
  display.print(fireSystem.temperature, 1);
  display.println(" C");
 
  // Smoke
  display.setCursor(0, 32);
  display.print("Smoke: ");
  display.print(fireSystem.smokeLevel);
  display.println(" %");
 
  // Flame
  display.setCursor(0, 42);
  display.print("Flame: ");
  display.print(fireSystem.flameLevel);
  display.println(" %");
 
  // Systems status
  display.setCursor(0, 52);
  if (fireSystem.sprinklerActive) display.print("SPRNKLR ");
  if (fireSystem.exhaustFanActive) display.print("FAN ");
  if (fireSystem.alarmActive) display.print("ALARM");
 
  display.display();
}

void sendAlert() {
  fireSystem.alertCount++;
  fireSystem.lastAlert = millis();
 
  Serial.println("\n╔══════════════════════════════════════╗");
  Serial.println("║     ๐Ÿšจ EMERGENCY ALERT SENT ๐Ÿšจ      ║");
  Serial.println("╠══════════════════════════════════════╣");
  Serial.print("║ Location: ");
  Serial.println(fireSystem.location);
  Serial.print("║ Level: ");
  Serial.println(getAlertLevelName(fireSystem.alertLevel));
  Serial.print("║ Temperature: ");
  Serial.print(fireSystem.temperature, 1);
  Serial.println(" °C");
  Serial.print("║ Smoke: ");
  Serial.print(fireSystem.smokeLevel);
  Serial.println(" %");
  Serial.println("║                                      ║");
  Serial.println("║ ✉️  Email sent to: admin@fire.dept  ║");
  Serial.println("║ ๐Ÿ“ฑ SMS sent to: Fire Department     ║");
  Serial.println("║ ๐Ÿ”” Push notification sent          ║");
  Serial.println("╚══════════════════════════════════════╝\n");
}

void logAlert() {
  alertHistory[historyIndex].timestamp = String(millis() / 1000) + "s";
  alertHistory[historyIndex].level = getAlertLevelName(fireSystem.alertLevel);
  alertHistory[historyIndex].temp = fireSystem.temperature;
  alertHistory[historyIndex].smoke = fireSystem.smokeLevel;
  alertHistory[historyIndex].flame = fireSystem.flameLevel;
 
  historyIndex = (historyIndex + 1) % 10;
}

String getAlertLevelName(AlertLevel level) {
  switch(level) {
    case SAFE: return "SAFE";
    case WARNING: return "WARNING";
    case DANGER: return "DANGER";
    case CRITICAL: return "CRITICAL";
    default: return "UNKNOWN";
  }
}

String getAlertColor(AlertLevel level) {
  switch(level) {
    case SAFE: return "#4CAF50";
    case WARNING: return "#2196F3";
    case DANGER: return "#FF9800";
    case CRITICAL: return "#F44336";
    default: return "#999";
  }
}

void playStartupTone() {
  tone(BUZZER_PIN, 1000, 100);
  delay(150);
  tone(BUZZER_PIN, 1500, 100);
  delay(150);
  tone(BUZZER_PIN, 2000, 100);
}

// Web Server Handlers
void handleRoot() {
  String html = "<!DOCTYPE html><html><head>";
  html += "<meta name='viewport' content='width=device-width,initial-scale=1'>";
  html += "<meta http-equiv='refresh' content='2'>";
  html += "<title>Fire Detection System</title>";
  html += "<style>";
  html += "body{margin:0;font-family:Arial;background:#1a1a1a;color:#fff;padding:20px}";
  html += ".container{max-width:1200px;margin:0 auto}";
  html += "h1{text-align:center;font-size:2.5em;margin-bottom:5px}";
  html += ".subtitle{text-align:center;opacity:0.7;margin-bottom:30px}";
  html += ".alert-banner{padding:20px;border-radius:10px;margin-bottom:20px;text-align:center;font-size:1.5em;font-weight:bold;animation:pulse 2s infinite}";
  html += "@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.7}}";
  html += ".grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:20px;margin-bottom:20px}";
  html += ".card{background:rgba(255,255,255,0.1);padding:20px;border-radius:10px;border:2px solid rgba(255,255,255,0.2)}";
  html += ".sensor-value{font-size:2.5em;font-weight:bold;margin:10px 0}";
  html += ".sensor-label{opacity:0.7;font-size:0.9em}";
  html += ".progress{background:rgba(255,255,255,0.2);height:20px;border-radius:10px;overflow:hidden;margin:10px 0}";
  html += ".progress-bar{height:100%;transition:width 0.3s}";
  html += ".status-indicator{display:inline-block;width:20px;height:20px;border-radius:50%;margin-right:10px}";
  html += ".btn{padding:15px 30px;border:none;border-radius:8px;cursor:pointer;font-size:1em;margin:5px;color:#fff;text-decoration:none;display:inline-block}";
  html += ".btn-danger{background:#f44336}";
  html += ".btn-primary{background:#2196F3}";
  html += ".systems{background:rgba(255,255,255,0.05);padding:20px;border-radius:10px;margin-top:20px}";
  html += ".system-item{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid rgba(255,255,255,0.1)}";
  html += "</style></head><body>";
  html += "<div class='container'>";
 
  html += "<h1>๐Ÿšจ Fire Detection System</h1>";
  html += "<div class='subtitle'>" + fireSystem.location + "</div>";
 
  // Alert Banner
  String alertColor = getAlertColor(fireSystem.alertLevel);
  html += "<div class='alert-banner' style='background:" + alertColor + "'>";
  html += "⚠️ " + getAlertLevelName(fireSystem.alertLevel);
  if (fireSystem.alertLevel >= DANGER) {
    html += " - EVACUATE IMMEDIATELY!";
  }
  html += "</div>";
 
  // Sensor Readings
  html += "<div class='grid'>";
 
  // Temperature
  html += "<div class='card'>";
  html += "<div class='sensor-label'>๐ŸŒก️ Temperature</div>";
  html += "<div class='sensor-value'>" + String(fireSystem.temperature, 1) + "°C</div>";
  int tempPercent = map(constrain(fireSystem.temperature, 0, 60), 0, 60, 0, 100);
  String tempColor = fireSystem.temperature >= TEMP_CRITICAL ? "#F44336" :
                     fireSystem.temperature >= TEMP_DANGER ? "#FF9800" : "#4CAF50";
  html += "<div class='progress'><div class='progress-bar' style='width:" + String(tempPercent) + "%;background:" + tempColor + "'></div></div>";
  html += "</div>";
 
  // Smoke
  html += "<div class='card'>";
  html += "<div class='sensor-label'>๐Ÿ’จ Smoke Level</div>";
  html += "<div class='sensor-value'>" + String(fireSystem.smokeLevel) + "%</div>";
  String smokeColor = fireSystem.smokeLevel >= SMOKE_CRITICAL ? "#F44336" :
                      fireSystem.smokeLevel >= SMOKE_DANGER ? "#FF9800" : "#4CAF50";
  html += "<div class='progress'><div class='progress-bar' style='width:" + String(fireSystem.smokeLevel) + "%;background:" + smokeColor + "'></div></div>";
  html += "</div>";
 
  // Flame
  html += "<div class='card'>";
  html += "<div class='sensor-label'>๐Ÿ”ฅ Flame Detection</div>";
  html += "<div class='sensor-value'>" + String(fireSystem.flameLevel) + "%</div>";
  String flameColor = fireSystem.flameLevel >= FLAME_THRESHOLD ? "#F44336" : "#4CAF50";
  html += "<div class='progress'><div class='progress-bar' style='width:" + String(fireSystem.flameLevel) + "%;background:" + flameColor + "'></div></div>";
  html += "</div>";
 
  // Humidity
  html += "<div class='card'>";
  html += "<div class='sensor-label'>๐Ÿ’ง Humidity</div>";
  html += "<div class='sensor-value'>" + String(fireSystem.humidity, 1) + "%</div>";
  html += "</div>";
 
  html += "</div>"; // End grid
 
  // Safety Systems Status
  html += "<div class='systems'>";
  html += "<h3>Safety Systems</h3>";
 
  html += "<div class='system-item'>";
  html += "<span><span class='status-indicator' style='background:" + String(fireSystem.sprinklerActive ? "#4CAF50" : "#666") + "'></span>๐Ÿšฟ Sprinkler System</span>";
  html += "<span>" + String(fireSystem.sprinklerActive ? "ACTIVE" : "Standby") + "</span>";
  html += "</div>";
 
  html += "<div class='system-item'>";
  html += "<span><span class='status-indicator' style='background:" + String(fireSystem.exhaustFanActive ? "#4CAF50" : "#666") + "'></span>๐Ÿ’จ Exhaust Fan</span>";
  html += "<span>" + String(fireSystem.exhaustFanActive ? "ACTIVE" : "Standby") + "</span>";
  html += "</div>";
 
  html += "<div class='system-item'>";
  html += "<span><span class='status-indicator' style='background:" + String(fireSystem.alarmActive ? "#F44336" : "#666") + "'></span>๐Ÿ”” Alarm System</span>";
  html += "<span>" + String(fireSystem.alarmActive ? "SOUNDING" : "Silent") + "</span>";
  html += "</div>";
 
  html += "</div>";
 
  // Controls
  html += "<div style='text-align:center;margin-top:30px'>";
  html += "<a href='/test' class='btn btn-danger'>Test Alarm</a>";
  html += "<a href='/silence' class='btn btn-primary'>Silence Alarm</a>";
  html += "<a href='/reset' class='btn btn-primary'>Reset System</a>";
  html += "</div>";
 
  html += "<div style='text-align:center;margin-top:20px;opacity:0.5;font-size:0.9em'>";
  html += "Alerts: " + String(fireSystem.alertCount) + " | ";
  html += "Uptime: " + String(millis()/1000) + "s | ";
  html += "IP: " + WiFi.localIP().toString();
  html += "</div>";
 
  html += "</div></body></html>";
 
  server.send(200, "text/html", html);
}

void handleStatus() {
  String json = "{";
  json += "\"temperature\":" + String(fireSystem.temperature, 2) + ",";
  json += "\"humidity\":" + String(fireSystem.humidity, 2) + ",";
  json += "\"smoke\":" + String(fireSystem.smokeLevel) + ",";
  json += "\"flame\":" + String(fireSystem.flameLevel) + ",";
  json += "\"alertLevel\":\"" + getAlertLevelName(fireSystem.alertLevel) + "\",";
  json += "\"sprinkler\":" + String(fireSystem.sprinklerActive ? "true" : "false") + ",";
  json += "\"exhaustFan\":" + String(fireSystem.exhaustFanActive ? "true" : "false") + ",";
  json += "\"alarm\":" + String(fireSystem.alarmActive ? "true" : "false") + ",";
  json += "\"alertCount\":" + String(fireSystem.alertCount);
  json += "}";
 
  server.send(200, "application/json", json);
}

void handleHistory() {
  String json = "[";
  for (int i = 0; i < 10; i++) {
    if (alertHistory[i].timestamp != "") {
      if (i > 0) json += ",";
      json += "{";
      json += "\"time\":\"" + alertHistory[i].timestamp + "\",";
      json += "\"level\":\"" + alertHistory[i].level + "\",";
      json += "\"temp\":" + String(alertHistory[i].temp, 1) + ",";
      json += "\"smoke\":" + String(alertHistory[i].smoke) + ",";
      json += "\"flame\":" + String(alertHistory[i].flame);
      json += "}";
    }
  }
  json += "]";
 
  server.send(200, "application/json", json);
}

void handleReset() {
  fireSystem.alertCount = 0;
  fireSystem.alarmActive = false;
  historyIndex = 0;
  for (int i = 0; i < 10; i++) {
    alertHistory[i].timestamp = "";
  }
 
  Serial.println("✓ System reset");
  server.sendHeader("Location", "/");
  server.send(303);
}

void handleTest() {
  Serial.println("๐Ÿงช Running alarm test...");
  for (int i = 0; i < 3; i++) {
    tone(BUZZER_PIN, 2000, 200);
    delay(300);
  }
 
  server.sendHeader("Location", "/");
  server.send(303);
}

void handleSilence() {
  fireSystem.alarmActive = false;
  digitalWrite(BUZZER_PIN, LOW);
  Serial.println("๐Ÿ”‡ Alarm silenced manually");
 
  server.sendHeader("Location", "/");
  server.send(303);
}


Applications
  • Home safety
  • Industrial facilities
  • Warehouses
  • Commercial buildings

Difficulty Level

Intermediate to Advanced

Amazing Features:

Triple Sensor Detection:

  •  DHT22 - Temperature monitoring (triggers at 35°C, 45°C, 55°C)
  •  MQ-2 Smoke Sensor - Gas/smoke detection (0-100%)
  •  Flame Sensor - Infrared flame detection

4-Level Alert System:

SAFE → Green LED, No alarm

WARNING  → Blue LED, No alarm  
DANGER   → Red LED + Medium beeps
CRITICAL → Red flashing + Fast beeps

Automatic Safety Response:

  •  Auto-Sprinkler - Activates at CRITICAL level
  •  Exhaust Fan - Turns on when smoke > 30%
  •  Smart Alarm - Different beep patterns per level
  •  Emergency Alerts - Simulated SMS/Email notifications

Beautiful Web Dashboard:

  •  Dark theme with color-coded alerts
  •  Progress bars for all sensors
  •  Auto-refresh every 2 seconds
  •  Mobile responsive design
  •  Remote controls (Test, Silence, Reset)


 How to Test:

Simulate a Fire:

  1. Start with Normal Conditions:
    • Green LED = SAFE
    • No alarm
    • All systems standby
  2. Increase Temperature:
    • Click DHT22, drag to 40°C
    • Blue LED lights up (WARNING)
    • Still no alarm
  3. Add Smoke:
    • Rotate "Smoke Sensor" to 60%
    • Red LED lights up (DANGER)
    • Alarm starts beeping!
    •  Exhaust fan turns ON
  4. Detect Flames:
    • Rotate "Flame Sensor" to 50%
    • Red LED flashes rapidly (CRITICAL)
    • Alarm beeps continuously
    • Sprinkler activates!
    • Emergency alerts sent!

Conclusion: Start Your ESP32 IoT Journey Today

The ESP32 microcontroller opens up endless possibilities for IoT innovation. These 15 projects cover a wide spectrum of applications, from simple home automation to complex industrial monitoring systems.

Comments