PyRaspBeta

MQ-2 gas sensor

The MQ-2 is a combustible-gas and smoke sensor for $5. Inside is a tiny heater and a tin-dioxide element whose resistance falls when reducing gases reach it; the breakout adds a load resistor, a trimmer-comparator and two outputs. AO gives an analog voltage you can convert to a rough concentration, and DO snaps low when the gas crosses the trimmer's threshold — the simplest possible "is there smoke?" signal. It responds to LPG, propane, methane, hydrogen, alcohol and smoke alike, and cannot tell them apart.

MQ-2 gas sensor

Pins

PinWhat it isType
VCCSupply 5 V (heater)power
GNDGroundground
DODigital out: LOW when gas is above the threshold (pulled up to VCC)io
AOAnalog out (0–VCC)io
SettingTypeRangeDefault
thresholdVnumber0–52.5

In circuit.py:

The thresholdV setting is the trimmer: the AO voltage above which DO pulls low. Both outputs swing to VCC, so on a 5 V supply both need dividing down before the Pi.

Wiring it in circuit.py

Digital output through a 10 kΩ / 20 kΩ divider, with the heater on 5 V:

circuit.py
from wiring import *

pi = Pi()

gas = GasSensor()

pi.V5 >> gas.vcc                        # the heater needs a real 5 V supply
gas.gnd >> pi.GND
gas.do >> Resistor(10000) >> pi.GPIO17  # DO swings to 5 V: divide it down
pi.GPIO17 >> Resistor(20000) >> pi.GND

The 10 kΩ series resistor and 20 kΩ to ground cap the pin at about 3.3 V. Reading AO instead means an MCP3008 or ADS1115 — the sensor's analog output is a divider itself, so the same rule applies: never put 5 V straight on the Pi. The module's own 10 kΩ pull-up holds DO high when the air is clean; the comparator pulls it low on gas.

Driving it in main.py

main.py
from gpiozero import DigitalInputDevice
from time import sleep

detector = DigitalInputDevice(17)     # DO is pulled up, and goes LOW on gas

while True:
    print("gas!" if detector.value == 0 else "clear")
    sleep(1)

DO is active low: 0 means gas, 1 means clear air. (gpiozero's active_state argument cannot be used here — it is only allowed on a floating pin, and the module's pull-up holds this one high.) To read a concentration, sample AO through an ADC and use the datasheet curve below; remember that the absolute number is only as good as the sensor's calibration.

Electrical notes

  • The heater needs 5 V at about 150 mA — the biggest load in the shop's sensors. It takes 20 s to warm up (the datasheet's own timing) and minutes to stabilise; a brand-new sensor wants a day of burn-in.
  • DO and AO swing to VCC (5 V): divide them down before a GPIO or a 3.3 V ADC. DO is active low and is pulled up to VCC through about 10 kΩ on the board.
  • The sensing curve is Rs/R0 ≈ 21 × ppm^−0.47 in clean air at about 9.8; R0 itself sits in the 5–20 kΩ band. AO is the load-resistor divider that turns that into volts.
  • Because it is a hot-wire sensor, it drifts with humidity and temperature and needs re-calibration at intervals; the absolute ppm numbers are rough.

Simulator vs real hardware

  • Gas concentration comes from the feed: background 5 ppm with occasional leaks (1 500 ppm for a minute, about four a day by default), or anything you drive it with in the Lab. A warmUpS knob (20 s by default) makes the element read artificially gassy while it heats.
  • The comparator threshold is the thresholdV property, default 2.5 V. The canvas shows the heater glow and the alarm light.
  • The model uses the datasheet power law exactly, capped at the clean-air ratio, so the curve is smooth where a real MQ-2 is noisy and hysteretic.
  • There is no burn-in, no poisoning, no drift and no humidity response in the model — all real reasons the same module reads differently after a month.

Going deeper

Further reading