Skip to content
MQ-135

Gas & Air Quality

Interfacing MQ-135 Gas & Air Quality with Arduino Uno

What is the MQ-135?

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

PinNameDescription
1VCC5 V supply. Powers the heater (~150 mA) and the comparator — do not use 3.3 V
2GNDGround
3DODigital 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
4AOAnalog 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

VariantPriceInterfaceNotes
MQ-135 4-pin module (this page)~$1–3Analog + digitalSensor 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–2Analog (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–18I2CDigital I²C TVOC and eCO₂ sensor. No load-resistor maths or analog calibration; the eCO₂ value is still an estimate
SCD40~$20–50I2CMeasures 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 vapourTypical responseWhere you will notice it
Ammonia (NH₃)HighCleaning products, pet and animal areas, fertiliser
Benzene and similar solvent vapoursHighPaint, glue, varnish, new furniture
AlcoholHighHand sanitiser, alcohol wipes, spirits
NOxMediumCombustion and traffic fumes
SmokeMediumCooking smoke, incense, burning
CO₂Low, indirectCrowded, 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.

StageWhenHow long
Initial burn-inBrand-new sensor, or stored for monthsAt least 24 hours of continuous power (some sellers say 48 hours or more)
Warm-upEvery power-upSeveral minutes; up to 10–15 minutes for stable readings
CalibrationOnce after burn-in, then every few weeksIn 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.

C++

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:

  1. 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).
  2. 2Move it to fresh, well-ventilated air, such as outdoors or beside an open window, away from cooking, solvents and people breathing on it.
  3. 3Wait at least 5–10 minutes after each power-up, until the readings stop falling.
  4. 4Record the clean-air baseline (Rs, or the raw value) and store it in your code or EEPROM.
  5. 5Compare later readings against that baseline, and repeat the calibration every few weeks or when you move the sensor to a new location.
  6. 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.

SymptomLikely causeFix
Reading is very high right after power-on, then fallsNormal warm-upWait several minutes and ignore early readings
Reading stuck near 0AO not connected, wrong pin, or no supplyCheck VCC, GND and AO wiring; measure AO with a multimeter
Reading stuck near maximum in clean airNew sensor not burned in, or the sensor is contaminatedBurn in for 24 hours or more, then move to fresh air
Values drift up and down over hoursHumidity or temperature change, or insufficient burn-inBurn in longer and log temperature and humidity
DO LED always on, or never onThreshold pot set badlyWarm up in clean air and turn the pot until the LED just switches off
Two modules give different numbersDifferent load resistors and sensor toleranceCalibrate each module separately
ESP32 readings noisy, or jump when WiFi connectsUsing an ADC2 pinUse an ADC1 pin (GPIO32–39) and average several samples
Arduino resets when the sensor powers upHeater inrush on a weak USB supplyUse a stronger 5 V supply and add a 100–470 µF capacitor across VCC and GND
Raspberry Pi has no analog inputThe Pi has no ADCAdd 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.

SensorBest forInterfaceNotes
MQ-135General air-quality trend (ammonia, benzene, alcohol, smoke)Analog + digitalCheapest option, needs burn-in and calibration
MQ-2LPG, methane, hydrogen and smokeAnalog + digitalBetter for combustible-gas and smoke detection
MQ-7Carbon monoxideAnalog + digitalWorks best with an alternating heater voltage
MQ-3AlcoholAnalog + digitalTuned for alcohol vapour
SGP30TVOC and eCO₂ trendsI²CDigital, no analog calibration; eCO₂ is an estimate
SCD40Real CO₂ measurementI²CMeasures 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.

Setting Up MQ-135 with Arduino Uno

Library

—

No library required — this sensor outputs a plain analog voltage

Wiring

Component pinArduino Uno pinNote
VCC5VHeater draws ~150 mA — fine from the Uno's 5 V pin
GNDGND
AOA0Analog output — relative air-quality value, not ppm (calibrate in clean air)
DOD2Optional threshold output — goes LOW when gas exceeds the pot setting on most modules

Swipe sideways to see every column →

C++

First use needs at least 24 hours of continuous power to burn in (some sellers recommend 48 hours or more), and every power-up needs a few minutes of warm-up. The raw 0–1023 value is not ppm. It is a relative trend until you calibrate against clean air. The calibration sketch on this page converts it to Rs/R0 and an approximate CO₂ estimate.

Related Components

Related Guides & Projects