IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Series 37 Module Cảm Biến – Nguyên Lý Hoạt Động MQ-2: Semiconductor SnO₂, Đường Cong Nhạy Khí & Đo Nồng Độ Gas

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ện300 – 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ânChức năng
VCC5V (bắt buộc — không dùng 3.3V)
GNDĐất
DOUTDigital: LOW khi nồng độ vượt ngưỡng (LM393)
AOUTAnalog: điện áp tỷ lệ với nồng độ khí

So Sánh MQ Series

ModelKhí phát hiện chínhRo (không khí sạch)Ứng dụng
MQ-2LPG, Smoke, H₂, Propane, CO3kΩ–30kΩĐa dụng — khí dễ cháy
MQ-3Hơi cồn (ethanol)~100kΩPhát hiện say rượu
MQ-4Methane (CH₄) tự nhiên~10kΩGas tự nhiên (CNG)
MQ-5LPG, Natural Gas~35kΩGas bếp
MQ-6LPG, Isobutane, Propane~30kΩBình gas nhà bếp
MQ-7CO (Carbon monoxide)~10kΩKhí CO nguy hiểm
MQ-9CO + Gas dễ cháyĐa dụng CO + gas
MQ-135NH₃, 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ụngChi 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óiNhận biết hơi từ đám cháy (propane, hydrocacbon)
Hệ thống thông gió tự độngBật quạt khi phát hiện khí > ngưỡng
Giám sát không khí nhà khoKế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.

Bài tiếp theo: