Báo rò rỉ gas / khói bằng cảm biến MQ-2 (còi + đèn)

Mạch phát hiện gas bếp (LPG, butan), khói và hơi cồn trong bếp hoặc phòng kín, hú còi và bật đèn đỏ khi nồng độ tăng bất thường. Tự làm nóng cảm biến 60 giây và tự hiệu chuẩn theo không khí sạch lúc khởi động nên không cần chỉnh tay.

⏱ 60 phút🔧 Mới học💰 Linh kiện ~125.700đ🧠 Arduino Nano⚡ Nguồn USB 5V

✅ Đã kiểm thử

Luật điệnKhông lỗiSai chân, chập nguồn, quá áp 5V vào chân 3,3V, thiếu đi-ốt, thiếu trở kéo…
Mô phỏng SPICE2/2 kịch bản · 14 phép đo đạtDòng/áp từng linh kiện ở trường hợp xấu nhất (ngspice)
Biên dịch codeĐạt · dùng 19% bộ nhớarduino:avr:nano
Xem chi tiết 14 phép đo

Đang báo động (còi + đèn đỏ bật, cảm biến xuất mức cao nhất)

  • Q1: dẫn 29.2mA, Vce=0.03V (bão hòa tốt).
  • D1: dòng 9.0mA (cho phép 20.0mA).
  • Chân D5 cấp 9.0mA (an toàn ≤ 20.0mA).
  • Chân D8 cấp 4.1mA (an toàn ≤ 20.0mA).
  • Tổng dòng đỉnh từ USB 232.3mA (đủ với cục sạc 5V 1A).
  • Dòng qua còi (khoảng 30mA để kêu to): 29.2mA ✓
  • Dòng chân D8 phải cấp để mở transistor: 4.1mA ✓
  • Dòng LED đỏ: 9.0mA ✓
  • Áp ngõ ra analog cảm biến vào A0: 5.00V ✓

Bình thường (đèn xanh, còi tắt)

  • D2: dòng 8.2mA (cho phép 20.0mA).
  • Chân D6 cấp 8.2mA (an toàn ≤ 20.0mA).
  • Tổng dòng đỉnh từ USB 198.2mA (đủ với cục sạc 5V 1A).
  • Còi tắt hẳn: 0.0mA ✓
  • Dòng LED xanh: 8.2mA ✓
Kiểm lần cuối: 11:39:06 12/11/2026

Nguyên lý hoạt động

Bên trong MQ-2 có dây đốt nóng (ăn khoảng 160mA) làm lớp thiếc ôxít nóng lên. Khi có gas hay khói, điện trở lớp này giảm nên điện áp chân AO tăng (0–5V). Arduino đọc A0 liên tục. Lúc mới cấp điện, mạch chờ 60 giây cho cảm biến nóng đều, rồi lấy trung bình 10 giây làm mức nền không khí sạch. Khi giá trị vượt mức nền khoảng 1,6 lần, hoặc chân DO của module xuống mức thấp (vượt ngưỡng chỉnh bằng biến trở), mạch bật đèn đỏ và hú còi. Còi ăn khoảng 30mA nên phải đi qua transistor S8050; chân D8 chỉ cấp khoảng 4mA.

Sơ đồ đấu dây

Mỗi màu là một dây. Chấm tròn là điểm hàn. Chạm vào tên dây trong bảng để làm nổi bật.

5V5VGNDGNDGAS_AOGAS_AOGAS_DOGAS_DOBZ_DRVBZ_DRVBZ_BASEBZ_BASEBZ_COLBZ_COLLED_R_DRVLED_R_DRVLED_RLED_RLED_G_DRVLED_G_DRVLED_GLED_GU1 · Arduino Nano5VA0D2D5D6D8GNDU2 · cảm biến khí gas/khói MQ-2VCCAODOGNDR2 · Điện trở 330Ω12D1 · Đèn LED 5mmA · chân dài (+)K · chân ngắn (−)R3 · Điện trở 330Ω12D2 · Đèn LED 5mmA · chân dài (+)K · chân ngắn (−)R1 · Điện trở 1kΩ12Q1 · Transistor NPN S8050B (gốc)C (góp)E (phát)BZ1 · Còi chip chủ động 5V-+
#DâyNối các điểm
1đỏ
5V
U1 5V ⟷ U2 VCC ⟷ BZ1 +
2đen
GND
U1 GND ⟷ U2 GND ⟷ Q1 E (phát) ⟷ D1 K · chân ngắn (−) ⟷ D2 K · chân ngắn (−)
3vàng
GAS_AO
U2 AO ⟷ U1 A0
4xanh lá
GAS_DO
U2 DO ⟷ U1 D2
5xanh dương
BZ_DRV
U1 D8 ⟷ R1 1
6tím
BZ_BASE
R1 2 ⟷ Q1 B (gốc)
7xanh ngọc
BZ_COL
BZ1 - ⟷ Q1 C (góp)
8nâu
LED_R_DRV
U1 D5 ⟷ R2 1
9hồng
LED_R
R2 2 ⟷ D1 A · chân dài (+)
10xám
LED_G_DRV
U1 D6 ⟷ R3 1
11xanh rêu
LED_G
R3 2 ⟷ D2 A · chân dài (+)

