Building a reliable fire detector sensor Arduino project requires more than just a single component. Relying solely on a smoke sensor or solely on a flame sensor invites false alarms from burnt toast or direct sunlight. By combining an MQ-2 combustible gas/smoke sensor with an IR flame module, you create a dual-verification system that triggers only when both particulate smoke and infrared radiation are present. This guide walks you through the exact hardware, bench-tested wiring, and robust C++ code needed to build, debug, and deploy this system.
Hardware Spec Sheet & Sensor Comparison
Before wiring the breadboard, it is critical to understand the physical limitations of the metal-oxide semiconductor (MOS) gas sensors. The MQ-series sensors require a preheat time to stabilize the internal tin dioxide (SnO2) layer. If you skip this, your analog baseline will drift wildly. Below is a data-dense comparison of common sensors used in fire and air-quality projects to justify our component selection.
| Sensor Model | Target Stimulus | Operating Voltage | Initial Preheat Time | Analog Out Range (0-5V) | Approx. Cost (USD) |
|---|---|---|---|---|---|
| MQ-2 | LPG, Butane, Propane, Methane, Smoke | 5.0V ± 0.1V | 24 Hours (First use) | 0.1V (Clean) to 4.5V (High PPM) | $2.50 - $4.00 |
| MQ-7 | Carbon Monoxide (CO) | 5.0V (Pulsed) | 48 Hours | Varies with pulse cycle | $3.00 - $4.50 |
| MQ-135 | NH3, NOx, Alcohol, Benzene, Smoke | 5.0V ± 0.1V | 24 Hours | 0.2V (Clean) to 4.8V (High PPM) | $2.00 - $3.50 |
| YG1006 (IR Flame) | 760nm - 1100nm IR Light (Flame) | 3.3V to 5.0V | None (Instant) | N/A (Digital/Comparator) | $1.00 - $2.00 |
Source: Hanwei Electronics MQ-2 Datasheet
Parts List & Pin Mapping
This build targets the Arduino Uno R3 (ATmega328P). We use the Uno because its 5V logic and dedicated 5V rail perfectly match the MQ-2's strict voltage requirements. Attempting to run an MQ-2 on a 3.3V Arduino Nano 33 IoT or ESP32 without a level shifter and dedicated 5V power supply will result in a non-responsive heater circuit.
Bill of Materials (BOM)
- Microcontroller: Arduino Uno R3 (Rev3) with ATmega328P
- Smoke Sensor: MQ-2 Breakout Board (Must include the LM393 voltage comparator IC)
- Flame Sensor: 5-pin IR Flame Module (YG1006 phototransistor with LM393)
- Alert: 5V Active Buzzer (Continuous tone, not passive)
- Indicators: 2x 5mm Red LEDs, 2x 220Ω current-limiting resistors
- Wiring: Half-size solderless breadboard, 22 AWG solid core jumper wires
Pin Mapping Table
| Component | Module Pin | Arduino Uno R3 Pin | Notes |
|---|---|---|---|
| MQ-2 Sensor | VCC | 5V | Do NOT use 3.3V |
| MQ-2 Sensor | GND | GND | Common ground |
| MQ-2 Sensor | AOUT | A0 | Analog smoke density |
| MQ-2 Sensor | DOUT | D8 | Digital threshold trigger |
| IR Flame Module | VCC | 5V | 3.3V acceptable but 5V preferred |
| IR Flame Module | GND | GND | Common ground |
| IR Flame Module | D0 | D9 | Digital flame detection |
| Active Buzzer | + (Red) | D10 | PWM capable, but digital HIGH used |
| Active Buzzer | - (Black) | GND | Common ground |
| Smoke LED | Anode (+) | D11 (via 220Ω) | Visual smoke alert |
| Flame LED | Anode (+) | D12 (via 220Ω) | Visual flame alert |
Step-by-Step Wiring & Assembly
- Establish Power Rails: Connect the Arduino 5V pin to the red breadboard rail and the Arduino GND to the blue breadboard rail. Verify with a multimeter that you have exactly 4.9V to 5.1V across these rails before plugging in sensitive modules.
- Wire the MQ-2: Connect VCC to 5V, GND to GND, AOUT to A0, and DOUT to D8. The MQ-2 draws roughly 150mA during peak heating; ensure your USB cable or wall adapter can supply at least 1A total.
- Wire the IR Flame Sensor: Connect VCC to 5V, GND to GND, and D0 to D9. Leave the AOUT pin on the flame sensor disconnected for this build, as we only need the digital comparator output to confirm the presence of an open flame.
- Wire the Outputs: Connect the active buzzer's positive leg to D10 and negative to GND. Connect your LEDs to D11 and D12, ensuring the 220Ω resistors are in series with the anodes to prevent burning out the Arduino's GPIO pins (max 20mA per pin).
- Calibrate the Potentiometers: Using a small Phillips screwdriver, turn the blue potentiometer on the MQ-2 board. While monitoring the Serial Monitor (code provided below), adjust it until the digital pin (D8) flips from HIGH to LOW in clean air. Do the same for the flame sensor, pointing it at a lighter flame from 12 inches away to set the detection distance.
Complete Arduino Code with Error Handling
The following code is written specifically for the Arduino Uno R3 (ATmega328P). It includes hardware fault detection. If a sensor wire breaks or shorts, the microcontroller will catch the stuck analog/digital values and flag a critical error rather than silently failing to protect your property.
// Fire Detector Sensor Arduino Project
// Target Board: Arduino Uno R3 (ATmega328P)
// Sensors: MQ-2 (Smoke/Gas), YG1006 (IR Flame)
// --- PIN DEFINITIONS ---
#define MQ2_ANALOG_PIN A0
#define MQ2_DIGITAL_PIN 8
#define FLAME_DIGI_PIN 9
#define BUZZER_PIN 10
#define SMOKE_LED_PIN 11
#define FLAME_LED_PIN 12
// --- THRESHOLDS ---
// MQ-2 Analog: 0 (clean) to 1023 (high gas). Trigger if > 400.
#define SMOKE_THRESHOLD 400
// Hardware fault thresholds
#define SENSOR_SHORT_VAL 0
#define SENSOR_OPEN_VAL 1023
bool systemFault = false;
void setup() {
Serial.begin(9600);
pinMode(MQ2_DIGITAL_PIN, INPUT);
pinMode(FLAME_DIGI_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(SMOKE_LED_PIN, OUTPUT);
pinMode(FLAME_LED_PIN, OUTPUT);
// Boot sequence indicator
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
Serial.println("[SYS] Fire Detector Initialized. Preheating MQ-2...");
// Allow MQ-2 to stabilize if recently powered on
// In a real deployment, remove this delay if the system runs 24/7
delay(3000);
}
void loop() {
if (systemFault) {
// Blink buzzer and both LEDs rapidly to indicate hardware failure
toggleOutputs();
delay(250);
return; // Halt normal operations
}
int smokeRaw = analogRead(MQ2_ANALOG_PIN);
bool smokeDigital = digitalRead(MQ2_DIGITAL_PIN);
bool flameDigital = digitalRead(FLAME_DIGI_PIN);
// --- ERROR HANDLING & SENSOR HEALTH CHECK ---
// If analog reads exactly 0 or 1023 consistently, wiring is likely faulted
if (smokeRaw <= SENSOR_SHORT_VAL + 5) {
Serial.println("[ERR] MQ2 Sensor Shorted/Disconnected (Val: 0)");
systemFault = true;
return;
}
// Note: A raw value of 1023 on MQ-2 can mean extremely high gas OR a broken AOUT trace.
// We rely on the digital pin to cross-verify. If Analog is 1023 but Digital is LOW, it's a broken trace.
if (smokeRaw >= SENSOR_OPEN_VAL - 5 && smokeDigital == LOW) {
Serial.println("[ERR] MQ2 AOUT Trace Broken (Val: 1023, DOUT: LOW)");
systemFault = true;
return;
}
// --- DUAL VERIFICATION LOGIC ---
// Alarm triggers ONLY if both Smoke (Analog > Threshold) AND Flame (IR detected) are true.
// This prevents false alarms from aerosol sprays or sunlight.
bool smokeDetected = (smokeRaw > SMOKE_THRESHOLD) || (smokeDigital == HIGH);
bool flameDetected = (flameDigital == LOW); // YG1006 D0 goes LOW when flame is detected
if (smokeDetected && flameDetected) {
triggerFireAlarm();
} else {
// Handle individual warnings for debugging
if (smokeDetected) {
digitalWrite(SMOKE_LED_PIN, HIGH);
Serial.print("[WARN] Smoke detected. Raw: "); Serial.println(smokeRaw);
} else {
digitalWrite(SMOKE_LED_PIN, LOW);
}
if (flameDetected) {
digitalWrite(FLAME_LED_PIN, HIGH);
Serial.println("[WARN] IR Flame detected.");
} else {
digitalWrite(FLAME_LED_PIN, LOW);
}
digitalWrite(BUZZER_PIN, LOW);
}
delay(500); // Polling interval
}
void triggerFireAlarm() {
Serial.println("[CRITICAL] FIRE DETECTED: Smoke + Flame Verified!");
digitalWrite(SMOKE_LED_PIN, HIGH);
digitalWrite(FLAME_LED_PIN, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
}
void toggleOutputs() {
static bool state = false;
state = !state;
digitalWrite(BUZZER_PIN, state);
digitalWrite(SMOKE_LED_PIN, state);
digitalWrite(FLAME_LED_PIN, state);
if (state) Serial.println("[FAULT] Hardware error. Check sensor wiring.");
}
Debugging: First Three Checks & Common Errors
When working with analog gas sensors on a breadboard, intermittent connections are the most common point of failure. If your Serial Monitor outputs [ERR] MQ2 Sensor Shorted/Disconnected (Val: 0) or the system fails to trigger, perform these first three diagnostic checks:
- Verify 5V Heater Continuity: Unplug the Arduino. Set your multimeter to continuity mode. Place the probes on the VCC and GND pins of the MQ-2 module. You should read a low resistance (typically 10Ω to 30Ω). If you read "OL" (Open Loop), the internal heating element is blown, or the breadboard contact is dead. The MQ-2 heater requires 5V; if powered by 3.3V, it won't heat up, and the sensor will output a flat 0 or baseline voltage regardless of gas presence.
- Check the LM393 Comparator Potentiometer: If the digital pin (D8/D9) is stuck HIGH or LOW, the blue trimpot on the breakout board is likely miscalibrated. Use a multimeter to measure the voltage on the DOUT pin while turning the screw. It should snap sharply from 0V to 5V at the threshold.
- Inspect Analog Pin Selection: A classic beginner mistake is wiring the MQ-2 AOUT pin to a digital pin (e.g., D2) and using
analogRead(), or wiring it to A0 but callingdigitalRead(A0)in the code. Ensure physical A0 matches the#define MQ2_ANALOG_PIN A0directive.
[ERR] MQ2 AOUT Trace Broken (Val: 1023, DOUT: LOW)Ranked Causes:
1. The analog wire is physically broken or loose, causing the ATmega328P internal pull-up or floating capacitance to read maximum ADC (1023).
2. The LM393 comparator on the MQ-2 board is functional (hence DOUT is correctly LOW for clean air), but the op-amp feeding the AOUT pin has failed.
3. The sensor is saturated beyond its 10,000 PPM limit in a highly concentrated gas environment (less likely in ambient room testing).
For more on how the Arduino ADC handles floating pins and reference voltages, consult the official Arduino analogRead() documentation.
Extending and Simplifying the Build
Depending on your end goal, this dual-sensor fire detector can be scaled up for home automation or stripped down for a basic science fair project.
How to Extend the Build (IoT & Compensation)
- Add MQTT via ESP32: Swap the Arduino Uno for an ESP32-WROOM-32 DevKit v1. Because the ESP32 is 3.3V logic, you must use a logic level converter (like the BSS138) between the ESP32 GPIOs and the MQ-2's 5V digital output. Use the
PubSubClientlibrary to push thesmokeRawinteger to a Home Assistant MQTT broker. - Humidity Compensation: Metal-oxide sensors suffer from baseline drift in high humidity. Add a DHT22 or BME280 sensor. If Relative Humidity (RH) exceeds 75%, apply a software offset to the
SMOKE_THRESHOLDin the code to prevent false alarms on muggy days. - Battery Backup: Add a 5V USB UPS module (like the Geekworm X735 or a standard 18650 power bank with pass-through charging) to ensure the detector survives a mains power outage during a fire.
How to Simplify the Build
If you only need a basic line-of-sight flame alarm (e.g., for a candle or a small robotics fire-fighting competition), drop the MQ-2 entirely. The MQ-2 is slow to respond and requires continuous high-current heating. By using only the YG1006 IR Flame Sensor, you reduce the circuit to three wires (VCC, GND, D0). You can power this simplified version directly from a 3.7V LiPo battery via a 3.3V LDO regulator, making it portable and eliminating the 24-hour preheat requirement.






