气体传感器实战:MQ 系列检测酒精烟雾一氧化碳,安全监控 DIY 方案

气体传感器实战: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 < 100; i++) {
    sum += analogRead(pin);
    delay(10);
  }
  return sum / 100.0;
}

// 使用:基线值 × 1.5 作为警告阈值,× 2.0 作为报警阈值
float baseline = getBaseline(MQ2_PIN);
float warningThreshold = baseline * 1.5;
float alarmThreshold = baseline * 2.0;

方法二:已知浓度对比法(更精确)

如果你有标准气体或者已知浓度的测试源(比如打火机气体对于 MQ-2),可以建立浓度-电压曲线:

  1. 在清洁空气中记录读数(0 ppm 基准点)
  2. 用已知浓度的气体靠近传感器,记录读数
  3. 两点连线,估算中间浓度
浓度(ppm) = (当前读数 - 基线) × 系数

系数需要根据你的具体传感器和气体类型标定。MQ 传感器的数据手册里通常会给出 Rs/R₀ 比值与浓度的关系曲线,可以参考。

各传感器注意事项

MQ-2(烟雾/可燃气体)

  • 检测对象:烟雾、液化气、甲烷、氢气
  • 灵敏度:对丁烷和丙烷最敏感
  • 典型应用:厨房烟雾报警、燃气泄漏检测
  • 注意:对酒精也有反应,厨房和酒精测试环境要分开考虑

MQ-3(酒精)

  • 检测对象:乙醇蒸气
  • 灵敏度:对酒精非常敏感,低浓度即可检测
  • 典型应用:酒驾检测模拟、酒精泄漏监控
  • 注意:呼出气体中的酒精浓度较高,做"酒精测试仪"时需要加采样腔

MQ-7(一氧化碳)

  • 检测对象:CO 气体
  • 特殊要求:需要交替加热(高温 5V 和低电压 1.5V)来区分气体
  • 典型应用:车库 CO 检测、取暖设备安全监控
  • 注意:CO 无色无味,危险性高,建议配合商业 CO 报警器使用

常见问题排查

1. 读数一直很高,不变化

  • 预热不够:传感器刚上电时读数会很高,等待至少 30 分钟
  • 环境有干扰:远离香水、清洁剂、烹饪油烟
  • 传感器老化:MQ 系列寿命约 1-2 年,长期不用的传感器可能失效

2. 读数波动很大

  • 电源不稳定:MQ 传感器加热丝需要较大电流(约 150-170mA),用 Arduino 的 5V 引脚可能供电不足,建议用外部 5V 电源
  • 模拟参考电压:默认参考 5V,如果供电电压有波动,可以用内部 1.1V 参考提高精度:
    analogReference(INTERNAL);  // 使用 1.1V 内部参考

3. 蜂鸣器一直响

  • 阈值设置太低,用上面的基线法重新校准
  • 环境中有持续的气体干扰源(比如附近有厨房或车库)

4. 数字输出 DOUT 不工作

  • 检查板载电位器是否调节到位
  • DOUT 的阈值是固定的(由电位器决定),如果电位器拧到底了可能永远输出高或低

进阶:接入 Home Assistant

如果你在做智能家居,可以把传感器数据通过 ESP32 发送到 Home Assistant:

#include 
#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 检测),建议配合商业设备双重保障

希望这篇博客文章对您有所帮助!