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: 16:26:05 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);
}

🔌 Cắm thử trên breadboard

Cắm nháp trên board cắm trước cho chắc, chạy đúng rồi hãy làm mạch in. Sơ đồ này do máy tự xếp từ chính netlist ở trên và đã đối chiếu lại: hai chân cùng một cột (cùng nửa board) là thông nhau, không có net nào bị chập.

+−+−55101015152020252530303535JIHGFEDCBAU1 · Arduino NanoGND5VD2D5D6D8A0U2Q1 S8050R1 1kBZ1+D1 redD2 greenR2 330R3 330
  • Mỗi cột 5 lỗ trong cùng một nửa board thông nhau; hai nửa cách nhau bởi rãnh giữa.
  • Hai đường kẻ dọc mép board là đường nguồn: hàng + (vạch đỏ) và hàng − (vạch xanh). Nhớ bắc dây nối đường nguồn trên với đường nguồn dưới nếu dùng cả hai nửa.
  • Màu dây trên hình trùng với màu trong bảng nối dây ở mục Sơ đồ, cắm theo màu cho dễ dò.

🧲 Mạch in để ủi (PCB 1 mặt)

Bản mạch in một mặt đồng, tự xếp linh kiện và tự đi dây, đã kiểm quy tắc khoảng cách và đối chiếu đúng 100% với sơ đồ nguyên lý ở trên. In tỉ lệ 1:1 rồi ủi lên tấm đồng.

Kích thước board61,0×61,0 mm49 lỗ khoan · mũi 0,8 / 0,9 / 1mm
Đi dây 1 mặt14 đoạn · 458,5 mm · 1 cầu nhảyCầu nhảy = đoạn dây hàn ở mặt linh kiện
Kiểm tra bản mạchĐạt DRC · khớp 100% netlistĐường ≥0,8mm, khe ≥0,5mm; mọi net đối chiếu lại từ hình học thật
Mặt đồng — đã lật gương sẵn để in rồi ủi úp xuống tấm đồng
Mặt linh kiện — vị trí, chiều cắm và tên từng chân
U1U2Q1R1BZ1D1D2R2R3D1D0RSTGNDD2D3D4D5D6D7D8D9D10D11D12VINGND2RST25VA7A6A5A4A3A2A1A0AREF3V3D13VCCGNDDOAO
Cầu nhảy cần hàn (dây đơn ở mặt linh kiện):
  • net GND: U1.GND → U2.GND
Hướng dẫn ủi – ăn mòn – khoan – hàn (đầy đủ)

Hướng dẫn làm mạch in bằng phương pháp ủi

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

Kích thước board: 61,0×61,0 mm · 49 lỗ khoan (mũi 0,8, 0,9 và 1 mm) · 14 đoạn mạch, tổng 458,5 mm · 1 cầu nhảy.

Quy tắc đã kiểm: đường mạch rộng 0,8mm (nguồn và GND 1mm), khe cách tối thiểu 0,5mm. Mạch in đã được máy đối chiếu đúng 100% với sơ đồ nguyên lý.

1. In đúng tỉ lệ 1:1

  • In trang "MẶT ĐỒNG" bằng máy in LASER, đặt tỉ lệ 100%, KHÔNG chọn "Fit to page" hay "Scale to fit".
  • Dùng thước trên bản in đo lại đoạn 100mm: phải đúng 100mm mới dùng được.
  • In trên giấy in ảnh bóng, giấy decal bóc, hoặc giấy tạp chí láng. Mực càng dày càng tốt.
  • Trang "MẶT ĐỒNG" đã được LẬT GƯƠNG sẵn: úp mặt có mực vào tấm đồng là đúng chiều.

2. Chuẩn bị tấm đồng

  • Cắt phíp đồng (board đồng một mặt) lớn hơn kích thước mạch mỗi bề khoảng 5mm.
  • Chà mặt đồng bằng giấy nhám mịn (P800–P1200) rồi rửa sạch, lau khô. Mặt đồng phải sáng, không vết dầu mỡ, không chạm tay vào.

