The MQ-2 senses smoke and flammable gases such as LPG and methane, which makes it the basis of kitchen gas and smoke alarms.
On the Uno it is a 5 V part with two outputs: AO to an analog pin for the level, and DO for a threshold you set with the trimmer. Treat it as an early-warning hobby sensor, not a certified alarm.
Wiring
| Arduino Uno R3 | MQ-2 gas sensor module | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | The heater draws about 150 mA — fine from USB 5 V. |
| A0 | AO | yellow | |
| D2 | DO | green | |
| GND | GND | black |
5 V (heater: about 150 mA) part, 5 V board. The heater needs 5 V. AO can reach about 5 V, so on ESP32 and Pico feed AO through a 10 kΩ / 20 kΩ divider (or similar) to stay under 3.3 V. DO is driven by the comparator from VCC — divide it too on 3.3 V boards.
Board quirks
- The MQ-2’s heater needs about a minute (and a day for best stability when new) before readings settle — the sketch marks early readings.
- AO gives a relative level, not ppm. Real ppm needs calibration in clean air and the datasheet curve.
- On most modules DO goes LOW and the on-board LED lights when gas exceeds the blue trimmer’s threshold.
Code
// MQ-2 smoke / LPG gas sensor module on an Arduino Uno R3.
// VCC → 5V, GND → GND, AO → A0 (analog level), DO → D2 (threshold set by the blue trimmer).
const uint8_t AO_PIN = A0;
const uint8_t DO_PIN = 2;
const unsigned long WARMUP_MS = 60000UL; // let the heater stabilise
void setup() {
Serial.begin(9600);
pinMode(DO_PIN, INPUT);
Serial.println(F("MQ-2 heating up - readings settle after about a minute"));
}
void loop() {
int raw = analogRead(AO_PIN); // 0-1023 for 0-5 V
bool alarm = digitalRead(DO_PIN) == LOW; // module pulls DO low above the threshold
Serial.print(millis() < WARMUP_MS ? F("[warming] ") : F(""));
Serial.print(F("Gas level: "));
Serial.print(raw);
Serial.println(alarm ? F(" ALARM (above trimmer threshold)") : F(""));
delay(1000);
}// MQ-2 smoke / LPG gas sensor module on an Arduino Uno R3.
// VCC → 5V, GND → GND, AO → A0 (analog level), DO → D2 (threshold set by the blue trimmer).
const uint8_t AO_PIN = A0;
const uint8_t DO_PIN = 2;
const unsigned long WARMUP_MS = 60000UL; // let the heater stabilise
void setup() {
Serial.begin(9600);
pinMode(DO_PIN, INPUT);
Serial.println(F("MQ-2 heating up - readings settle after about a minute"));
}
void loop() {
int raw = analogRead(AO_PIN); // 0-1023 for 0-5 V
bool alarm = digitalRead(DO_PIN) == LOW; // module pulls DO low above the threshold
Serial.print(millis() < WARMUP_MS ? F("[warming] ") : F(""));
Serial.print(F("Gas level: "));
Serial.print(raw);
Serial.println(alarm ? F(" ALARM (above trimmer threshold)") : F(""));
delay(1000);
}Expected serial output
MQ-2 heating up - readings settle after about a minute
[warming] Gas level: 412
Gas level: 168
Gas level: 655 ALARM (above trimmer threshold)MQ-2 heating up - readings settle after about a minute [warming] Gas level: 412 Gas level: 168 Gas level: 655 ALARM (above trimmer threshold)
Common errors
Readings drift for the first minutes
Normal heater warm-up. Ignore readings until it stabilises.
The module gets hot
Expected — the sensing element runs a heater. Mount it with airflow, away from plastic.