嵌入式开发 气体传感器实战:MQ 系列检测酒精烟雾一氧化碳,安全监控 DIY 方案
为什么 MQ 系列传感器还在用?
MQ 系列气体传感器诞生已经二十多年了,便宜、好买、容易上手。虽然精度比不上工业级设备,但做个家庭烟雾报警、酒精检测、一氧化碳监控,完全够用。
今天我用 Arduino 把 MQ-2(烟雾/可燃气体)、MQ-3(酒精)、MQ-7(一氧化碳)三个最常用的传感器跑一遍,从接线到校准到报警系统,一次讲清楚。
硬件清单
| 模块 | 型号 | 价格(约) | 说明 |
|---|---|---|---|
| 气体传感器 | MQ-2 | ¥8-15 | 烟雾、液化气、甲烷检测 |
| 气体传感器 | MQ-3 | ¥6-12 | 酒精/乙醇检测 |
| 气体传感器 | MQ-7 | ¥10-18 | 一氧化碳检测 |
| 主控板 | Arduino Uno R3 | ¥15-25 | 也可用 ESP32 |
| 面包板 | 830 孔 | ¥5-10 | 接线用 |
| 蜂鸣器 | 有源 5V | ¥2-5 | 报警声音 |
| LED | 红/黄/绿各 1 | ¥0.5 | 状态指示 |
| 电阻 | 220Ω + 10kΩ | ¥1 | 限流和分压 |
| 杜邦线 | 公对公/公对母 | ¥3 | 连接线 |
总成本:约 ¥50-90,比买一个成品烟雾报警器还便宜。
传感器原理速讲
MQ 系列的核心是一个 SnO₂(二氧化锡)敏感材料,加热后电阻会随周围气体浓度变化:
-
清洁空气中,SnO₂ 表面吸附氧气,电阻较高
-
遇到还原性气体(烟雾、酒精、CO),氧气被消耗,电阻下降
-
气体浓度越高,电阻越低,输出电压越高
关键参数:加热时间。 每个 MQ 传感器上电后需要预热 24-48 小时 才能达到稳定状态(有些型号可以缩短到几分钟用于快速测试,但精度会打折扣)。实际项目中建议至少预热 30 分钟再开始读数。
接线方案
三个传感器的接线方式基本一样,都是 4 个引脚:VCC、GND、AOUT(模拟输出)、DOUT(数字输出,部分模块带)。
Arduino Uno
├── 5V ────→ 传感器 VCC
├── GND ────→ 传感器 GND
├── A0 ────→ 传感器 AOUT(模拟信号)
├── D2 ────→ 蜂鸣器正极(通过 220Ω 电阻)
└── GND ────→ 蜂鸣器负极
如果你用的是带比较器的模块(淘宝上大部分都带),还会多一个 DOUT 引脚,可以通过板载电位器调节数字阈值,直接输出高/低电平。不过我建议用 AOUT 模拟输出,精度更高,可以在代码里灵活调整阈值。
完整代码
// MQ 系列气体传感器 - 多通道检测 + 报警系统
// 支持 MQ-2(烟雾)、MQ-3(酒精)、MQ-7(一氧化碳)
#define MQ2_PIN A0 // MQ-2 烟雾传感器
#define MQ3_PIN A1 // MQ-3 酒精传感器
#define MQ7_PIN A2 // MQ-7 一氧化碳传感器
#define BUZZER_PIN 2 // 蜂鸣器
#define LED_RED 3 // 红色 LED - 危险
#define LED_YELLOW 4 // 黄色 LED - 警告
#define LED_GREEN 5 // 绿色 LED - 正常
// 报警阈值(需要根据实际校准调整)
#define MQ2_SMOKE_THRESHOLD 300 // MQ-2 烟雾报警值
#define MQ3_ALCOHOL_THRESHOLD 250 // MQ-3 酒精报警值
#define MQ7_CO_THRESHOLD 200 // MQ-7 CO 报警值
// 预热时间(毫秒)- 传感器需要时间稳定
#define WARMUP_TIME 180000 // 3 分钟最小预热
unsigned long warmupStart;
bool sensorReady = false;
void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
// 所有 LED 关闭
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
digitalWrite(BUZZER_PIN, LOW);
warmupStart = millis();
Serial.println("=== MQ 气体传感器系统启动 ===");
Serial.print("预热中...预计 ");
Serial.print(WARMUP_TIME / 60000);
Serial.println(" 分钟");
}
void loop() {
// 预热检查
if (!sensorReady) {
unsigned long elapsed = millis() - warmupStart;
if (elapsed >= WARMUP_TIME) {
sensorReady = true;
Serial.println("✅ 预热完成,传感器就绪!");
digitalWrite(LED_GREEN, HIGH);
} else {
Serial.print("预热进度: ");
Serial.print(elapsed / 1000);
Serial.print(" / ");
Serial.print(WARMUP_TIME / 1000);
Serial.println(" 秒");
delay(5000);
return;
}
}
// 读取传感器值
int mq2Value = analogRead(MQ2_PIN);
int mq3Value = analogRead(MQ3_PIN);
int mq7Value = analogRead(MQ7_PIN);
// 打印数据
Serial.print("MQ-2(烟雾): ");
Serial.print(mq2Value);
Serial.print(" | MQ-3(酒精): ");
Serial.print(mq3Value);
Serial.print(" | MQ-7(CO): ");
Serial.println(mq7Value);
// 判断状态并控制输出
bool alarm = false;
bool warning = false;
// 烟雾检测
if (mq2Value > MQ2_SMOKE_THRESHOLD) {
Serial.println("⚠️ 检测到烟雾!");
alarm = true;
} else if (mq2Value > MQ2_SMOKE_THRESHOLD * 0.7) {
warning = true;
}
// 酒精检测
if (mq3Value > MQ3_ALCOHOL_THRESHOLD) {
Serial.println("⚠️ 检测到酒精蒸气!");
alarm = true;
} else if (mq3Value > MQ3_ALCOHOL_THRESHOLD * 0.7) {
warning = true;
}
// 一氧化碳检测
if (mq7Value > MQ7_CO_THRESHOLD) {
Serial.println("🚨 检测到一氧化碳!危险!");
alarm = true;
} else if (mq7Value > MQ7_CO_THRESHOLD * 0.7) {
warning = true;
}
// 控制 LED 和蜂鸣器
if (alarm) {
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
digitalWrite(BUZZER_PIN, HIGH); // 蜂鸣器响
} else if (warning) {
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, HIGH);
digitalWrite(LED_GREEN, LOW);
digitalWrite(BUZZER_PIN, LOW);
} else {
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(BUZZER_PIN, LOW);
}
delay(2000); // 每 2 秒读取一次
}
校准方法:这一步不能省
MQ 传感器的数值不是绝对的,受温度、湿度、传感器个体差异影响很大。校准是必须的。
方法一:清洁空气基线法(推荐入门)
// 在已知清洁空气中读取 100 次,取平均值作为基线
float getBaseline(int pin) {
long sum = 0;
for (int i = 0; i
#include
// WiFi 和 MQTT 配置
const char* wifi_ssid = "YOUR_WIFI";
const char* mqtt_server = "192.168.1.100";
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
WiFi.begin(wifi_ssid, "YOUR_PASSWORD");
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer(mqtt_server, 1883);
client.connect("gas-sensor");
}
void loop() {
if (client.connected()) {
int mq2Value = analogRead(MQ2_PIN);
client.publish("sensor/gas/mq2", String(mq2Value).c_str());
}
delay(5000);
}
在 Home Assistant 的 configuration.yaml 中添加:
sensor:
- platform: mqtt
name: "厨房烟雾传感器"
state_topic: "sensor/gas/mq2"
unit_of_measurement: "ppm"
device_class: "gas"
总结
MQ 系列传感器虽然古老,但胜在便宜好用。做家庭安全监控、实验室气体检测、或者简单的 DIY 项目,完全够用。
核心要点回顾:
-
上电先预热,至少 30 分钟
-
一定要校准,清洁空气基线是最简单的方法
-
电源要稳定,加热丝耗电不小
-
阈值要根据实际环境调整,不要照搬数据手册
-
安全相关的应用(尤其 CO 检测),建议配合商业设备双重保障
希望这篇博客文章对您有所帮助!