Fire accidents can cause devastating damage to property and endanger lives when not detected early. This project presents an IoT-based fire detection system that continuously monitors environmental conditions using a smoke sensor (MQ-2) and a flame sensor and flames, triggers water pump activation when danger is detected, and sends real-time alerts to the user’s smartphone via Telegram.
Features
- Real-time fire detection & alerts
- Remote monitoring via Telegram
- Automatic & manual water pump control
- Low power consumption
Materials Required
- ESP32 board
- MQ-2 Smoke/Gas Sensor
- IR Flame Sensor
- Relay module & water pump
- I2C LCD Display
- LEDs & resistors
- Jumper wires & breadboard
Understanding the Sensors
MQ-2 Smoke Sensor
The MQ-2 is a gas sensor that can detect LPG, smoke, alcohol, propane, hydrogen, methane, and carbon monoxide. For our fire detection system, we’re primarily interested in its smoke detection capability.
How it works: The sensor contains a heating element and an electrochemical sensor. When smoke particles come into contact with the sensor, they change the resistance of the sensing element. This change in resistance is converted to a voltage that is read by the ESP32’s analog input.
Connection to ESP32:
- VCC → 5V
- GND → GND
- AO (Analog Output) → GPIO 36 (ADC)
Flame Sensor
The flame sensor detects infrared light emitted by fire, making it excellent for direct fire detection.How it works: The sensor uses an IR photodiode to detect infrared light in the 760-1100 nm wavelength range, which is emitted by fire. When flames are detected, the sensor’s output pin goes LOW.
Connection to ESP32:
- VCC → 3.3V
- GND → GND
- DO (Digital Output) → GPIO 39
Hardware Setup
Wiring Diagram
Connect the components to the ESP32 as follows:
- MQ-2 Smoke Sensor:
- VCC → 5V
- GND → GND
- AO → GPIO 36
- Flame Sensor:
- VCC → 3.3V
- GND → GND
- DO → GPIO 39
- Relay Module:
- VCC → 5V
- GND → GND
- IN → GPIO 33
- LCD Display (I2C):
- VCC → 5V
- GND → GND
- SDA → GPIO 21
- SCL → GPIO 22
- LEDs:
- Red LED (+ with 220Ω resistor) → GPIO 13
- Green LED (+ with 220Ω resistor) → GPIO 12
- LED – pins → GND
- Water Pump:
- Connect to the Normally Open (NO) and Common (COM) terminals of the relay
- Power the pump with an appropriate 5-12V DC supply
Required Libraries
Before uploading the code, install these libraries through the Arduino IDE Library Manager:
- Library Installation
- Open Arduino IDE
- Navigate to Sketch > Include Library > Manage Libraries
- Search and install:
- LiquidCrystal I2C by Frank de Brabander
- Universal Telegram Bot by Brian Lough
- ArduinoJson by Benoit Blanchon
Setting Up Telegram Bot – IoT Based Fire & Smoke Detection ESP32
Checkout our previous post how to setup and Control LED with Telegram Bot Using ESP8266/ESP32
- Search for “BotFather” in Telegram
- Send the command
/newbot
and follow the instructions - Save the API token provided by BotFather
- Find your Telegram Chat ID using the “IDBot” (search for “@myidbot” and send the command
/getid
) - Replace the placeholders in the code with your Telegram bot token and chat ID
Source Code/Program – IoT Based Fire & Smoke Detection
But before that please make changes to the WiFiSSID, Password & API Token.
1 2 3 4 5 6 |
// WiFi credentials const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; // Telegram Bot details #define BOT_TOKEN "YOUR_BOT_TOKEN" #define CHAT_ID "YOUR_CHAT_ID" |
Here’s the full code for the project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #include <ArduinoJson.h> // Define pins const int smokeSensorPin = 36; // GPIO 36 (VP) - MQ-2 smoke sensor const int flameSensorPin = 39; // GPIO 39 (VN) - Flame sensor const int relayPin = 33; // GPIO 33 for water pump relay control const int redLEDPin = 13; // GPIO 13 for red LED (danger) const int greenLEDPin = 12; // GPIO 12 for green LED (safe) // WiFi credentials const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; // Telegram Bot details #define BOT_TOKEN "YOUR_BOT_TOKEN" #define CHAT_ID "YOUR_CHAT_ID" // Initialize Telegram bot WiFiClientSecure client; UniversalTelegramBot bot(BOT_TOKEN, client); // Initialize LCD (Address 0x27 for most I2C LCD modules) LiquidCrystal_I2C lcd(0x27, 16, 2); // Variables to store sensor readings int smokeValue = 0; int smokePPM = 0; // Calculated PPM value bool flameDetected = false; bool pumpOn = false; bool alertSent = false; // Track if alert was sent to avoid repeated messages // Time tracking unsigned long lastBotCheckTime = 0; unsigned long lastLcdUpdateTime = 0; unsigned long lastAlertTime = 0; // Timing constants const int botCheckInterval = 1000; // Check Telegram messages every 1 second const int lcdUpdateInterval = 1000; // Update LCD every 1 second const int alertThrottleTime = 30000; // Minimum time between repeated alerts (30 seconds) // Thresholds const int smokeDangerThreshold = 180; // PPM threshold for smoke detection void setup() { // Initialize serial communication Serial.begin(115200); Serial.println("Fire Detection System Starting..."); // Initialize the pins pinMode(smokeSensorPin, INPUT); pinMode(flameSensorPin, INPUT); pinMode(relayPin, OUTPUT); pinMode(redLEDPin, OUTPUT); pinMode(greenLEDPin, OUTPUT); // Turn off the pump and set LEDs initially digitalWrite(relayPin, HIGH); digitalWrite(redLEDPin, LOW); digitalWrite(greenLEDPin, LOW); // Setup LCD lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("System Initializing"); // Connect to WiFi WiFi.begin(ssid, password); Serial.print("Connecting to WiFi..."); lcd.setCursor(0, 1); lcd.print("Connecting WiFi"); int wifiAttempts = 0; while (WiFi.status() != WL_CONNECTED && wifiAttempts < 20) { delay(500); Serial.print("."); wifiAttempts++; } if (WiFi.status() == WL_CONNECTED) { Serial.println("\nWiFi Connected!"); Serial.println("IP: " + WiFi.localIP().toString()); lcd.clear(); lcd.setCursor(0, 0); lcd.print("WiFi Connected"); lcd.setCursor(0, 1); lcd.print(WiFi.localIP().toString()); } else { Serial.println("\nWiFi Connection Failed!"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("WiFi Failed!"); } delay(2000); // Display WiFi status for 2 seconds // Enable secure connection for Telegram (skip certificate validation) client.setInsecure(); // System ready lcd.clear(); lcd.setCursor(0, 0); lcd.print("System Ready"); digitalWrite(greenLEDPin, HIGH); // Green LED on when system is ready // Send startup notification to Telegram sendTelegramMessage("🔔 Fire Detection System Online!"); } void loop() { // Read sensor values readSensors(); // Check if in danger state bool dangerState = (smokePPM > smokeDangerThreshold || flameDetected); // Handle danger state if (dangerState) { handleDangerState(); } else { handleSafeState(); } // Check for Telegram messages checkTelegramMessages(); // Update LCD if needed if (millis() - lastLcdUpdateTime >= lcdUpdateInterval) { updateLcd(); lastLcdUpdateTime = millis(); } } void readSensors() { // Read raw smoke sensor value smokeValue = analogRead(smokeSensorPin); // Convert analog reading to PPM (simplified calculation) // You may need to adjust this calculation based on your specific MQ-2 sensor calibration smokePPM = map(smokeValue, 0, 4095, 0, 1000); // Read flame sensor (LOW means flame detected) flameDetected = digitalRead(flameSensorPin) == LOW; // Debug output to serial Serial.print("Smoke Value (raw): "); Serial.print(smokeValue); Serial.print(", Smoke (PPM): "); Serial.print(smokePPM); Serial.print(", Flame Detected: "); Serial.println(flameDetected ? "YES" : "NO"); } void handleDangerState() { // Turn on danger indicators digitalWrite(redLEDPin, HIGH); digitalWrite(greenLEDPin, LOW); // Activate water pump if not already on if (!pumpOn) { digitalWrite(relayPin, LOW); pumpOn = true; Serial.println("ALERT: Activating water pump!"); } // Send alert notifications if not recently sent if (!alertSent || (millis() - lastAlertTime >= alertThrottleTime)) { String alertMessage = "⚠️ ALERT: "; if (smokePPM > smokeDangerThreshold) { alertMessage += "Smoke detected (" + String(smokePPM) + " PPM)! "; } if (flameDetected) { alertMessage += "🔥 Fire detected! "; } alertMessage += "Water pump activated!"; sendTelegramMessage(alertMessage); lastAlertTime = millis(); alertSent = true; } } void handleSafeState() { // Turn on safe indicators digitalWrite(redLEDPin, LOW); digitalWrite(greenLEDPin, HIGH); // Deactivate water pump if it's on if (pumpOn) { digitalWrite(relayPin, HIGH); pumpOn = false; Serial.println("System normal: Deactivating water pump"); // Send all-clear message if we were previously in alert state if (alertSent) { sendTelegramMessage("✅ All clear! Smoke and fire no longer detected."); alertSent = false; } } } void updateLcd() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Smoke: "); lcd.print(smokePPM); lcd.print(" PPM"); lcd.setCursor(0, 1); lcd.print("Fire: "); lcd.print(flameDetected ? "DETECTED!" : "Safe"); // Add a visual indicator of pump status lcd.setCursor(15, 1); lcd.print(pumpOn ? "P" : "-"); } void checkTelegramMessages() { if (millis() - lastBotCheckTime > botCheckInterval) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { Serial.println("New Telegram message received"); String chat_id = String(bot.messages[0].chat_id); String messageText = bot.messages[0].text; if (chat_id == CHAT_ID) { processTelegramCommand(chat_id, messageText); } numNewMessages = bot.getUpdates(bot.last_message_received + 1); } lastBotCheckTime = millis(); } } void processTelegramCommand(String chat_id, String message) { if (message == "/start" || message == "/help") { String helpMessage = "Fire Detection System Commands:\n"; helpMessage += "/status - Get current sensor readings\n"; helpMessage += "/pump_on - Turn on water pump\n"; helpMessage += "/pump_off - Turn off water pump\n"; helpMessage += "/reset - Reset system alerts\n"; bot.sendMessage(chat_id, helpMessage, ""); } else if (message == "/status") { String statusMessage = "📊 Current Status:\n"; statusMessage += "Smoke Level: " + String(smokePPM) + " PPM\n"; statusMessage += "Fire Detected: " + String(flameDetected ? "YES ⚠️" : "No ✅") + "\n"; statusMessage += "Water Pump: " + String(pumpOn ? "ON 💧" : "OFF") + "\n"; statusMessage += "System State: " + String((smokePPM > smokeDangerThreshold || flameDetected) ? "⚠️ DANGER" : "✅ SAFE"); bot.sendMessage(chat_id, statusMessage, ""); } else if (message == "/pump_on") { digitalWrite(relayPin, LOW); pumpOn = true; bot.sendMessage(chat_id, "💧 Water pump turned ON manually", ""); } else if (message == "/pump_off") { digitalWrite(relayPin, HIGH); pumpOn = false; bot.sendMessage(chat_id, "Water pump turned OFF manually", ""); } else if (message == "/reset") { alertSent = false; bot.sendMessage(chat_id, "System alerts have been reset", ""); } else { bot.sendMessage(chat_id, "Unknown command. Send /help for available commands.", ""); } } void sendTelegramMessage(String message) { if (WiFi.status() != WL_CONNECTED) { Serial.println("Cannot send Telegram message: WiFi not connected"); return; } bot.sendMessage(CHAT_ID, message, ""); Serial.println("Telegram message sent: " + message); } |
Testing: IoT Based Fire & Smoke Detection Project with ESP32
The ESP32 Board will try connecting to the wifi Network using the given SSID & Password.
When any sensor detected, the system automatically activates a water pump, triggers visual alerts with LEDs and an LCD display.
Telegram Bot Integration
The system can receive commands via Telegram:
/start
or/help
– Display available commands/status
– Check current sensor readings/pump_on
– Manually activate the water pump/pump_off
– Manually deactivate the water pump/reset
– Reset the alert state
When detected, the system automatically sends real-time notifications to a Telegram Bot.