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.
✅ Đã kiểm thử
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 ✓
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.
| # | Dây | Nố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 (−) |
| 3 | vàng GAS_AO | U2 AO ⟷ U1 A0 |
| 4 | xanh lá GAS_DO | U2 DO ⟷ U1 D2 |
| 5 | xanh dương BZ_DRV | U1 D8 ⟷ R1 1 |
| 6 | tím BZ_BASE | R1 2 ⟷ Q1 B (gốc) |
| 7 | xanh ngọc BZ_COL | BZ1 - ⟷ Q1 C (góp) |
| 8 | nâu LED_R_DRV | U1 D5 ⟷ R2 1 |
| 9 | hồng LED_R | R2 2 ⟷ D1 A · chân dài (+) |
| 10 | xám LED_G_DRV | U1 D6 ⟷ R3 1 |
| 11 | xanh rêu LED_G | R3 2 ⟷ D2 A · chân dài (+) |
Danh sách linh kiện
| Ký hiệu | Linh kiện | Giá tham khảo | |
|---|---|---|---|
| U1 | Arduino Nano V3 (ATmega328P, chip nạp CH340), có hàn sẵn chân | 85.000đ | Tìm mua |
| U2 | Module 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 |
| Q1 | Transistor S8050 (TO-92) | 500đ | Tìm mua |
| R1 | Điện trở 1kΩ 1/4W (nâu-đen-đỏ) | 200đ | Tìm mua |
| BZ1 | Cò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 |
| D1 | LED đỏ 5mm (red) | 300đ | Tìm mua |
| D2 | LED 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-2 | 4,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ạch | khoảng 0,3 – 1,2V |
| Giữa AO và GND khi xì gas bật lửa gần | tăng lên trên 2V |
| Serial Monitor 9600 | In 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.