Complete guide to gas detection with MQ series sensors
MQ sensors are semiconductor gas sensors that detect various gases by changes in resistance of the sensing material when exposed to target gases.
| Sensor | Detects | Detection Range | Heater Voltage | Load Resistance | Preheat Time |
|---|---|---|---|---|---|
| MQ-2 | LPG, Propane, Hydrogen, Smoke | 300-10000ppm | 5V±0.1V | 20KΩ | 24+ hours |
| MQ-3 | Alcohol, Ethanol, Benzine | 25-500ppm | 5V±0.1V | 200KΩ | 24+ hours |
| MQ-4 | Methane, Natural Gas | 200-10000ppm | 5V±0.1V | 20KΩ | 24+ hours |
| MQ-5 | Natural Gas, LPG, Coal Gas | 200-10000ppm | 5V±0.1V | 20KΩ (adjustable) | 48+ hours |
| MQ-6 | LPG, Butane, Propane | 200-10000ppm | 5V±0.1V | 10KΩ | 24+ hours |
| MQ-7 | Carbon Monoxide | 20-2000ppm | 5V±0.1V | 10KΩ | 48+ hours |
| MQ-8 | Hydrogen Gas | 100-10000ppm | 5V±0.1V | 10KΩ | 48+ hours |
| MQ-9 | CO, Combustible Gases | 10-1000ppm CO 100-10000ppm Comb. |
5V±0.1V | 10KΩ | 48+ hours |
| MQ-135 | Air Quality (NH3, NOx, CO2) | 10-300ppm NH3 10-1000ppm CO2 |
5V±0.1V | 20KΩ | 24+ hours |
| MQ-136 | Hydrogen Sulfide | 1-200ppm | 5V±0.1V | 20KΩ | 48+ hours |
| MQ-137 | Ammonia | 5-500ppm | 5V±0.1V | 20KΩ | 48+ hours |
| MQ-138 | Benzene, Toluene, Alcohol | 1-200ppm | 5V±0.1V | 20KΩ | 48+ hours |
Unified library for all MQ sensors with calibration functions
// Library initialization
#include <MQUnifiedsensor.h>
// Setup for MQ-135
MQUnifiedsensor MQ135("Arduino UNO", 5.0, 10, A0, "MQ-135");
void setup() {
Serial.begin(9600);
MQ135.init();
MQ135.setRegressionMethod(1); //_PPM = a*ratio^b
MQ135.setA(110.47); MQ135.setB(-2.862); // CO2 curve
MQ135.setR0(11.82); // Found during calibration
}
void loop() {
MQ135.update();
float CO2 = MQ135.readSensor();
Serial.print("CO2: "); Serial.print(CO2); Serial.println(" ppm");
delay(500);
}
// R0 Calibration for MQ Sensors
void setup() {
Serial.begin(9600);
MQ135.init();
Serial.println("Calibrating please wait.");
float calcR0 = 0;
for(int i = 1; i<=10; i++) {
MQ135.update();
calcR0 += MQ135.calibrate(3.6); // 3.6 for clean air
Serial.print(".");
}
MQ135.setR0(calcR0/10);
Serial.println("Calibration done!");
Serial.print("R0 = "); Serial.println(MQ135.getR0());
}
// Basic MQ-2 Gas Sensor Example
#define MQ2_PIN A0
void setup() {
Serial.begin(9600);
pinMode(MQ2_PIN, INPUT);
}
void loop() {
int sensorValue = analogRead(MQ2_PIN);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.print("Raw ADC: "); Serial.print(sensorValue);
Serial.print(" | Voltage: "); Serial.print(voltage);
Serial.println("V");
if(sensorValue > 300) { // Threshold value
Serial.println("Gas detected!");
}
delay(1000);
}
// ESP32 MQ-135 Web Server
#include <WiFi.h>
#include <MQUnifiedsensor.h>
#define BOARD "ESP32"
#define PIN_MQ135 34
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
MQUnifiedsensor MQ135(BOARD, 3.3, 12, PIN_MQ135, "MQ-135");
WiFiServer server(80);
void setup() {
Serial.begin(115200);
MQ135.init();
MQ135.setRegressionMethod(1);
MQ135.setA(110.47); MQ135.setB(-2.862); // CO2 curve
MQ135.setR0(9.03); // Calibrated value
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
server.begin();
Serial.println("Server started at " + WiFi.localIP());
}
void loop() {
MQ135.update();
float co2 = MQ135.readSensor();
WiFiClient client = server.available();
if (client) {
String html = "<html><body>";
html += "<h1>Air Quality Monitor</h1>";
html += "<p>CO2: " + String(co2) + " ppm</p>";
html += "</body></html>";
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println(html);
client.stop();
}
delay(2000);
}
// MQ-135 with DHT22 for temp/humidity compensation
#include <MQUnifiedsensor.h>
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#define MQ135_PIN A0
DHT dht(DHTPIN, DHTTYPE);
MQUnifiedsensor MQ135("Arduino UNO", 5.0, 10, MQ135_PIN, "MQ-135");
void setup() {
Serial.begin(9600);
dht.begin();
MQ135.init();
MQ135.setRegressionMethod(1);
MQ135.setA(110.47); MQ135.setB(-2.862);
MQ135.setR0(11.82);
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed DHT read!");
return;
}
MQ135.update();
MQ135.setTempHumidCorrection(t, h); // Apply compensation
float co2 = MQ135.readSensor();
Serial.print("Temp: "); Serial.print(t); Serial.print("°C | ");
Serial.print("Humidity: "); Serial.print(h); Serial.print("% | ");
Serial.print("CO2: "); Serial.print(co2); Serial.println(" ppm");
delay(2000);
}
Combine MQ-135 with ESP8266 to create a WiFi-enabled air quality monitor that sends data to the cloud.
Use MQ-4/MQ-6 with alarm buzzer and GSM module to send SMS alerts when gas leaks are detected.
Create a portable breathalyzer using MQ-3 sensor with OLED display and battery power.
Combine MQ-2 (gas/smoke) and MQ-7 (CO) with automatic exhaust fan control.
Monitor CO2 (MQ-135), humidity (DHT22), and temperature for optimal plant growth.
Use MQ-9 and MQ-135 to monitor in-car air quality with automatic window control.
// Components needed:
- MQ-2 (LPG/Smoke)
- MQ-7 (CO)
- MQ-135 (Air Quality)
- ESP32
- SD Card Module
- OLED Display
- Buzzer
- 18650 Battery
// Features:
1. Real-time monitoring of multiple gases
2. Data logging to SD card
3. Threshold-based audible alarms
4. Battery level monitoring
5. WiFi data upload option
6. OLED display for local readings
// Implementation Tips:
- Use FreeRTOS on ESP32 to handle:
- Sensor readings
- Data logging
- Display updates
- WiFi communication
- Implement deep sleep between readings for battery life
- Create CSV files on SD card with timestamped data
- Add calibration mode with button input
| Mistake | Consequence | Solution |
|---|---|---|
| Skipping preheat | Inaccurate readings | Always preheat for 24-48 hours initially |
| No warm-up time | Fluctuating values | Wait 2-3 minutes after power on |
| Ignoring environmental factors | False readings | Compensate for temp/humidity |
| Poor ventilation | Slow response time | Ensure proper airflow to sensor |
| Using unstable power | Inconsistent operation | Use regulated power supply |