How to use an MQ-2 gas sensor with an Arduino
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
Wire VCC to 5 V, GND to GND and AO to A0, then read it with analogRead(): a higher number means more gas. Wait for the heater to warm up before you believe any reading, and set your alarm level from what your own sensor reads in clean air. The DO pin gives a yes or no from the board’s trimmer, and it goes LOW on gas.
The circuit above is an MQ-2 on A0 of an Uno, printing the reading five times a second. Press Run and watch the warm-up. One second in it prints "A0 = 336 (1642 mV)" in perfectly clean air, and the number sinks as the heater settles, to "A0 = 11 (53 mV)" by about 20 seconds. Then drag the slider to 1000 ppm of LPG and it climbs to "A0 = 120 (586 mV)" over a few seconds.
That warm-up is the thing every MQ-2 project trips over, so this page starts there. Then come the parts, the wiring, a smoke alarm that waits for it, what each gas reads, and how to turn the reading into the ratio the datasheet uses.
What you need
- An Arduino Uno
- An MQ-2 gas sensor on its comparator board (FC-22 or similar)
- An LED and a 220 ohm resistor, or an active buzzer
- Jumper wires
Wiring
| Part and pin | Goes to | Note |
|---|---|---|
| MQ-2 VCC | 5 V | The heater needs a real 5 V and about 150 mA |
| MQ-2 GND | GND | |
| MQ-2 AO | A0 | Higher means more gas |
| MQ-2 DO | Any digital pin | Optional: LOW when past the trimmer |
How it works, and why it needs to warm up
Inside the steel mesh can is a small ceramic tube coated with tin dioxide, with a heater coil down the middle. Hot tin dioxide conducts poorly in clean air. A gas that burns, such as LPG, methane, hydrogen, alcohol or smoke, lets it conduct better, so its resistance falls. The board puts the sensor over a 1k load resistor, so less resistance means a higher voltage on AO.
A cold sensor reads like a room full of gas. In the run above the reading was 336 one second in, and the DO lamp on the board was lit, with nothing in the air at all. Over the next 20 seconds the reading fell to 11. A sketch that sounds the alarm on its first reading goes off every time it is switched on. Wait for the warm-up, and on a real sensor give a new one a day of burn-in before you trust its numbers.
A smoke and gas alarm that waits
This sketch reads A0 once a second, ignores it for the first 20 seconds and then lights the LED on pin 13 when the reading passes 100. We ran it with an MQ-2 wired up and clean air for 25 seconds, then 1000 ppm of LPG. The first readings were 500, 302 and 180, each printed with "warming up". From 20 seconds it printed "11 clean". When the gas came in the reading rose 28, 51, 72, 88 and 100, still "clean", then "107 GAS!" and the LED came on.
Why 100? Because clean air here reads 11, and 1000 ppm of LPG settles at about 120. Your sensor will differ. Run the sketch once in clean air, note the number, and set LIMIT well above it.
const int GAS_AO = A0;
const int ALARM_LED = 13;
const int LIMIT = 100;
const unsigned long WARMUP_MS = 20000;
void setup() {
pinMode(ALARM_LED, OUTPUT);
Serial.begin(9600);
Serial.println("MQ-2 warming up");
}
void loop() {
int reading = analogRead(GAS_AO);
bool warm = millis() >= WARMUP_MS;
bool gas = warm && reading > LIMIT;
digitalWrite(ALARM_LED, gas ? HIGH : LOW);
Serial.print(reading);
if (!warm) {
Serial.println(" warming up");
} else {
Serial.println(gas ? " GAS!" : " clean");
}
delay(1000);
}The same ppm reads differently for each gas
The MQ-2 reacts to many gases, but not equally. We ran the alarm above with 1000 ppm of each gas the model knows. After the reading settled, LPG read 119, hydrogen 93, alcohol 60, methane 59, smoke 57 and carbon monoxide 33. Only LPG passed the limit of 100.
So a reading on its own cannot tell you which gas is there, or how much of it. A level that catches a leaking camping stove may miss the same amount of natural gas. If you care about one gas, set the limit with that gas in mind, and for carbon monoxide use a sensor made for it, such as an MQ-7.
From a reading to the datasheet’s ratio
The datasheet does not talk in counts. It plots Rs/R0: the sensor’s resistance divided by its resistance in 1000 ppm of hydrogen. You can work Rs out from the reading, because the sensor and the 1k load resistor make a voltage divider: Rs = RL x (1023 - reading) / reading. The sketch below does it in whole numbers, since an Uno has no fast floating point.
With R0 at 10k, as this model’s is, clean air printed "Rs = 92000 ohm, Rs/R0 = 9.2", close to the 9.8 the datasheet shows for clean air. With 1000 ppm of LPG it settled at "Rs = 7525 ohm, Rs/R0 = 0.7". To get a real ppm you would find R0 for your own sensor and read the gas off the datasheet’s chart. Most hobby projects do not need to, and a threshold is enough.
const long RL = 1000; // the board's load resistor
const long R0 = 10000; // Rs in 1000 ppm of hydrogen
void setup() {
Serial.begin(9600);
}
void loop() {
int raw = analogRead(A0);
if (raw < 1) raw = 1;
long rs = RL * (1023 - raw) / raw;
long tenths = rs * 10 / R0;
Serial.print("Rs = ");
Serial.print(rs);
Serial.print(" ohm, Rs/R0 = ");
Serial.print(tenths / 10);
Serial.print(".");
Serial.println(tenths % 10);
delay(1000);
}What the simulation leaves out
The model has one gas at a time, and humidity and temperature do not move the reading, though on a real sensor they move it by tens of percent. The heater draws about 150 mA on a real board, enough to make a USB-powered Uno’s 5 V sag, and the supply here does not feel it. The 20 second warm-up stands in for the datasheet’s 24 hour burn-in.
Common mistakes
Alarming during the warm-up. A cold MQ-2 reads high, so ignore it for the first 20 seconds or more.
Running it from 3.3 V or a weak supply. The heater is specified at 5 V and draws around 150 mA, and a sagging supply moves every reading.
Expecting ppm from analogRead(). The number is counts on a divider, not parts per million, and each gas has its own curve.
Reading DO as "HIGH means gas". DO goes LOW and its lamp lights when the gas passes the trimmer.
Using it as a safety device. A hobby MQ-2 is fine for learning and for a smoke-sensing robot. A gas or carbon monoxide alarm in a home should be a certified one.
Questions
How do I connect an MQ-2 to an Arduino?
VCC to 5 V, GND to GND and AO to an analog pin such as A0. Read it with analogRead(); a higher number means more gas. DO can go to a digital pin for a yes or no from the board’s trimmer.
Why does my MQ-2 read high when I first turn it on?
The heater is still warming up, and a cold sensor reads as if the room were full of gas. In the simulator it read 336 one second after power in clean air, and fell to 11 over about 20 seconds.
What gases does the MQ-2 detect?
LPG, propane, methane, hydrogen, alcohol and smoke, and carbon monoxide weakly. At the same 1000 ppm, LPG read 119 and carbon monoxide 33 in the simulator, so one threshold does not suit every gas.
Can the MQ-2 measure ppm?
Only roughly. Work out Rs from the reading, divide by your sensor’s R0 and read the gas off the datasheet’s chart. Each sensor’s R0 is different, so it has to be found for yours first.
Can I simulate an MQ-2 gas sensor online?
Yes, in the circuit at the top of this page. The slider on the sensor sets the gas, and the heater warms up as a real one does: one second in, clean air read "A0 = 336 (1642 mV)", and it had sunk to "A0 = 11 (53 mV)" by about 20 seconds.
Keep going
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.