MQ-2 là sensor khí bán dẫn dùng vật liệu SnO₂ (thiếc dioxide) để phát hiện các khí dễ cháy: LPG, propane, methane, khói, hydrogen, và hơi xăng. Nguyên lý đơn giản nhưng đặc tính phi tuyến đòi hỏi hiệu chỉnh đúng cách. Bài này phân tích sâu từ datasheet Hanwei Electronics, bao gồm mạch heater, đường cong Rs/Ro, và cách tính nồng độ ppm thực tế.
Nguyên Lý Hoạt Động
1. Vật Liệu SnO₂ Và Hiệu Ứng Nhạy Khí
MQ-2 dùng lớp bột SnO₂ (Tin Dioxide) nung kết lên substrate nhôm oxide (Al₂O₃) có kết cấu dạng mạng tinh thể đa tinh thể.
Tại sao SnO₂ nhạy với khí?
Trạng thái không khí sạch:
O₂ từ không khí ──→ Hấp phụ lên bề mặt SnO₂
O₂ + e⁻(từ SnO₂) → O₂⁻ (ion oxy bề mặt)
Điện tử SnO₂ bị "bắt" → Vùng nghèo điện tử → Điện trở CAO (Rs cao)
Khi có khí dễ cháy (VD: LPG, H₂):
Khí khử + O₂⁻ → CO₂ + H₂O + e⁻ (điện tử giải phóng lại)
Điện tử trả về SnO₂ → Thu hẹp vùng nghèo → Điện trở THẤP (Rs thấp)
Phản ứng ví dụ với CH₄ (methane):
CH₄ + 4O₂⁻ → CO₂ + 2H₂O + 4e⁻
Kết quả: Nồng độ khí tăng → điện trở Rs giảm → AOUT giảm.
Tại sao cần heater?
SnO₂ chỉ hoạt động đủ nhạy ở nhiệt độ cao (~200°C – 300°C). Ở nhiệt độ phòng, phản ứng bề mặt quá chậm. MQ-2 tích hợp cuộn dây Ni-Cr (nickel-chromium) làm heater để duy trì nhiệt độ hoạt động trong sensor.
2. Cấu Trúc Vật Lý Bên Trong MQ-2
[Vỏ kim loại lưới đôi — Steel mesh]
↓
┌─────────────────────┐
│ Substrate Al₂O₃ │← Đế gốm
│ ┌───────────────┐ │
│ │ SnO₂ layer │ │← Lớp vật liệu nhạy khí
│ └───────────────┘ │
│ [Heater coil] │← Cuộn dây Ni-Cr (5V ~900mA)
└─────────────────────┘
↑
6 chân ra ngoài (A, B, H — mỗi bên 3 chân song song)
Vỏ lưới thép đôi: Cho khí lọt vào nhưng ngăn lửa bùng ra ngoài (flashback protection) nếu có khí bắt cháy bên trong sensor.
3. Mạch Đo — Voltage Divider Với R_L
Bên trong (hoặc trên module):
VCC (5V)
│
Rs (điện trở sensor SnO₂ — thay đổi)
│
├──── AOUT (đọc điện áp này)
│
R_L (điện trở tải — cố định, thường 10kΩ trên module)
│
GND
Điện áp AOUT = VCC × RL / (Rs + RL)
- Không khí sạch → Rs lớn → AOUT thấp
- Có khí → Rs nhỏ → AOUT tăng
Lưu ý: Logic này ngược với soil moisture — ở MQ-2, AOUT cao = có nhiều khí.
4. Đường Cong Rs/Ro — Đặc Tính Phi Tuyến Log-Log
Datasheet MQ-2 của Hanwei cung cấp đồ thị đường cong Rs/Ro vs ppm cho từng loại khí trên thang log-log.
Trục Y (log): Rs/Ro (tỷ lệ điện trở)
Trục X (log): Nồng độ (ppm)
Rs = Điện trở sensor tại nồng độ khí hiện tại
Ro = Điện trở sensor trong không khí sạch (calibration point)
Ví dụ LPG từ đường cong (ước tính):
1000ppm → Rs/Ro ≈ 0.6
5000ppm → Rs/Ro ≈ 0.25
10000ppm → Rs/Ro ≈ 0.16
Công thức tính ppm (từ đường cong power-law trên log-log):
ppm = a × (Rs/Ro)^b
Trong đó a và b là hệ số đường thẳng trên đồ thị log-log.
Ví dụ LPG (ước tính từ đồ thị MQ-2 datasheet):
- a ≈ 574.25
- b ≈ -2.222
Calibrate Ro: Đo Rs trong không khí sạch sau khi heater đã nóng đủ (>24h):
Ro = Rs_measured / 9.83
(9.83 là tỷ lệ Rs/Ro trong không khí sạch theo datasheet MQ-2)
Thông Số Kỹ Thuật
| Thông số | Giá trị |
|---|---|
| Điện áp mạch sensor (Vc) | 5V DC ± 0.1V |
| Điện áp heater (Vh) | 5V DC ± 0.1V |
| Công suất heater | ~800mW (dòng ~160mA @ 5V) |
| Dòng toàn module | ≈170–200mA @ 5V |
| Điện trở tải R_L (module) | 10kΩ (thường) |
| Điện trở sensor Rs (không khí) | 3kΩ – 30kΩ |
| Thời gian preheat | ≥24 giờ (lần đầu dùng) |
| Thời gian làm nóng (bật lại) | ≥20 phút |
| Phạm vi phát hiện | 300 – 10,000 ppm (LPG, CO) |
| Nhiệt độ hoạt động | -10°C – 50°C |
| Độ ẩm tối đa | ≤95% RH |
QUAN TRỌNG — Heater cần 5V, dòng cao:
- Không kết nối module MQ-2 với nguồn 3.3V → heater không đủ nóng → đọc sai
- ESP32 chạy 3.3V → phải cấp 5V riêng cho module, GND chung với ESP32
- Dòng 170–200mA: không lấy từ pin 3V3 của ESP32/Arduino → nguồn ngoài hoặc USB 5V
Sơ Đồ Chân (Pinout)
Chip MQ-2 (6 chân — không dùng trực tiếp)
Nhìn từ trên:
A ─────── B
A ─────── B ← A và B là cặp tương ứng song song
H ─────── H ← H là heater
A: Sensor output (một đầu SnO₂)
B: Sensor output (đầu kia SnO₂) — nối với R_L
H: Heater (2 chân, cấp 5V)
Module MQ-2 (4 chân — dùng phổ biến)
┌──────────────────────┐
│ [MQ-2 sensor] │
│ [LED] [Triết áp] │
│ LM393 Comparator │
└──────────────────────┘
VCC GND DOUT AOUT
| Chân | Chức năng |
|---|---|
| VCC | 5V (bắt buộc — không dùng 3.3V) |
| GND | Đất |
| DOUT | Digital: LOW khi nồng độ vượt ngưỡng (LM393) |
| AOUT | Analog: điện áp tỷ lệ với nồng độ khí |
So Sánh MQ Series
| Model | Khí phát hiện chính | Ro (không khí sạch) | Ứng dụng |
|---|---|---|---|
| MQ-2 | LPG, Smoke, H₂, Propane, CO | 3kΩ–30kΩ | Đa dụng — khí dễ cháy |
| MQ-3 | Hơi cồn (ethanol) | ~100kΩ | Phát hiện say rượu |
| MQ-4 | Methane (CH₄) tự nhiên | ~10kΩ | Gas tự nhiên (CNG) |
| MQ-5 | LPG, Natural Gas | ~35kΩ | Gas bếp |
| MQ-6 | LPG, Isobutane, Propane | ~30kΩ | Bình gas nhà bếp |
| MQ-7 | CO (Carbon monoxide) | ~10kΩ | Khí CO nguy hiểm |
| MQ-9 | CO + Gas dễ cháy | — | Đa dụng CO + gas |
| MQ-135 | NH₃, NOx, CO₂, Benzene | ~76.63kΩ | Chất lượng không khí |
Chọn MQ nào:
- Gas bếp/LPG → MQ-2 hoặc MQ-6
- Gas tự nhiên (CNG, methane) → MQ-4
- CO nguy hiểm (phòng ngủ, xe hơi) → MQ-7
- Chất lượng không khí (IAQ) → MQ-135
Kết Nối Phần Cứng
Kết Nối với ESP32 DevKit V1
MQ-2 cần 5V — ESP32 chạy 3.3V logic nhưng có chân VIN/5V:
Nguồn USB 5V
│
├──── Module MQ-2 VCC (5V — không qua ESP32 3V3 pin)
│
ESP32 DevKit V1 MQ-2 Module
───────────────────── ─────────────────
GND ───────────────────→ GND (GND chung)
GPIO32 (ADC1_CH4) ──────→ AOUT (3.3V logic OK — AOUT < 1V khi gas thấp)
GPIO25 (Input) ─────────→ DOUT (3.3V logic OK — LM393 open collector)
Tại sao GPIO cần 3.3V logic từ AOUT (module 5V): AOUT = VCC × RL / (Rs + RL) = 5V × 10kΩ / (Rs + 10kΩ)
- Khi Rs rất lớn (không khí sạch): AOUT ≈ 0.1–0.3V (an toàn cho GPIO 3.3V)
- Khi Rs nhỏ (nhiều gas): AOUT ≈ 1–2V (vẫn an toàn, dưới 3.3V)
- Trong trường hợp cực đoan AOUT có thể lên 3-4V → nguy hiểm cho ESP32 GPIO
An toàn nhất: Dùng voltage divider (100kΩ + 200kΩ) để hạ AOUT xuống 2/3 điện áp, hoặc dùng mạch level shifter trước khi nối vào ESP32.
Kết Nối với Arduino Uno
Arduino Uno 5V — tương thích trực tiếp với module MQ-2:
Arduino Uno MQ-2 Module
───────────────────── ─────────────────────
5V ────────────────────→ VCC (5V — an toàn)
GND ────────────────────→ GND
A0 (Analog) ────────────→ AOUT
Pin 7 (Input) ──────────→ DOUT
Arduino Uno 5V logic hoàn toàn tương thích với module MQ-2 5V — đây là setup dễ nhất.
Code Arduino IDE
Code Khởi Động — Chờ Heater Nóng (Arduino Uno & ESP32)
/*
* MQ-2 — Chờ heater nóng trước khi đọc
* QUAN TRỌNG: Lần đầu dùng phải chờ >=24 giờ để heater ổn định!
* Mỗi lần bật lại: chờ tối thiểu 20 phút
*/
void waitForPreheat(int minutes) {
Serial.print("Đang làm nóng MQ-2...");
for (int i = 0; i < minutes; i++) {
Serial.print(i);
Serial.print("phút ");
delay(60000); // 1 phút
}
Serial.println("Sẵn sàng!");
}
Code Đọc Đơn Giản — Arduino Uno
/*
* MQ-2 Gas Sensor — Phát hiện khí dễ cháy
* Board: Arduino Uno
* Kết nối: VCC→5V, GND→GND, AOUT→A0, DOUT→Pin7
*
* LƯU Ý: Chạy lần đầu cần preheat 24 giờ!
* Sau đó mỗi lần bật: preheat 20 phút trước khi tin kết quả
*/
const int ANALOG_PIN = A0;
const int DIGITAL_PIN = 7;
// Giá trị Ro — calibrate trong không khí sạch sau preheat đầy đủ
// Thay thế bằng giá trị thực sau khi chạy code calibration
float Ro = 10.0; // kΩ — ước tính ban đầu, cần calibrate!
// Hệ số đường cong cho LPG (từ đồ thị datasheet MQ-2 — ước tính)
// Các khí khác có hệ số khác nhau
const float LPG_A = 574.25;
const float LPG_B = -2.222;
// Điện trở tải trên module (thông thường 10kΩ)
const float RL = 10.0; // kΩ
void setup() {
Serial.begin(9600);
pinMode(DIGITAL_PIN, INPUT);
Serial.println("=== MQ-2 Gas Sensor - Arduino Uno ===");
Serial.println("CHÚ Ý: Chờ sensor nóng ít nhất 20 phút!");
Serial.println("Lần đầu dùng: 24 giờ!");
}
// Tính điện trở sensor Rs từ điện áp analog
float calcRs(int analogRaw) {
// Điện áp tại AOUT
float voltage = (float)analogRaw / 1023.0 * 5.0; // Arduino Uno: 5V ref
// Tính Rs từ voltage divider: voltage = VCC * RL / (Rs + RL)
// Rs = RL * (VCC / voltage - 1)
if (voltage == 0) return 0;
float rs = RL * (5.0 / voltage - 1.0);
return rs;
}
// Tính ppm từ Rs/Ro và hệ số đường cong
float calcPPM(float rs, float ro, float a, float b) {
if (ro <= 0) return -1;
float ratio = rs / ro;
return a * pow(ratio, b);
}
void loop() {
int analogValue = analogRead(ANALOG_PIN);
int digitalValue = digitalRead(DIGITAL_PIN);
float rs = calcRs(analogValue);
float ppm = calcPPM(rs, Ro, LPG_A, LPG_B);
Serial.print("ADC: "); Serial.print(analogValue);
Serial.print(" | Rs: "); Serial.print(rs, 2); Serial.print("kΩ");
Serial.print(" | Rs/Ro: "); Serial.print(rs / Ro, 3);
Serial.print(" | ~LPG: "); Serial.print(ppm, 0); Serial.print("ppm");
Serial.print(" | Digital: ");
// DOUT HIGH = có khí vượt ngưỡng (logic thuận với MQ, khác rain sensor)
Serial.println(digitalValue == HIGH ? "KHÍ PHÁT HIỆN!" : "An toàn");
// Cảnh báo nếu ppm cao
if (ppm > 1000) {
Serial.println("!!! CẢNH BÁO: Nồng độ cao !!!");
}
delay(2000);
}
Code Với Calibration Ro — ESP32
/*
* MQ-2 — Calibration Ro + Đọc nồng độ LPG
* Board: ESP32 DevKit V1
* Kết nối: VCC→5V riêng, GND→GND chung, AOUT→GPIO32 (ADC1), DOUT→GPIO25
*
* ESP32: AOUT từ module 5V có thể >3.3V → thêm voltage divider 100k/200k
* Hoặc nối thẳng nếu ổn định sensor đã cấu hình < 3.3V
*
* Quy trình calibration:
* 1. Đặt sensor nơi không khí sạch (ngoài trời hoặc phòng thông gió)
* 2. Bật nguồn, chờ 20 phút (hoặc 24h lần đầu)
* 3. Đọc giá trị Ro từ Serial Monitor
* 4. Điền Ro vào code chính
*/
const int ANALOG_PIN = 32; // ADC1_CH4
const int DIGITAL_PIN = 25;
const float RL = 10.0; // kΩ — điện trở tải module
const float CLEAN_AIR_RATIO = 9.83; // Rs/Ro trong không khí sạch (từ datasheet MQ-2)
// Hệ số LPG (ước tính từ đồ thị MQ-2 datasheet — log-log power law)
const float LPG_A = 574.25;
const float LPG_B = -2.222;
// Ro — đặt sau khi calibrate; 10.0 là ước tính mặc định
float Ro = 10.0;
bool calibrated = false;
void setup() {
Serial.begin(115200);
analogSetAttenuation(ADC_11db); // Đọc 0-3.3V (cần voltage divider nếu AOUT >3.3V)
analogReadResolution(12); // 12-bit: 0-4095
Serial.println("=== MQ-2 Gas Sensor - ESP32 ===");
Serial.println("Chờ preheat... (20 phút hoặc 24h lần đầu)");
Serial.println("Nhập 'C' vào Serial để bắt đầu calibration sau khi nóng đủ");
}
float calcRs(int rawADC) {
// ESP32 dùng voltage divider 100k/200k nên điện áp thực = rawVoltage * 3/2
// Nếu không có divider: voltage = rawADC / 4095.0 * 3.3
float voltage = (float)rawADC / 4095.0 * 3.3;
// Nếu có voltage divider 100k+200k: thực ra cần nhân 3/2 nhưng
// để đơn giản, tính Rs từ điện áp đọc được (với sai số nếu >3.3V)
if (voltage <= 0) return 0;
// Tính Rs giả định VCC module = 5V
// Rs = RL * (VCC/Vout - 1), nhưng Vout đo tại đây có thể bị scale
// Với voltage divider 1:2: thực Vout = voltage * 2/3 * (5/3.3) ≈ voltage * 1.01
// Để đơn giản: sử dụng 5V và voltage đọc
float rs = RL * (5.0 / (voltage * (5.0 / 3.3)) - 1.0);
return rs;
}
void calibrateRo() {
Serial.println("Đang calibrate Ro trong không khí sạch...");
float rsSum = 0;
for (int i = 0; i < 50; i++) {
int raw = analogRead(ANALOG_PIN);
rsSum += calcRs(raw);
delay(200);
}
float rsAvg = rsSum / 50.0;
Ro = rsAvg / CLEAN_AIR_RATIO; // Ro = Rs_clean / 9.83
Serial.printf("Rs trung bình (không khí sạch): %.2f kΩ\n", rsAvg);
Serial.printf("Ro = %.2f kΩ → Điền giá trị này vào biến Ro!\n", Ro);
calibrated = true;
}
void loop() {
// Nhận lệnh calibration từ Serial
if (Serial.available()) {
char c = Serial.read();
if (c == 'C' || c == 'c') {
calibrateRo();
}
}
int rawADC = analogRead(ANALOG_PIN);
float rs = calcRs(rawADC);
float ratio = rs / Ro;
float ppmLPG = LPG_A * pow(ratio, LPG_B);
ppmLPG = constrain(ppmLPG, 0, 50000); // Giới hạn kết quả hợp lý
int digitalVal = digitalRead(DIGITAL_PIN);
Serial.printf("ADC:%4d Rs:%.2fkΩ Rs/Ro:%.3f ~LPG:%5.0fppm %s\n",
rawADC, rs, ratio, ppmLPG,
digitalVal == HIGH ? "⚠ KHÍ!" : "OK"
);
if (!calibrated) {
Serial.println(" [Nhập 'C' để calibrate Ro sau khi sensor đủ nóng]");
}
delay(2000);
}
Kết Quả Mong Đợi (Sau Calibration)
=== MQ-2 Gas Sensor - ESP32 ===
Đang calibrate Ro trong không khí sạch...
Rs trung bình (không khí sạch): 98.30 kΩ
Ro = 10.00 kΩ → Điền giá trị này vào biến Ro!
ADC:1205 Rs:98.50kΩ Rs/Ro:9.850 ~LPG: 41ppm OK
ADC:1198 Rs:99.20kΩ Rs/Ro:9.920 ~LPG: 38ppm OK
[Bật bật lửa gần sensor]
ADC:2850 Rs:25.00kΩ Rs/Ro:2.500 ~LPG: 1850ppm ⚠ KHÍ!
Ứng Dụng Thực Tế
| Ứng dụng | Chi tiết |
|---|---|
| Cảnh báo rò gas bếp | Đặt gần bếp gas, cảnh báo khi LPG > 1000ppm |
| Detector khói | Nhận biết hơi từ đám cháy (propane, hydrocacbon) |
| Hệ thống thông gió tự động | Bật quạt khi phát hiện khí > ngưỡng |
| Giám sát không khí nhà kho | Kết hợp MQTT + dashboard |
| Thiết bị phòng cháy nổ | Cắt nguồn gas tự động qua relay |
Lưu Ý Khi Sử Dụng
1. Bắt buộc preheat — không đọc ngay sau khi cấp điện
MQ-2 cần 20–30 phút để heater đạt nhiệt độ ổn định. Lần đầu tiên dùng: ≥24 giờ để lớp SnO₂ “điều hòa” (conditioning). Nếu đọc khi chưa nóng đủ → kết quả sai hoàn toàn, thường báo gas cao giả.
2. Heater cần 5V — dòng cao
Module MQ-2 tiêu thụ ~170–200mA từ nguồn 5V. Không lấy từ pin 3V3 của ESP32 (chỉ chịu 50–150mA). Không dùng 3.3V cho module → heater không đủ nóng → nhạy kém. Cấp 5V riêng từ USB hoặc nguồn adapter.
3. AOUT có thể vượt 3.3V khi nồng độ gas cao
Với module 5V, AOUT = 5V × RL / (Rs + RL). Khi Rs rất nhỏ (gas đậm đặc), AOUT có thể lên 3–4V → vượt ngưỡng an toàn GPIO ESP32 (3.3V). Nên dùng voltage divider (2 điện trở) hạ AOUT xuống 2/3 trước khi nối ESP32.
4. Calibration Ro là bắt buộc cho kết quả ppm chính xác
Mỗi sensor MQ-2 có Ro khác nhau (sai số sản xuất ±20%). Không calibrate → ppm sai 2-5 lần. Calibrate bằng cách đo Rs trong không khí sạch sau preheat đầy đủ, chia cho 9.83 (từ datasheet) để ra Ro.
5. Sensor nhạy cảm với nhiệt độ và độ ẩm
Nhiệt độ và độ ẩm ảnh hưởng đến điện trở SnO₂. Datasheet MQ-2 cung cấp hệ số bù nhiệt độ/độ ẩm, nhưng trong ứng dụng đơn giản thường bỏ qua. Để chính xác cao: kết hợp với DHT22 để bù nhiệt độ/độ ẩm trong công thức.
6. Không dùng để đo CO chính xác
MQ-2 có thể phát hiện CO nhưng đường cong nhạy với CO không tuyến tính và bị nhiễu bởi các khí khác. Để đo CO an toàn (phòng ngủ, xe hơi) → dùng MQ-7 chuyên biệt.


