How to use MQ-2 gas sensor for smoke detection?

ampheoampheo
4 min read

Here’s a practical, no-nonsense guide to using an MQ-2 for smoke detection with Arduino.


What the MQ-2 is (and isn’t)

  • Detects: smoke/particulates via combustible gases (LPG/propane, H₂, CH₄, alcohol, etc.). Output is analog (resistance change).

  • Not a certified safety detector. For life safety, use a UL/EN-certified smoke alarm. MQ-2 is great for hobby / non-critical projects.


Hardware you’ll need

  • MQ-2 sensor (bare sensor or common breakout with LM393 + potentiometer).

  • Arduino Uno (or similar, 5 V ADC).

  • 5 V power that can supply ≥200 mA (the heater draws ~150–180 mA). Prefer an external 5 V supply; tie grounds together.

  • Optional: buzzer/LED.


Pinout & wiring (typical breakout)

  • VCC → 5 V, GND → GND

  • A0 → A0 (Arduino analog input)

  • D0 (digital/threshold output from on-board comparator) → any digital pin (optional)

Use A0/analog for reliable detection & tuning. The D0 threshold is coarse.

If you have the bare sensor:

  • It’s a resistive element + heater. Use a load resistor (RL ~ 5–20 kΩ) in series to form a divider:
5V ---[ MQ-2 (Rs) ]---+--- A0
                       |
                      [RL] 10k (start here)
                       |
                      GND

Warm-up & calibration

  1. Burn-in: first use, let heater run for 24–48 h (datasheet practice) for stable baseline.

  2. Each power-up: wait 3–5 min before trusting readings.

  3. Baseline R0 (optional but useful):

    • In clean air, measure sensor resistance Rs​ and record it as R0.

    • With the divider above:
      Rs​=RL​⋅(VCC​​/Vout​−1)
      where Vout is the voltage at A0.

    • Use Rs/R0 ratio for robust thresholds: smoke ⇒ Rs dropsRs/R0 decreases.


Simple “smoke present” detection (recommended start)

Idea: Smooth the analog value, compare to a threshold you find during tests (e.g., incense, match smoke).

// MQ-2 on A0, buzzer on D8 (optional)
const int PIN_MQ2 = A0;
const int PIN_BUZ = 8;

const int N = 20;              // moving average length
float avg = 0;
float alpha = 2.0f / (N + 1);  // EMA smoother

// Set after experiments:
// Lower threshold => more sensitive (more false positives)
int smokeThreshold = 520; // 0..1023 (adjust to your room & sensor)

void setup() {
  pinMode(PIN_BUZ, OUTPUT);
  digitalWrite(PIN_BUZ, LOW);
  Serial.begin(115200);

  // Warm-up notice
  Serial.println("MQ-2 warming up 180s...");
  for (int i = 0; i < 180; i++) { delay(1000); }
  Serial.println("Ready.");
}

void loop() {
  int raw = analogRead(PIN_MQ2);          // 0..1023
  if (avg == 0) avg = raw;                // init EMA
  avg = avg + alpha * (raw - avg);

  // simple hysteresis to reduce chatter
  static bool alarm = false;
  const int H = 15; // hysteresis counts

  if (!alarm && avg > smokeThreshold) {
    alarm = true;
    digitalWrite(PIN_BUZ, HIGH);
    Serial.print("ALARM: ");
  } else if (alarm && avg < smokeThreshold - H) {
    alarm = false;
    digitalWrite(PIN_BUZ, LOW);
    Serial.print("Clear: ");
  }

  Serial.print("raw="); Serial.print(raw);
  Serial.print(" avg="); Serial.print((int)avg);
  Serial.print(" th="); Serial.println(smokeThreshold);

  delay(50);
}

How to set smokeThreshold:

  • Measure avg in clean air (after warm-up). Note the value (e.g., 400–480 with RL=10 k).

  • Expose to a small smoke source (incense/match at safe distance) and see the avg rise (often ≥550–700).

  • Pick a threshold between them with some margin (e.g., clean 460 → smoke 620 ⇒ threshold ≈ 520–560).


Going further: Rs/R0 & (rough) ppm estimation

  • The MQ-2 datasheet provides log-log curves of Rs/R0 vs ppm for various gases (smoke line ≈ “smoke/alcohol/LPG” family).

  • Procedure:

    1. Find R0 in clean air (or per datasheet reference gas).

    2. Compute Rs from A0 each sample; then ratio = Rs/R0.

    3. Using two points from the datasheet’s smoke curve, fit a line in log-space:
      log10​(ratio)=m⋅log10​(ppm)+b
      ⇒ppm=10(log10​(ratio)−b)/m.

  • Because curves vary unit-to-unit and with humidity/temperature, treat ppm as order-of-magnitude, not exact.


Practical tips (to reduce false alarms)

  • Ventilation & placement: Avoid placing near kitchens directly over stoves; rising alcohol vapors trigger it.

  • Humidity/temperature affect readings; if possible, log values and use adaptive thresholds or add a temp/RH sensor for compensation.

  • Power: Don’t run the sensor heater from Arduino’s 5 V if powered via USB; use an external 5 V with common GND.

  • Settling: After power-on, ignore the first minutes; values drift as the heater stabilizes.

  • Filtering: Use moving average / EMA (as above) and a time window (e.g., must exceed threshold for ≥2–5 s) before alarm.

  • Digital D0 pin on LM393 boards: convenient but coarse. Prefer A0 and your own logic.

  • Safety: Treat this as an indicator, not a certified alarm.


Troubleshooting

  • No change with smoke: wrong wiring, RL too high/low, not warmed up, bad airflow.

  • Always high: sensor saturated (too close to source) or threshold too low.

  • Noisy readings: add averaging, keep wires short, separate sensor power from noisy loads, decouple 5 V near the module (e.g., 100 nF + 10 µF).

0
Subscribe to my newsletter

Read articles from ampheo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ampheo
ampheo