Danh sách linh kiện

Ký hiệuLinh kiệnGiá tham khảo
U1Arduino Nano V3 (ATmega328P, chip nạp CH340), có hàn sẵn chân85.000đTìm mua
U2Module cảm biến khí gas MQ-2 (4 chân VCC-GND-DO-AO, có biến trở chỉnh ngưỡng)35.000đTìm mua
Q1Transistor S8050 (TO-92)500đTìm mua
R1Điện trở 1kΩ 1/4W (nâu-đen-đỏ)200đTìm mua
BZ1Còi chip chủ động 5V (loại có chữ + trên thân, kêu khi cấp điện)4.000đTìm mua
D1LED đỏ 5mm (red)300đTìm mua
D2LED xanh lá 5mm (green)300đTìm mua
R2Điện trở 330Ω 1/4W (cam-cam-nâu)200đTìm mua
R3Điện trở 330Ω 1/4W (cam-cam-nâu)200đTìm mua
Tổng (chưa gồm board hàn, dây, thiếc)125.700đ

Các bước làm

Code nạp cho mạch

Chọn board Arduino Nano.

/*
  Mạch Gọn — Báo rò rỉ gas / khói bằng MQ-2
  Board : Arduino Nano (ATmega328P)
  Chân  : A0 <- AO module MQ-2 | D2 <- DO module (mức THẤP = vượt ngưỡng biến trở)
          D8 -> R 1k -> B S8050 (còi chủ động ở cực C)
          D5 -> 330Ω -> LED đỏ | D6 -> 330Ω -> LED xanh
*/
#include <Arduino.h>

// ----- Cấu hình -----
const uint8_t  PIN_AO      = A0;
const uint8_t  PIN_DO      = 2;
const uint8_t  PIN_BUZZER  = 8;
const uint8_t  PIN_LED_RED = 5;
const uint8_t  PIN_LED_GRN = 6;
const uint32_t WARMUP_MS   = 60000UL;  // làm nóng cảm biến
const uint32_t CALIB_MS    = 10000UL;  // lấy mức nền không khí sạch
const float    ALARM_RATIO = 1.6;      // báo khi vượt mức nền x1.6
const int      ALARM_MIN_DELTA = 60;   // và cao hơn nền ít nhất 60 đơn vị ADC
const int      CLEAR_HYST  = 40;       // trễ để không bật tắt liên tục
const uint32_t CONFIRM_MS  = 1500;     // vượt ngưỡng liên tục 1,5s mới báo
const uint32_t MIN_ALARM_MS = 5000;    // giữ báo động ít nhất 5s

enum State { WARMUP, CALIB, NORMAL, ALARM };
State state = WARMUP;
float baseline = 0;
uint32_t calibSum = 0, calibN = 0;
uint32_t tStart, tCalib, overSince = 0, alarmSince = 0, lastLog = 0;
float filtered = 0;

int readGas() {
  // trung bình 8 mẫu để giảm nhiễu
  uint16_t s = 0;
  for (uint8_t i = 0; i < 8; i++) s += analogRead(PIN_AO);
  return s / 8;
}

void setLeds(bool red, bool green) {
  digitalWrite(PIN_LED_RED, red);
  digitalWrite(PIN_LED_GRN, green);
}

void setup() {
  Serial.begin(9600);
  pinMode(PIN_DO, INPUT);
  pinMode(PIN_BUZZER, OUTPUT);
  pinMode(PIN_LED_RED, OUTPUT);
  pinMode(PIN_LED_GRN, OUTPUT);
  digitalWrite(PIN_BUZZER, LOW);
  // tiếng bíp khởi động
  digitalWrite(PIN_BUZZER, HIGH); delay(80); digitalWrite(PIN_BUZZER, LOW);
  tStart = millis();
  Serial.println(F("Bao gas MQ-2: dang lam nong cam bien 60s..."));
}

