MQ-135 Air Quality Gas Sensor Module
Low-cost analog air-quality sensor for ammonia, NOx, benzene, alcohol, smoke and CO₂ — a relative pollution indicator, not a ppm meter.
- Storage temperature
- −20 °C to +70 °C
Wiring & code for
What is the MQ-135, and when should you use one?
The MQ-135 is the sensor most people reach for when they want to add "air quality" to an Arduino or ESP32 project without spending much. It costs a couple of dollars, needs nothing more than a 5 V supply and one analog pin, and gives you a number that goes up when the air in the room gets worse. That is exactly what it is good at, and it is worth being clear about what that means before you build anything around it.
Inside the metal mesh cap sits a small ceramic tube coated with tin dioxide (SnO₂) and warmed by a tiny heater coil. In clean air the coating has a high electrical resistance. When pollutant gases drift in, they react with oxygen on the hot surface and the coating's resistance falls. The more pollution, the lower the resistance. A load resistor on the module turns that change into a voltage, and that voltage is what comes out of the AO pin.
The manufacturer, Hanwei, designed it for air-quality equipment in homes and offices, and that is the right mental model: the MQ-135 is a relative pollution indicator. It will tell you that the air in your kitchen got worse after cooking, that a room has become stuffy, or that someone opened a bottle of solvent nearby. It will not tell you which gas it was or give you a trustworthy concentration in ppm unless you calibrate it carefully, and even then only as an estimate.
Warning
The MQ-135 cannot tell you which gas is present. Ammonia, benzene, alcohol vapour, smoke and CO₂ all push the reading the same way, and humidity and temperature shift it too. A rising number means "the air is getting worse", not "CO₂ is 1200 ppm". If you need a true CO₂ value, use a dedicated CO₂ sensor such as the SCD40.
Specifications
- Sensing element
- SnO₂ (tin dioxide) metal-oxide semiconductor on an Al₂O₃ ceramic tube, with a Ni-Cr heater coil
- Module type
- 4-pin breakout with LM393 comparator, 10 kΩ trimmer potentiometer, power LED and DO LED
- Supply voltage
- 5 V DC. The heater is specified at 5.0 V ±0.1 V; some module listings quote 2.5–5 V, but a lower voltage changes the sensor's sensitivity, so use 5 V
- Heater current / power
- ~150 mA continuous (≤800 mW); heater resistance 33 Ω ±5%
- Detectable gases
- NH₃ (ammonia), NOx, benzene, alcohol, smoke, CO₂ — broad-spectrum, not selective to any one gas
- Detection range
- 10–300 ppm (NH₃, alcohol) up to 10–1000 ppm (benzene), depending on the gas
- Analog output (AO)
- Voltage that rises with gas concentration, from 0 V up to roughly the supply voltage (datasheets quote 4.2 V to 5 V). Needs a divider for 3.3 V ADCs
- Digital output (DO)
- TTL level (≈0 V / Vcc), threshold set by the onboard pot. Active LOW on most modules: goes LOW and lights the DO LED when gas exceeds the threshold
- First-use burn-in
- At least 24 hours of continuous power (Hanwei datasheet); some sellers recommend 48 hours or more
- Warm-up on every power-up
- Several minutes; stable readings can take 10–15 minutes
- Operating conditions
- −10 °C to +45 °C, below 95 % RH
- Storage temperature
- −20 °C to +70 °C
- Module size
- ≈35 × 22 × 23 mm (L × W × H); varies slightly by manufacturer
- Interface
- 1 analog pin (AO) + 1 digital pin (DO). Raspberry Pi needs an external ADC such as the ADS1115
Pinout
| Pin | Name | Description |
|---|---|---|
| 1 | VCC | 5 V supply. Powers the heater (~150 mA) and the comparator — do not use 3.3 V |
| 2 | GND | Ground |
| 3 | DO | Digital output. Threshold set by the onboard pot; goes LOW (DO LED on) when gas exceeds the threshold on most modules. Output is about 5 V logic |
| 4 | AO | Analog output. Voltage rises as gas concentration rises, up to roughly Vcc. Read with an ADC pin |
Swipe sideways to see every column →
Pin order varies by manufacturer, so read the silkscreen before wiring. The ADIY module is VCC, GND, DO, AO. VCC must be 5 V because it also powers the heater. On a 3.3 V board such as the ESP32, put a voltage divider on AO and level-shift DO, since both can reach about 5 V. Allow warm-up before trusting readings, and treat AO as a relative air-quality trend until you calibrate it in clean air.
Variants
| Variant | Price | Interface | Notes |
|---|---|---|---|
| MQ-135 4-pin module (this page) | ~$1–3 | Analog + digital | Sensor on a breakout with LM393 comparator, trimmer pot and two LEDs. Gives both AO and DO. This is what most makers buy |
| MQ-135 bare sensor (6-pin) | ~$1–2 | Analog (external load resistor) | The raw Hanwei sensor: 4 signal pins and 2 heater pins. You supply the load resistor and wiring, so it is only worth it for custom PCBs |
| SGP30 | ~$8–18 | I2C | Digital I²C TVOC and eCO₂ sensor. No load-resistor maths or analog calibration; the eCO₂ value is still an estimate |
| SCD40 | ~$20–50 | I2C | Measures real CO₂ directly, plus temperature and humidity. Choose it when you need a trustworthy CO₂ number |
Swipe sideways to see every column →
Choose the MQ-135 when you want a cheap relative indicator of general air quality. Choose the SGP30 for digital TVOC/eCO₂ trends without analog calibration, and the SCD40 when you need a real CO₂ measurement — the MQ-135 can only infer CO₂, not measure it.
How the sensor works
Understanding the physics for a minute makes every odd behaviour of this sensor make sense later.
The heater is not optional. Metal-oxide sensors only react to gases when the sensing layer is hot, so the heater runs the whole time the module is powered. That is why the sensor draws around 150 mA, why the cap gets hot, and why the readings are unstable for the first few minutes after power-on: the layer is still reaching its working temperature.
The sensing layer and the load resistor on the module form a voltage divider. When the layer's resistance (Rs) drops because of pollutants, a larger share of the supply voltage appears across the load resistor, and the voltage on the AO pin rises. So the analog output goes up as the air gets worse, even though the sensor's resistance is going down. If you ever wonder why the numbers move the opposite way from the resistance, this is the reason.
The sensor also has no idea what it is looking at. Any gas that reacts on the hot tin-dioxide surface lowers the resistance, which is why one reading represents the combined effect of everything in the air.
What it responds to
Hanwei lists ammonia, NOx, alcohol, benzene, smoke and CO₂ as the target gases. Not all of them affect the sensor equally, and the table gives a practical feel for what you will actually see.
| Gas or vapour | Typical response | Where you will notice it |
|---|---|---|
| Ammonia (NH₃) | High | Cleaning products, pet and animal areas, fertiliser |
| Benzene and similar solvent vapours | High | Paint, glue, varnish, new furniture |
| Alcohol | High | Hand sanitiser, alcohol wipes, spirits |
| NOx | Medium | Combustion and traffic fumes |
| Smoke | Medium | Cooking smoke, incense, burning |
| CO₂ | Low, indirect | Crowded, unventilated rooms |
The CO₂ row deserves a note. The MQ-135 is often sold as a "CO₂ sensor", but it reacts only weakly to CO₂. When code reports a CO₂ value in ppm, it is applying a curve fit and assuming the air is clean apart from CO₂. In a real room, hand sanitiser or cooking fumes will move that number far more than breath will. Use it for a trend, not a measurement.
Some sellers also claim the MQ-135 detects sulfur or hydrogen sulfide. That is not in Hanwei's own list of applications, so do not build anything that depends on it. It is also the wrong tool for LPG or methane leaks (use an MQ-2 or MQ-6) and for carbon monoxide (use an MQ-7).
Getting to know the module
Most MQ-135 boards you can buy are the 4-pin breakout version, and it helps to know what each part is doing.
The metal-capped sensor sits on one end. Next to it is an LM393 comparator, a small chip that compares the sensor's voltage with a threshold and switches the digital output (DO) accordingly. The threshold is set by the blue 10 kΩ trimmer potentiometer. There are two LEDs: a power LED that lights whenever the module has power, and a DO LED that lights when the digital output is triggered. The four pins are VCC, GND, DO and AO.
The digital output is what makes the module useful without a microcontroller. Power it up, adjust the pot, and DO can drive a buzzer, LED or relay through a simple transistor. To set it up, let the module warm up in clean air, then turn the pot with a small screwdriver until the DO LED just switches off. From then on, any rise in pollution turns the LED back on.
One detail trips people up: on this style of module the digital output is active LOW. DO sits HIGH in clean air and goes LOW, with the DO LED lit, when gas passes the threshold. Some datasheets, including parts of the ADIY one, describe it the opposite way in one paragraph and this way in another. Check on your own board, either with a multimeter or by reading the pin in a short sketch, before you write logic that depends on it.
The AO pin is for microcontrollers. It gives a continuous voltage that tracks the gas level, which is what you read with analogRead().
Warm-up and burn-in: the part everyone skips
If you power an MQ-135 for the first time, read it immediately and see a wild, drifting number, nothing is wrong with your wiring. The sensor needs time, and there are two separate waiting periods to understand.
The first is the initial burn-in. A brand-new sensor, or one that has been stored for months, needs to be powered continuously for at least 24 hours before it behaves consistently. This is Hanwei's own figure, and some sellers recommend 48 hours or more. During this period the sensing layer stabilises chemically. Skipping it is the most common reason people say their MQ-135 is "inaccurate".
The second is the warm-up you need every time you power the module on. Different makers quote different times, from 30 seconds to a couple of minutes just to start, up to 10–15 minutes for readings that truly settle. A sensible rule is to ignore the first five minutes and trust the output properly after that.
| Stage | When | How long |
|---|---|---|
| Initial burn-in | Brand-new sensor, or stored for months | At least 24 hours of continuous power (some sellers say 48 hours or more) |
| Warm-up | Every power-up | Several minutes; up to 10–15 minutes for stable readings |
| Calibration | Once after burn-in, then every few weeks | In fresh outdoor air |
Readings in the first minutes after power-on are always high and falling. Do not log them or trigger alarms from them.
Danger
Do not use the MQ-135 as a gas-leak, carbon-monoxide or smoke alarm. It is uncalibrated out of the box, drifts with age, temperature and humidity, and has no safety certification. For anything life-safety related, use a certified detector.
Powering it correctly
The heater needs a proper 5 V supply, and it draws about 150 mA continuously, roughly three-quarters of a watt. An Arduino Uno's 5 V pin handles that comfortably. Some datasheets list the module's operating voltage as 2.5–5 V, but the heater itself is specified at 5.0 V, and running it lower changes the sensor's sensitivity, so treat 5 V as the working voltage.
Because it runs hot, mount it so the cap cannot touch wires, plastic enclosures or fingers. The cap is hot enough to burn skin or soften plastic.
On batteries, the maths is unforgiving: a 2000 mAh cell runs the heater for only about 13 hours. If you are building something battery-powered, switch the sensor's supply with a MOSFET, wake it only when you want a reading, and accept the warm-up time on every wake. For most projects, a wall-powered setup is far more practical.
Warning
Never power the MQ-135 from a 3.3 V pin — the heater needs 5 V. And do not connect AO or DO directly to a 3.3 V-only board (ESP32, Raspberry Pi): both can reach about 5 V. Use a voltage divider (for example 10 kΩ + 20 kΩ) or a level shifter.
Turning raw readings into something useful
There are three levels at which you can use the MQ-135, from simplest to most useful.
The simplest is the raw ADC value. That is fine for watching a trend or catching a spike, but the number differs from module to module, so you cannot compare two sensors directly.
The next level is the Rs/R0 ratio. Here you convert the voltage into the sensor's resistance (Rs) and compare it with a clean-air baseline (R0). This removes most of the differences between modules, and it is a much more meaningful signal: close to 1 in clean air, falling as pollution rises.
The final level is an approximate ppm figure, found by applying a curve fit to that ratio. It is the most appealing number, and also the least reliable.
The conversion itself is two lines:
Vout = ADC ÷ ADC_MAX × Vref
Rs = RL × (Vc − Vout) ÷ Vout
Vc is the module's supply voltage, and RL is the load resistor on the module. RL is not the same on every board: Joy-it documents 1.5 kΩ, while other boards use 1 kΩ or 10 kΩ. Look at the small SMD resistor next to the sensor to find out (102 means 1 kΩ, 103 means 10 kΩ, 152 means 1.5 kΩ).
One more detail: Hanwei defines R0 as the sensor's resistance in 100 ppm of ammonia. Almost nobody has ammonia test gas, so hobby code uses fresh outdoor air as the baseline instead. That works well for trends, which is all this sensor can really offer.
Reading the output and calibrating properly
When the sketch runs, the first thing it prints is the clean-air resistance it measured. After that, every second you get Rs, the Rs/R0 ratio and a CO₂ estimate. In clean air the ratio sits close to 1.00. As pollution rises, Rs falls, the ratio drops below 1, and the estimate climbs. Treat the CO₂ figure as a trend with an error that can easily be hundreds of ppm.
For real projects, the most dependable approach is to log the ratio and set alert levels relative to your own baseline, for example "alert when the ratio drops 30 % below clean air", instead of chasing absolute ppm numbers. Your sensor, your room and your humidity all shape the result, and a relative threshold copes with that far better than a fixed number.
The calibration only takes a few minutes of attention once the sensor has been burned in. Follow these steps:
- 1Power the module from a stable 5 V supply and leave it running for 24 hours on first use (48 hours if it has been stored for months).
- 2Move it to fresh, well-ventilated air, such as outdoors or beside an open window, away from cooking, solvents and people breathing on it.
- 3Wait at least 5–10 minutes after each power-up, until the readings stop falling.
- 4Record the clean-air baseline (Rs, or the raw value) and store it in your code or EEPROM.
- 5Compare later readings against that baseline, and repeat the calibration every few weeks or when you move the sensor to a new location.
- 6Optional: log temperature and humidity alongside it (for example with a BME280 or DHT22) so you can spot drift caused by the weather rather than by pollution.
What affects accuracy
Even a well-calibrated MQ-135 will wander a little, and knowing why saves a lot of confusion.
Temperature and humidity are the biggest factors. The sensor's clean-air resistance changes with both, and Hanwei's datasheet includes a correction curve for exactly this reason. If you pair the sensor with a BME280 or DHT22, you can compensate in software. The sensor is rated for −10 °C to +45 °C and below 95 % RH, so keep it dry and away from condensation.
Age matters too. Metal-oxide sensors drift slowly over months, which is why recalibrating every few weeks is a good habit, and why a sensor that no longer responds at all should simply be replaced.
Finally, remember cross-sensitivity: everything in the response table moves the reading, so a bottle of hand sanitiser on the desk will look like bad air. And keep the sensor away from silicone sealants and sprays, strong corrosive gases and water splashes, all of which can permanently damage metal-oxide sensors.
Troubleshooting
Most MQ-135 problems come down to a short list of causes. Find your symptom below.
| Symptom | Likely cause | Fix |
|---|---|---|
| Reading is very high right after power-on, then falls | Normal warm-up | Wait several minutes and ignore early readings |
| Reading stuck near 0 | AO not connected, wrong pin, or no supply | Check VCC, GND and AO wiring; measure AO with a multimeter |
| Reading stuck near maximum in clean air | New sensor not burned in, or the sensor is contaminated | Burn in for 24 hours or more, then move to fresh air |
| Values drift up and down over hours | Humidity or temperature change, or insufficient burn-in | Burn in longer and log temperature and humidity |
| DO LED always on, or never on | Threshold pot set badly | Warm up in clean air and turn the pot until the LED just switches off |
| Two modules give different numbers | Different load resistors and sensor tolerance | Calibrate each module separately |
| ESP32 readings noisy, or jump when WiFi connects | Using an ADC2 pin | Use an ADC1 pin (GPIO32–39) and average several samples |
| Arduino resets when the sensor powers up | Heater inrush on a weak USB supply | Use a stronger 5 V supply and add a 100–470 µF capacitor across VCC and GND |
| Raspberry Pi has no analog input | The Pi has no ADC | Add an ADS1115 and a voltage divider on AO |
MQ-135 or something else?
The right sensor depends on what you actually want to know. If the goal is a cheap, general "is the air getting worse?" signal, the MQ-135 does that well. If you care about a specific gas, a more specialised sensor will serve you better, and if you need real CO₂ numbers, a purpose-built sensor is the only honest answer.
| Sensor | Best for | Interface | Notes |
|---|---|---|---|
| MQ-135 | General air-quality trend (ammonia, benzene, alcohol, smoke) | Analog + digital | Cheapest option, needs burn-in and calibration |
| MQ-2 | LPG, methane, hydrogen and smoke | Analog + digital | Better for combustible-gas and smoke detection |
| MQ-7 | Carbon monoxide | Analog + digital | Works best with an alternating heater voltage |
| MQ-3 | Alcohol | Analog + digital | Tuned for alcohol vapour |
| SGP30 | TVOC and eCO₂ trends | I²C | Digital, no analog calibration; eCO₂ is an estimate |
| SCD40 | Real CO₂ measurement | I²C | Measures CO₂ directly, with temperature and humidity |
Project ideas
Once the sensor is burned in and calibrated, it fits naturally into a few popular builds.
WiFi air-quality dashboard. Read the sensor on an ESP32, add a BME280 for temperature and humidity, and publish the values over MQTT to Home Assistant or a simple web page. Plotting the Rs/R0 ratio over a day shows cooking, ventilation and occupancy patterns clearly.
Automatic ventilation. Use the ratio, or the DO output, to switch an exhaust fan through a relay when the air gets stale. Add some hysteresis so the fan does not flick on and off around the threshold.
Standalone alarm with no microcontroller. Set the pot, then use the DO pin with a transistor to drive a buzzer or LED. It is crude, but it works as a simple "air has gone bad" indicator in a workshop or kitchen.
Indoor-air comparison. Log readings in different rooms, or before and after opening a window, to see how much ventilation really changes things. This is also an easy way to learn why calibration and baselines matter.
Frequently asked questions
Can the MQ-135 measure CO₂? Only indirectly. It reacts weakly to CO₂ and strongly to other gases, so a CO₂ ppm figure from MQ-135 code is a curve-fit estimate that assumes clean air with one dominant gas. Use it as a trend, or choose an SCD40 for real CO₂ readings.
Can it detect LPG, methane or smoke from a fire? Not reliably, and never for safety. Use an MQ-2 or MQ-6 for hobby experiments with combustible gas, and a certified alarm for real protection.
Why do I get different numbers from a commercial air-quality monitor? Commercial monitors use calibrated sensors for specific gases. The MQ-135 measures overall pollutant load, so the two are not directly comparable.
Do I need to leave it powered all the time? For the best stability, yes. Every power cycle brings a warm-up period, which is why continuous operation gives the most consistent readings.
Can I use it with ESP32, ESP8266 or Raspberry Pi? Yes, with care. Power the heater from 5 V, use a divider on AO, and for a Raspberry Pi add an external ADC such as the ADS1115.
How long does it last? Metal-oxide sensors typically last for years of indoor use, but sensitivity drifts over time, so re-calibrate every few weeks and replace it if readings no longer respond.