Contents — 26 sections
Project Overview
Interconnected smoke and heat detectors so that when one senses fire, every alarm in the building sounds — and everyone, including a control point, knows exactly where it started.
The deadliest gap in home and building fire safety is not detection — it is hearing the alarm in time. A smoke detector in the basement can be screaming while people asleep upstairs hear nothing until the fire has spread. The single most important improvement, proven to save lives, is interconnection: when any one detector senses fire, all of them sound, everywhere, at once. This project builds a networked, interconnected fire and smoke alarm system where detectors in every room talk to each other, so a fire anywhere wakes everyone — and, because it is networked, it also announces where the fire started and can alert a control point or phones.
Each node combines the sensing that catches fire in its different forms: a smoke sensor for the smouldering and flaming smoke that is the earliest and most common sign, and a heat channel that watches both absolute temperature and its rate of rise (a fast-climbing temperature signals a fast-developing fire even before heavy smoke), with an optional flame sensor. Fusing smoke and heat, and watching rate-of-change against each node's baseline, is what lets it alarm early on a real fire while resisting the nuisance trips — cooking steam, shower humidity, dust — that make people disable detectors, which is itself a major cause of fire deaths.
Interconnection is the heart of it: nodes are networked (wired or wireless) so a detection propagates to every node in well under the critical few seconds, and a location-aware control point shows which room originated the alarm — invaluable for occupants deciding an escape route and for responders. The system supports battery backup so a power cut does not blind it, supervises every detector so a dead or removed unit is flagged (a missing detector is a silent risk), and can escalate to phones or a monitoring point. It is emphatic about its limits — a DIY system is not a certified, listed fire-alarm installation, and where codes require listed smoke alarms and professional monitoring you must use them; low-cost sensors are for supplementary awareness, not life-safety certification. But as a demonstration and a supplementary interconnected alarm, it embodies the one lesson that matters most in fire safety: when it detects fire, everyone hears it, everywhere, immediately.
What this project does
- Detects fire by smoke and by heat (absolute + rate-of-rise), optional flame
- Interconnects detectors so one detection sounds every alarm in the building
- Identifies and reports which room the alarm originated in
- Resists nuisance trips (steam, dust) by fusing smoke and heat and using rate-of-change
- Supervises every detector so a dead/removed unit is flagged
- Runs on battery backup so a power cut does not blind it
- Escalates a location-aware alert to a control point/phones
Real-World Applications
| Setting | How it is used |
|---|---|
| Home fire safety (supplementary) | Interconnected detectors so a fire anywhere in the house wakes everyone, with location and phone alerts — alongside listed smoke alarms. |
| Small building / hostel / office | Building-wide interconnected detection with a control point showing the room of origin. |
| Workshops / labs | Early smoke/heat detection in areas with specific fire risks, networked to a coordinator. |
| Education / demonstration | Teaching fire-detection sensing, interconnection and rate-of-rise principles. |
Deployment contexts where a build of this kind earns its keep.
Features & Capabilities
- Interconnected sounding — the proven life-saver (all alarm when one detects)
- Smoke + heat + rate-of-rise fusion for early, robust detection
- Location-aware alarms (which room started it)
- Nuisance-resistant logic to stop people disabling detectors
- Per-detector supervision (a missing detector is a risk)
- Battery backup and escalation to a control point/phones
- Explicit: supplementary, not a certified/listed fire-alarm system
Difficulty, Time & Required Skills
| Attribute | Value |
|---|---|
| Difficulty level | Advanced |
| Estimated completion time | 14–20 hours |
| Indicative build cost | ₹3,500 – ₹6,000 (multi-node) |
| Primary discipline | Security |
| Reference platform | ESP32 DevKit V1 (ESP-WROOM-32) |
Skills you should have (or will pick up)
- Smoke and heat sensing (absolute + rate-of-rise) and fusion
- Interconnecting detectors for all-sound-on-one-detect
- Nuisance-rejection logic and per-node baselines
- Detector supervision and battery backup
- Location-aware alerting and escalation
Bill of Materials
Every part below is commonly available from Indian and international hobby-electronics suppliers. Prices are indicative 2026 retail figures in Indian rupees and will drift — treat them as a budgeting guide, not a quotation.
| Component | Key specification | Qty | Approx. cost |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) Wi-Fi transmit bursts peak near 500 mA — size the regulator accordingly. | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18× 12-bit ADC, 2× 8-bit DAC | 1 | ₹450 |
| MQ-2 combustible gas / smoke sensor Needs 24–48 h burn-in and a stable 5 V; the heater alone draws ~150 mA. | 300–10000 ppm LPG, propane, methane, hydrogen, smoke; analogue + digital output | 1 | ₹150 |
| DHT22 / AM2302 temperature + humidity sensor Needs a 4.7 kΩ pull-up on the data line and 2 s between reads. | −40 to +80 °C ±0.5 °C, 0–100 %RH ±2 %, 0.5 Hz sample rate, single-wire digital | 1 | ₹250 |
| IR flame sensor module (YG1006) Sunlight and incandescent bulbs both trigger it — always confirm with a second sensor type. | 760–1100 nm, 60° detection cone, 0.8 m range, analogue + digital out | 1 | ₹70 |
| Active piezo buzzer 5 V Active buzzers make tone on DC; passive ones need a PWM carrier. | 85 dB at 10 cm, 2.3 kHz resonance, 12 mm diameter | 1 | ₹25 |
| SX1278 LoRa 433 MHz module (Ra-02) Never power the radio without an antenna — the PA will destroy itself. | −148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7–SF12 | 1 | ₹480 |
| 0.96″ SSD1306 OLED display Static images burn in — invert or scroll the screen periodically. | 128 × 64 monochrome, 1.3–3.3 V logic, 100 kHz–400 kHz I²C | 1 | ₹250 |
| 18650 Li-ion cell 3400 mAh + holder Never charge below 0 °C; always use a protected cell or a BMS. | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 1 | ₹450 |
| Photoelectric smoke sensor Photoelectric suits smouldering; combine sensing types for coverage | Photoelectric smoke chamber (good for smouldering fires) per node | 4 | ₹3,200 |
| Loud interconnected sounders | Piezo/horn sounder per node, loud enough to wake sleepers | 4 | ₹2,400 |
| Backup batteries | Per-node battery so a power cut does not blind detection | 4 | ₹1,600 |
| Control point / annunciator | Panel showing room-of-origin and building status | 1 | ₹1,200 |
Estimated total: ₹10,525, excluding tools, shipping and consumables.
Tools and consumables
- Soldering iron (temperature controlled, 350 °C) with 0.8 mm 60/40 or lead-free solder
- Digital multimeter — continuity, DC volts and current ranges
- Wire strippers, flush cutters and a small set of precision screwdrivers
- Heat-shrink tubing and a heat gun (or a lighter, carefully)
- A laptop with a USB port and the toolchain listed above
Hardware Specifications
| Part | Specification | Supply | Interface | Reference |
|---|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18× 12-bit ADC, 2× 8-bit DAC | 3.3 V logic / 5 V USB | UART, SPI, I²C, I²S, CAN, PWM | Datasheet |
| MQ-2 combustible gas / smoke sensor | 300–10000 ppm LPG, propane, methane, hydrogen, smoke; analogue + digital output | 5 V (heater) | Analogue + comparator digital | Datasheet |
| DHT22 / AM2302 temperature + humidity sensor | −40 to +80 °C ±0.5 °C, 0–100 %RH ±2 %, 0.5 Hz sample rate, single-wire digital | 3.3–6 V | 1-wire proprietary | Datasheet |
| IR flame sensor module (YG1006) | 760–1100 nm, 60° detection cone, 0.8 m range, analogue + digital out | 3.3–5 V | Analogue + digital | Datasheet |
| Active piezo buzzer 5 V | 85 dB at 10 cm, 2.3 kHz resonance, 12 mm diameter | 3–5 V | Digital / PWM | Datasheet |
| SX1278 LoRa 433 MHz module (Ra-02) | −148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7–SF12 | 3.3 V | SPI | Datasheet |
| 0.96″ SSD1306 OLED display | 128 × 64 monochrome, 1.3–3.3 V logic, 100 kHz–400 kHz I²C | 3.3–5 V | I²C (0x3C) | Datasheet |
| 18650 Li-ion cell 3400 mAh + holder | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 3.0–4.2 V | Holder / spot-welded tabs | Datasheet |
Consolidated electrical and interface specifications for every active part in the build.
Power Budget & Supply Sizing
Add up the typical active current of every part, then size the supply with at least 50 % headroom so transmit bursts and motor inrush never brown out the controller.
| Load | Supply rail | Typical current (mA) | Notes |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | 3.3 V logic / 5 V USB | 160 | Wi-Fi transmit bursts peak near 500 mA — size the regulator accordingly. |
| MQ-2 combustible gas / smoke sensor | 5 V (heater) | 150 | Needs 24–48 h burn-in and a stable 5 V; the heater alone draws ~150 mA. |
| DHT22 / AM2302 temperature + humidity sensor | 3.3–6 V | 1.5 | Needs a 4.7 kΩ pull-up on the data line and 2 s between reads. |
| IR flame sensor module (YG1006) | 3.3–5 V | 15 | Sunlight and incandescent bulbs both trigger it — always confirm with a second sensor type. |
| Active piezo buzzer 5 V | 3–5 V | 30 | Active buzzers make tone on DC; passive ones need a PWM carrier. |
| SX1278 LoRa 433 MHz module (Ra-02) | 3.3 V | 120 | Never power the radio without an antenna — the PA will destroy itself. |
| 0.96″ SSD1306 OLED display | 3.3–5 V | 20 | Static images burn in — invert or scroll the screen periodically. |
Summed typical draw is 496.5 mA. With a 1.5× design margin the supply should deliver at least 800 mA continuously at the stated rail voltage.
Software Requirements & Development Environment
Reference toolchain: Arduino IDE 2.3.x with the ESP32 board package 3.x (or PlatformIO on VS Code). Anything newer normally works; anything older may lack the board definitions used here.
- Install the Arduino IDE 2.3.x (or PlatformIO if you prefer a real editor and dependency locking).
- Add
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonunder File → Preferences → Additional Board Manager URLs, then install esp32 from the Boards Manager. - Set the correct port under Tools → Port. On Linux add yourself to the
dialoutgroup:sudo usermod -aG dialout $USERand log out and back in. - Open the Serial Monitor at 115200 baud — every sketch here logs its state there.
- Keep File → Preferences → Show verbose output during: compilation switched on while you are debugging build errors.
Required libraries
| Library | Why it is needed | Install |
|---|---|---|
| WiFi (ESP32 core) bundled | Station/AP connection management for the ESP32. | Bundled with the ESP32 Arduino core |
| PubSubClient 2.8 | Lightweight MQTT 3.1.1 client for constrained devices. | Library Manager → "PubSubClient" by Nick O'Leary |
| DHT sensor library 1.4.6 | Timing-critical driver for DHT11/DHT22. | Library Manager → "DHT sensor library" by Adafruit |
| LoRa (sandeepmistry) 0.8.0 | SX127x radio configuration, packet TX/RX and callbacks. | Library Manager → "LoRa" by Sandeep Mistry |
| Adafruit SSD1306 + GFX 2.5.x | Framebuffer and text/graphics primitives for the OLED. | Library Manager → "Adafruit SSD1306" |
| NTPClient / configTime bundled | Wall-clock time from an NTP server for timestamping. | Bundled (`configTime()` on ESP32) |
| Preferences (NVS) bundled | Wear-levelled key/value storage in ESP32 flash for settings. | Bundled with the ESP32 core |
Block Diagram
The block diagram shows the functional decomposition of the system — what senses, what decides, what acts, and where the data ends up.
Circuit Diagram & Wiring
Every signal line in the build is shown below, followed by a pin-by-pin connection table you can work through with a multimeter in hand.
| Peripheral | Peripheral pin | Controller pin | Signal |
|---|---|---|---|
| Smoke sensor | AOUT | GPIO 34 | Smoke concentration |
| DHT22 / temp | DATA | GPIO 4 | Heat + rate-of-rise |
| Flame sensor | DOUT | GPIO 27 | Flame (optional confirm) |
| Sounder | IN | GPIO 26 | Local + interconnected alarm |
| Interconnect | wired/LoRa | bus / SPI | All-sound propagation |
| OLED | SDA/SCL | GPIO 21/22 | Status / origin |
| Backup battery | sense | ADC | Power supervision |
Wire one row at a time and tick it off — most "it does not work" reports trace back to a single swapped pair.
Wiring explanation
- Interconnect the detectors — a wired interconnect line/bus or a fast wireless (LoRa/ESP-NOW) mesh — so any node's detection makes every node sound within a couple of seconds.
- Mount smoke sensors per fire-code guidance (ceiling, away from kitchens/bathrooms to reduce nuisance trips) and give each a temperature sensor for heat/rate-of-rise.
- Power each node with battery backup and sense the supply so power loss is detected and the node stays alive.
- Make each sounder loud enough to wake a sleeping person through a closed door.
- Give each node an ID/location so the control point can name the room of origin.
System Architecture
Read the stack from the bottom up: physical hardware, the firmware that drives it, the transport that moves data off the device, and the software a human actually looks at.
Working Principle
Decades of fire-safety research converge on one finding above all: the biggest determinant of surviving a fire is early warning that everyone hears. Detection technology matters, but the fatal failures are usually that the alarm sounded somewhere no one could hear it in time, or that a nuisance-prone detector had been disabled. This system is built around those two lessons. Its defining feature is interconnection — the principle, now required by code for new homes in many places, that when any single detector senses fire, every detector in the building sounds simultaneously. A fire starting in a distant or closed room no longer relies on one local sounder to wake sleeping occupants across the house; the whole building alarms at once. Making that propagation fast and reliable (well under the few seconds that matter, over a wired interconnect or a fast wireless mesh) is the most important engineering goal in the project.
Detecting fire early and robustly means sensing its different signatures and fusing them. Fires present differently: a smouldering couch produces smoke long before heat, while a flaming fire produces heat and flame fast. So each node watches smoke (the earliest sign of most fires, and the primary sensor) and heat — and heat is watched two ways: absolute temperature, and crucially its rate of rise. A rate-of-rise heat detector alarms on a rapid temperature climb even before the absolute temperature is high, catching a fast-developing fire early; it is a classic, powerful complement to a fixed-temperature threshold. An optional flame sensor adds direct confirmation. Fusing these — smoke OR a dangerous heat/rate-of-rise, corroborated where possible — gives both earlier and more reliable detection than any single sensor.
The counter-intuitive but vital design goal is rejecting nuisance alarms, because nuisance trips kill. Detectors that cry wolf on cooking steam, shower humidity or dust get disabled by frustrated occupants — batteries removed, units unplugged — and a disabled detector is the leading contributor to fire deaths in homes that had alarms. So the system works to alarm on real fire while staying quiet on steam and dust: fusing smoke with heat/rate-of-rise (steam raises humidity but not the fire signature; a real fire moves both smoke and heat), using each node's baseline and rate-of-change rather than a bare threshold, and siting sensors away from kitchens and bathrooms. Reducing false alarms is not mere convenience — it is what keeps the detectors enabled, which is a prerequisite for them ever saving a life.
Around these, the system adds the properties that make it dependable and useful: location awareness so the control point (and the alert to phones) names the room the fire started in, helping occupants choose a safe escape route and responders go straight to the seat of the fire; supervision so every detector's presence and health is continuously checked and a dead, removed or low-battery unit is flagged (a missing detector is a silent hole in coverage); and battery backup so a power cut — which can accompany a fire — does not blind the system. It must be said as plainly as possible, though, that this is a supplementary and educational system, not a certified, listed, professionally-monitored fire-alarm installation. Life-safety fire detection is governed by codes and standards for good reason, and where they require listed smoke alarms and monitoring, those must be used. Built with that honesty, this project is a faithful, hands-on realisation of fire safety's central principle: detect early, reject nuisances so it stays enabled, and when it does detect, make sure everyone, everywhere, hears it at once and knows where to run from.
The maths behind it
Rate-of-rise heat detection
Watch both the absolute temperature and its rate of change:
fixed : alarm if T > T_max (e.g. 58 °C)
ROR : alarm if dT/dt > R_max (e.g. > 8 °C/min)
ROR catches a fast fire before T is high; fixed catches a
slow one. Use BOTH — many real detectors do.
Smoke + heat fusion (nuisance rejection)
fire likely if:
smoke > S_thresh AND (dT/dt > R_max OR T > T_max)
OR smoke >> S_high (heavy smoke alone)
OR flame_confirmed
Steam raises humidity, not the smoke+heat signature →
rejected. Baseline/rate-of-change per node adapts to the
room and avoids threshold nuisance trips.
Interconnection propagation
On local fire detection at node i:
broadcast ALARM(origin=i) to all nodes
every node j: sound_local() (target < ~2 s)
Receiving an ALARM makes a node sound even with no local
smoke — the all-sound-on-one-detect life-safety behaviour.
Program Flowchart
The firmware is a single cooperative loop. Nothing blocks for long, so networking, sensing and the user interface all stay responsive.
Assembly Instructions
Build on a breadboard first and only commit to solder once the whole system has run for an hour without a fault.
Build interconnected detector nodes
Give each node a smoke sensor, a temperature sensor (for heat and rate-of-rise), an optional flame sensor, a loud sounder, battery backup and a network interface (wired interconnect or fast wireless), plus an ID/location.
Site smoke sensors per fire-code guidance, away from kitchens/bathrooms to reduce nuisance trips.
Set up supervision and backup
Have each node heartbeat its presence and health; power each with battery backup and sense the supply so power loss and low battery are flagged.
Set up the control point and escalation
Provide a control point/annunciator that shows the room of origin and building status, and configure escalation to phones/a monitoring point.
Step-by-Step Implementation Guide
Work through these in order. Each step ends in something you can observe, so a failure is always localised to the step you just finished.
Detect fire with fusion and rate-of-rise
Read smoke and temperature, compute the rate of rise, and confirm fire from the fused smoke+heat signature (with nuisance rejection) or heavy smoke or flame.
cppfire-detect.inofloat prevTemp = NAN; uint32_t prevMs = 0; // Rate of rise in deg C per minute, from successive temperature reads. float rateOfRise(float t, uint32_t now) { if (isnan(prevTemp)) { prevTemp = t; prevMs = now; return 0; } float dtMin = (now - prevMs) / 60000.0f; float ror = dtMin > 0 ? (t - prevTemp) / dtMin : 0; prevTemp = t; prevMs = now; return ror; } // Fuse smoke + heat with nuisance rejection. bool fireConfirmed(float smoke, float temp, float ror, bool flame) { bool heat = (temp > 58.0f) || (ror > 8.0f); // fixed OR rate-of-rise if (smoke > SMOKE_THRESH && heat) return true; // classic fire signature if (smoke > SMOKE_HEAVY) return true; // heavy smoke alone if (flame) return true; // direct confirmation return false; // steam/dust: rejected }float rateOfRise(float t, uint32_t now)Computes how fast the temperature is climbing, the signal that catches a fast-developing fire before the absolute temperature is dangerous.bool heat = (temp > 58.0f) || (ror > 8.0f)Heat is flagged either by a fixed high temperature or by a rapid rate of rise, combining the two classic heat-detection methods.if (smoke > SMOKE_THRESH && heat) return trueThe primary confirmation requires smoke together with a heat signature — a real fire moves both, while steam raises humidity without the heat signature, so nuisance trips are rejected.if (smoke > SMOKE_HEAVY) return trueOverwhelming smoke alone is enough to alarm, since heavy smoke is unambiguous even before heat builds.Interconnect and escalate
On local confirmation, broadcast an alarm with this node's origin so every node sounds, sound locally on receiving any node's alarm, and escalate a located alert to the control point/phones; heartbeat health continuously.
Complete Source Code
The listing below is complete and compiles as written — there are no elided sections. Read the annotations under each block before you upload it.
/* ═══════════════════════════════════════════════════════════════
Networked Fire & Smoke Alarm — ESP32, interconnected detectors
Smoke + heat (fixed + rate-of-rise) + optional flame, fused with
nuisance rejection. Any node's detection sounds EVERY node and
reports the room of origin. Supervised, battery-backed.
SUPPLEMENTARY / EDUCATIONAL — not a certified fire-alarm system.
══════════════════════════════════════════════════════════════════ */
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <LoRa.h>
#include <SPI.h>
#include <Preferences.h>
#include <math.h>
#define PIN_SMOKE 34
#define PIN_DHT 4
#define PIN_FLAME 27
#define PIN_SOUNDER 26
#define SMOKE_THRESH 1500
#define SMOKE_HEAVY 3000
#define HEARTBEAT_MS 60000UL
DHT dht(PIN_DHT, DHT22);
WiFiClient net; PubSubClient mqtt(net);
Preferences prefs;
const uint8_t NODE_ID = 1;
const char *ROOM = "Kitchen";
float prevTemp = NAN; uint32_t prevMs = 0, lastBeat = 0;
bool localFire = false;
float rateOfRise(float t, uint32_t now) {
if (isnan(prevTemp)) { prevTemp = t; prevMs = now; return 0; }
float dtMin = (now - prevMs) / 60000.0f;
float ror = dtMin > 0 ? (t - prevTemp) / dtMin : 0;
prevTemp = t; prevMs = now; return ror;
}
bool fireConfirmed(float smoke, float temp, float ror, bool flame) {
bool heat = (temp > 58.0f) || (ror > 8.0f);
return (smoke > SMOKE_THRESH && heat) || (smoke > SMOKE_HEAVY) || flame;
}
void soundLocal(bool on) { digitalWrite(PIN_SOUNDER, on ? HIGH : LOW); }
// Broadcast to interconnect (LoRa here; a wired bus works too).
void broadcastAlarm() {
LoRa.beginPacket();
LoRa.printf("{\"t\":\"FIRE\",\"origin\":%u,\"room\":\"%s\"}",
NODE_ID, ROOM);
LoRa.endPacket();
mqtt.publish("fire/alarm", ""); // escalate to control point/phones
}
// Sound when ANY node reports fire (all-sound-on-one-detect).
void checkInterconnect() {
if (LoRa.parsePacket()) {
String p; while (LoRa.available()) p += (char)LoRa.read();
if (p.indexOf("FIRE") >= 0) {
soundLocal(true); // sound even without local smoke
// relay origin to the control point / OLED for room-of-origin
mqtt.publish("fire/echo", p.c_str());
}
}
}
void setup() {
Serial.begin(115200);
pinMode(PIN_FLAME, INPUT);
pinMode(PIN_SOUNDER, OUTPUT);
analogSetPinAttenuation(PIN_SMOKE, ADC_11db);
dht.begin();
SPI.begin();
LoRa.setPins(5,14,2); LoRa.begin(433E6); LoRa.setSpreadingFactor(9);
WiFi.begin(WIFI_SSID, WIFI_PASS);
mqtt.setServer(MQTT_HOST, 1883);
}
void loop() {
if (!mqtt.connected() && WiFi.status()==WL_CONNECTED) mqtt.connect("fire-1");
mqtt.loop();
checkInterconnect(); // sound on any node's alarm
uint32_t now = millis();
float smoke = analogRead(PIN_SMOKE);
float temp = dht.readTemperature();
float ror = rateOfRise(temp, now);
bool flame = digitalRead(PIN_FLAME) == LOW;
if (fireConfirmed(smoke, temp, ror, flame)) {
if (!localFire) {
localFire = true;
soundLocal(true);
broadcastAlarm(); // make EVERY node sound + report origin
}
}
if (now - lastBeat > HEARTBEAT_MS) { // supervision heartbeat
char m[80];
snprintf(m,sizeof m,"{\"id\":%u,\"room\":\"%s\",\"ok\":1}",NODE_ID,ROOM);
mqtt.publish("fire/heartbeat", m);
lastBeat = now;
}
delay(200);
}
Configuration & Calibration
Configuration steps
- Set each node's ID/room, the smoke/heat/rate-of-rise thresholds, and the interconnect medium (wired/wireless).
- Tune nuisance-rejection (fusion, baselines) for each room's conditions and siting.
- Configure the control point, escalation to phones, and per-node supervision/heartbeat.
- Ensure battery backup and low-battery/power-loss alerts on every node.
Calibration procedure
An uncalibrated sensor produces confident, precise, wrong numbers. Do this once per physical unit and record the constants.
Detection thresholds
With test smoke/heat sources (safely), confirm early detection while cooking steam/shower humidity and dust do not trip the fused logic.
Rate-of-rise
Verify a rapid temperature climb triggers the ROR path before the absolute threshold, and that slow ambient changes do not.
Interconnect timing
Measure the time from one node detecting to all nodes sounding; ensure it is within a couple of seconds across the building.
Network Architecture & Connectivity
Communication protocol
A detection broadcasts to all nodes so every sounder fires within ~2 s, and escalates a located alert; heartbeats supervise every detector. The all-sound behaviour and local sounders do not depend on the internet.
| Topic / endpoint | Direction | Payload |
|---|---|---|
fire/alarm | node → all/control | FIRE with origin node/room |
fire/heartbeat | node → control | detector present/healthy (supervision) |
fire/status | node → control | battery, power, sensor health |
Message contract between the device and the broker.
Cloud platform configuration
A control point shows the room of origin and building status and escalates to phones/a monitoring point; heartbeats surface any missing or low-battery detector.
Dashboard setup
A building/floor plan with detector health and, on alarm, the origin room highlighted, plus an event and supervision log.
Mobile app integration
Immediate located fire alerts and maintenance alerts for missing/low-battery detectors.
Security considerations
- Authenticate interconnect/alarm messages so false fire alarms cannot be injected.
- Keep all-sound and local sounders independent of the internet; supervise continuously.
- Treat missing heartbeats and power loss as safety-relevant events.
Testing Procedure & Expected Output
Test from the bottom up. Confirm power, then each sensor in isolation, then the integrated loop — the first failing step tells you exactly where to look.
| Test | What you should see |
|---|---|
| Trigger smoke at one node | That node and ALL nodes sound within ~2 s; origin room reported |
| Rapidly heat a node | Rate-of-rise alarms before the fixed threshold |
| Create steam/dust near a node | No alarm (fused logic rejects the nuisance) |
| Remove/disable a node | Control point flags the missing detector via heartbeat loss |
| Cut mains power | Nodes keep detecting on battery; power-loss noted |
| Check the control point on alarm | Room of origin clearly shown for escape/response |
Bench-test checklist. If a row fails, stop and fix it before moving on.
Expected output
The control point shows building status and, on alarm, the room of origin; every node sounds, and a located alert escalates to phones.
{
"type": "FIRE",
"origin": 3,
"room": "Bedroom 2",
"time": "2026-07-27T03:12:44"
}
A detection in Bedroom 2 sounds every node in the building at once and tells the control point (and phones) the room of origin — the interconnection and location awareness that turn detection into survivable warning.
Troubleshooting: Common Errors & Fixes
Performance Optimisation
- Prioritise interconnect latency — all nodes must sound within a couple of seconds of any detection.
- Read sensors frequently enough for rate-of-rise to be meaningful without excess power.
- Keep all-sound and local sounders independent of Wi-Fi/internet; escalation is secondary.
- Heartbeat continuously so detector presence/health is always known.
- Replace every
delay()with amillis()comparison — blocking delays are the single most common cause of dropped readings. - Sample sensors on a fixed cadence and publish on a slower one; you almost never need to transmit at the sampling rate.
- Move networking into its own FreeRTOS task so a slow DNS lookup cannot stall the control loop.
- Use
uint8_t/uint16_twhere the range allows; on an 8-bit AVR a 32-bit add costs four times as much. - Batch several samples into one MQTT publish. Radio time, not CPU time, dominates the energy budget.
- Set the MQTT keep-alive to a value that matches your reporting interval so the broker does not churn reconnections.
- For battery builds use deep sleep between samples: an ESP32 drops from ~160 mA awake to about 10 µA asleep, which is the difference between days and months of runtime.
Safety Precautions
- THIS IS SUPPLEMENTARY/EDUCATIONAL — not a certified, listed, professionally-monitored fire-alarm system. Use listed smoke alarms and monitoring where codes require them.
- Interconnection (all sound when one detects) and low false-alarm rates (so detectors stay enabled) are the key life-safety properties — never compromise them.
- Provide battery backup and supervise every detector; a dead or removed detector is a silent, dangerous gap.
- Follow fire-code guidance on detector siting, quantity and placement.
- Lithium cells vent and burn when abused. Only use protected cells or a proper BMS, never charge below 0 °C, and never leave a charging pack unattended on a wooden desk.
- MQ-series sensors run a hot element. They get genuinely hot, need ventilation, and must never be enclosed in a sealed plastic box.
- Never power an RF module without its antenna fitted — the reflected power destroys the output stage. Check your local licence-free band and duty-cycle limits before transmitting.
- Wear eye protection when soldering or cutting, and solder in a ventilated space — rosin flux fumes are a respiratory irritant.
- Power the circuit through a bench supply with a current limit while you are testing. A 300 mA limit turns a wiring mistake into a beep instead of a dead board.
- Disconnect power before changing any wiring. Hot-plugging a sensor onto a live bus is the fastest way to lose a controller.
Maintenance
- Test the whole interconnected system regularly (one node triggers all) and check sounder loudness.
- Replace/clean smoke sensors and check batteries; act on every supervision alert.
- Re-verify nuisance rejection after changes in room use or siting.
- Keep the room/location map accurate for correct origin reporting.
- Re-check every screw terminal and header after the first week — thermal cycling loosens connections that felt tight on day one.
- Log pack voltage. When resting voltage after a full charge drops below about 4.0 V, the cell is near end of life — replace it.
- Keep the broker and dashboard containers patched, and rotate device credentials at least once a year.
- Recalibrate at the interval given in the calibration section, and keep the constants in a text file next to the firmware — not only in flash.
- Keep a short logbook of firmware versions and what changed. Six months later you will not remember why that constant is 1.083.
Future Improvements & Upgrades
A working v1 is a platform, not a finish line. These are the upgrades that add the most capability for the least rework.
- Add CO detection for a combined fire+CO safety system.
- Add voice evacuation messages naming the safe route away from the origin.
- Integrate with smart-home actions (lights on to escape routes, HVAC off).
- Add automatic escalation to a monitoring service or fire brigade where appropriate and permitted.
- Design a proper PCB. Once the breadboard version has run for a month, moving to a two-layer board removes the intermittent-contact failures that dominate prototype faults.
- Add over-the-air firmware updates so you never have to physically reach a deployed node again.
- Add persistent local storage (microSD or the on-chip flash) so a network outage does not create a hole in your data.
- Move configuration out of the source: a captive-portal setup page or a JSON config file makes the build reusable without a recompile.
- Add a battery and solar option so the unit survives a power cut and can be sited away from a socket.
- Write a small test harness that feeds synthetic sensor values through the decision logic, so you can validate thresholds without physically triggering the event.
Frequently Asked Questions
References & Learning Resources
These are the primary sources worth reading in full. Manufacturer datasheets always outrank forum posts when the two disagree.