void loop() {
  uint32_t now = millis();
  int raw = readGas();
  filtered = filtered == 0 ? raw : filtered * 0.8 + raw * 0.2;
  bool doTrig = digitalRead(PIN_DO) == LOW;

  switch (state) {
    case WARMUP:
      setLeds(false, (now / 500) % 2);  // xanh nháy
      if (now - tStart >= WARMUP_MS) { state = CALIB; tCalib = now; calibSum = 0; calibN = 0; }
      break;

    case CALIB:
      setLeds(false, (now / 150) % 2);  // xanh nháy nhanh
      calibSum += raw; calibN++;
      if (now - tCalib >= CALIB_MS) {
        baseline = (float)calibSum / calibN;
        if (baseline < 20) baseline = 20;      // phòng cảm biến hỏng/đứt dây
        state = NORMAL;
        Serial.print(F("Muc nen khong khi sach = ")); Serial.println(baseline);
        if (baseline > 700) Serial.println(F("CANH BAO: muc nen qua cao, kiem tra cam bien hoac khong khi luc khoi dong"));
      }
      break;

    case NORMAL: {
      setLeds(false, true);
      digitalWrite(PIN_BUZZER, LOW);
      bool over = (filtered > baseline * ALARM_RATIO && filtered > baseline + ALARM_MIN_DELTA) || doTrig;
      if (over) { if (!overSince) overSince = now; if (now - overSince >= CONFIRM_MS) { state = ALARM; alarmSince = now; Serial.println(F("!!! BAO DONG GAS/KHOI !!!")); } }
      else overSince = 0;
      // không khí sạch thay đổi chậm theo nhiệt độ/độ ẩm: cập nhật nền rất chậm
      if (!over && filtered < baseline * 1.2) baseline = baseline * 0.9995 + filtered * 0.0005;
      break;
    }

    case ALARM: {
      setLeds(true, false);
      // hú còi kiểu ngắt quãng 200ms
      digitalWrite(PIN_BUZZER, (now / 200) % 2);
      float clearLevel = max(baseline * ALARM_RATIO, baseline + ALARM_MIN_DELTA) - CLEAR_HYST;
      if (now - alarmSince >= MIN_ALARM_MS && filtered < clearLevel && !doTrig) {
        state = NORMAL; overSince = 0; digitalWrite(PIN_BUZZER, LOW);
        Serial.println(F("Da ve binh thuong"));
      }
      break;
    }
  }

  if (now - lastLog >= 1000) {
    lastLog = now;
    const char* names[] = {"LAM NONG", "HIEU CHUAN", "BINH THUONG", "BAO DONG"};
    Serial.print(F("A0=")); Serial.print((int)filtered);
    Serial.print(F(" nen=")); Serial.print((int)baseline);
    Serial.print(F(" DO=")); Serial.print(doTrig ? F("VUOT") : F("ok"));
    Serial.print(F(" trang thai=")); Serial.println(names[state]);
  }
  delay(20);
}

Đo kiểm bằng đồng hồ vạn năng

Giữa chân VCC và GND của module MQ-24,8 – 5,1V (cảm biến hơi ấm tay sau vài phút)
Giữa AO và GND trong không khí sạchkhoảng 0,3 – 1,2V
Giữa AO và GND khi xì gas bật lửa gầntăng lên trên 2V
Serial Monitor 9600In giá trị A0, mức nền và trạng thái mỗi giây

Sửa lỗi thường gặp

Mới cắm đã hú còi

Cảm biến mới cần làm nóng lâu; mạch đã chờ 60s nhưng nếu khởi động ở chỗ có mùi (cồn, sơn, nước hoa) mức nền sẽ sai. Mang ra chỗ thoáng rồi bấm nút RESET trên Nano.

Xì gas mà không kêu

Xem Serial Monitor giá trị A0 có tăng không. Không tăng: kiểm tra dây AO → A0 và nguồn 5V. Tăng ít: vặn biến trở trên module (theo chiều kim đồng hồ) để chân DO nhạy hơn.

Còi kêu rè hoặc không kêu

Kiểm tra là còi CHỦ ĐỘNG (cấp 5V trực tiếp vào phải kêu), chiều chân + và chiều transistor E-B-C.

Module rất nóng

Bình thường, dây đốt bên trong chạy ở khoảng 50–60°C. Không đặt sát vật dễ cháy, không bọc kín module.

⚠️ An toàn

  • Mạch tham khảo, KHÔNG thay thế thiết bị báo cháy/báo gas đạt chuẩn PCCC.
  • Khi có mùi gas: không bật/tắt công tắc điện, không đánh lửa; khóa van bình gas, mở cửa thông gió rồi mới xử lý.
  • Chỉ dùng nguồn USB 5V; đặt mạch xa vùng lửa và nước của bếp.