3. Ủi mực sang đồng

  • Úp mặt có mực vào tấm đồng, dùng băng keo giấy dán cố định một cạnh.
  • Bàn ủi để mức nóng nhất (cotton/linen), KHÔNG dùng chế độ phun hơi nước.
  • Ủi đè mạnh và đều 3–5 phút, tập trung từng vùng nhỏ, chú ý các góc và mép.
  • Để nguội hẳn rồi ngâm cả tấm vào nước ấm 5–10 phút, bóc giấy thật nhẹ. Giấy decal thì bóc khi còn ấm.
  • Soi kỹ: chỗ nào mực bị thiếu hoặc đứt đường thì tô lại bằng bút lông dầu (bút CD) rồi để khô.

4. Ăn mòn (etching)

  • Pha dung dịch sắt(III) clorua FeCl3 theo hướng dẫn trên bao bì, hoặc dung dịch oxy già + muối ăn + a-xít; dùng hộp nhựa, KHÔNG dùng đồ kim loại.
  • Nhiệt độ dung dịch khoảng 40–50°C thì ăn nhanh hơn. Lắc nhẹ hộp cho đều, thường 10–25 phút là xong.
  • An toàn: đeo găng tay cao su và kính bảo hộ, làm ở nơi thoáng. Dung dịch ăn mòn làm hỏng quần áo, bồn rửa và gây bỏng rát da.
  • Xong thì rửa board bằng nước sạch, lau khô, dùng xăng thơm hoặc axeton lau sạch lớp mực.
  • Dung dịch đã dùng KHÔNG đổ xuống bồn rửa hay cống; đựng vào can kín và bỏ đúng nơi thu gom chất thải.

5. Khoan lỗ

  • Đối chiếu trang "BẢN VẼ LỖ KHOAN" để biết lỗ nào dùng mũi nào.
  • Dùng mũi khoan 0,8mm, 0,9mm và 1mm, khoan từ MẶT ĐỒNG vào để mũi tự định tâm giữa pad.
  • Khoan tốc độ cao, đẩy nhẹ; mũi nhỏ rất dễ gãy. Khoan xong chà nhẹ bavia hai mặt.

6. Hàn linh kiện

  • Linh kiện cắm ở MẶT KHÔNG CÓ ĐỒNG, hàn ở mặt đồng. Theo trang "MẶT LINH KIỆN" để đặt đúng vị trí và đúng chiều.
  • Hàn linh kiện thấp trước (điện trở, đi-ốt), cao sau (tụ, hàng chân, board vi điều khiển).
  • Chú ý chiều: LED chân dài là (+); đi-ốt có vạch trắng là K; tụ hoá có vạch là (−); transistor theo mặt chữ như nét vẽ đỏ.
  • Mạch này còn 1 CẦU NHẢY: hàn đoạn dây đơn ở mặt linh kiện theo nét đỏ gạch trên bản vẽ:
  • cầu nhảy net GND: từ U1.GND sang U2.GND
  • Trước khi cấp điện: đo thông mạch giữa chân nguồn và GND — KHÔNG được kêu (không được chập).

Lưu ý với board vi điều khiển

  • Board nhái có thể khác thứ tự chân. Đối chiếu tên chân in cạnh từng lỗ trên trang "MẶT LINH KIỆN" với chữ in trên board thật TRƯỚC KHI ăn mòn. Nếu khác, đừng hàn mà báo lại để sửa bản vẽ.
Bản vẽ lỗ khoan
BẢN VẼ LỖ KHOAN (nhìn từ mặt linh kiện)mũi khoan 0,8mm — 9 lỗmũi khoan 0,9mm — 6 lỗmũi khoan 1mm — 34 lỗ

Đ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.