Learn
Detecting Gas and Smoke with an MQ-2 Sensor on a Raspberry Pi 4B
Wire an MQ-2 gas/smoke sensor to a Raspberry Pi 4B, read its digital alarm output (DO) directly, and read its analog output (AO) through an MCP3008 ADC, all driven by one adjustable gas level in the simulator.
Note: the MQ-2 Gas/Smoke Sensor is a VIP-tier component in the simulator — you’ll need a VIP plan to use it there.
Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.
What you’ll need
- Raspberry Pi 4B
- MQ-2 Gas/Smoke Sensor
- Resistor (1kΩ)
- Resistor (2kΩ)
- MCP3008 ADC (for the analog part)
Step by step
- Drag Raspberry Pi 4B and the MQ-2 Gas/Smoke Sensor onto the Canvas.
- Power the sensor:
| MQ-2 pin | Pi pin |
|---|---|
| VCC | 5V |
| GND | GND |
The MQ-2 has two outputs from the same simulated gas level. DO is a yes/no alarm: it sits HIGH in clean air and is pulled LOW once the gas level reaches the sensor's sensitivity threshold (this is how the real module's comparator works, so LOW means gas detected). AO is an analog voltage that rises smoothly with the gas level. We'll use DO first because it needs no ADC.
- Part 1, the digital alarm (DO). DO swings up to 5V, but the Pi's GPIO pins only tolerate 3.3V, so drop it through a voltage divider:
| From | To |
|---|---|
| MQ-2 DO | one end of the 1kΩ Resistor |
| other end of the 1kΩ Resistor | Pi physical pin 37 and one end of the 2kΩ Resistor (the divider's middle) |
| other end of the 2kΩ Resistor | Pi GND pin |
1kΩ over 2kΩ turns 5V into about 3.3V at the middle point, which is safe for the Pi. If you wire DO straight to a Pi pin instead, the Console prints a warning about 5V on a 3.3V pin when the script sets the pin up.
- Go to the Code tab and write a script that watches the alarm:
import RPi.GPIO as GPIOimport asyncio GPIO.setmode(GPIO.BOARD)GPIO.setup(37, GPIO.IN) while True: if GPIO.input(37) == 0: print("GAS DETECTED!") else: print("Air is clear") await asyncio.sleep(0.5)- Select the MQ-2 and look at its settings panel. Gas level (ppm) is the simulated concentration; Sensitivity threshold (ppm) is where the alarm trips (default 1000). Click a preset such as LPG leak, then click Start.
Settings can only be changed while the simulation is stopped. Stop, choose Clean air (400 ppm) and Start again to see "Air is clear"; choose LPG leak (3000 ppm) or Smoke (8000 ppm) and Start to see "GAS DETECTED!". The sensor's onboard LED turns red while the alarm is on.
- Part 2, the analog reading (AO). Drag the MCP3008 ADC onto the Canvas and wire it to the Pi's fixed SPI pins (physical/BOARD numbering):
| MCP3008 pin | Pi pin |
|---|---|
| VDD | 3.3V |
| VREF | 3.3V |
| AGND | GND |
| DGND | GND |
| CLK | Physical pin 23 (SCLK) |
| DOUT | Physical pin 21 (MISO) |
| DIN | Physical pin 19 (MOSI) |
| CS/SHDN | Physical pin 24 (CE0) |
- Wire the sensor's analog output to the ADC:
| From | To |
|---|---|
| MQ-2 AO | MCP3008 CH0 |
- Replace the script with one that reads the analog value:
import spidevimport asyncio spi = spidev.SpiDev()spi.open(0, 0)spi.max_speed_hz = 1350000 def read_channel(channel): adc = spi.xfer2([1, (8 + channel) << 4, 0]) return ((adc[1] & 3) << 8) + adc[2] # returns 0-1023 while True: value = read_channel(0) print(f"Gas reading: {value} / 1023") await asyncio.sleep(0.5)AO rises in a straight line from 0V at 0 ppm to 5V at 10000 ppm. The MCP3008 here measures against 3.3V, so expect roughly 62 at Clean air (400 ppm) and about 465 at LPG leak (3000 ppm). At Smoke (8000 ppm) the sensor outputs about 4V, more than the 3.3V reference, so the reading pins at 1023 and the Console warns that the channel is over range. That warning is real: on hardware you would put a divider on AO too.
What “working correctly” looks like
- Part 1: the Console prints "Air is clear" at Clean air and "GAS DETECTED!" once the gas level reaches the threshold or goes above it.
- The sensor's onboard LED lights red while gas is detected.
- Part 2: the reading climbs as you raise the gas level: about 62 in clean air, about 465 at 3000 ppm, and 1023 when the level is high enough to exceed the 3.3V reference.
- Lowering the Sensitivity threshold makes the alarm trip at a lower gas level; raising it makes the sensor less sensitive.
If something’s wrong
- The alarm never trips, or is always tripped → check the Gas level against the Sensitivity threshold in the settings panel: DO only goes LOW when the gas level is at or above the threshold.
- The Console warns about 5V on a 3.3V pin → DO is wired straight to the Pi pin; put the 1kΩ/2kΩ divider between DO and the pin as shown.
- DO always reads the same value → make sure VCC goes to 5V and GND to GND, and that the script uses the same physical pin (37) you wired.
- The analog reading is always 0 → check the MCP3008's VDD, VREF, AGND and DGND, that CS goes to physical pin 24 (CE0), and that AO goes to CH0.
- The analog reading pins at 1023 with an over-range warning → the sensor's AO is above the ADC's 3.3V reference at that gas level; lower the gas level, or add a divider on AO as you would on real hardware.
- The reading doesn't change when you change the gas level → change it while stopped, then Start again.