第14章:气体检测传感器
本章介绍 MQ 系列气体传感器的工作原理、数据采集方法与安全应用。
14.1 MQ 系列传感器原理
14.1.1 工作原理
MQ 系列传感器基于金属氧化物半导体(MOS)原理:
清洁空气中: SnO2 电导率低 → 高电阻
目标气体中: 气体与 SnO2 反应 → 电导率升高 → 电阻降低
14.1.2 传感器结构
┌─────────────────┐
│ 加热线圈 │
│ ┌─────────┐ │
│ │ SnO2层 │ │
│ └─────────┘ │
│ 电极 │
└─────────────────┘
传感器需要加热到工作温度(约 300°C),预热时间约 1-3 分钟。
14.1.3 MQ 系列型号
| 型号 | 检测气体 | 应用场景 |
|---|---|---|
| MQ-2 | 可燃气体、烟雾 | 烟雾报警 |
| MQ-3 | 酒精蒸汽 | 酒驾检测 |
| MQ-4 | 天然气、甲烷 | 燃气泄漏 |
| MQ-5 | LPG、天然气 | 燃气报警 |
| MQ-7 | 一氧化碳 | CO 报警 |
| MQ-135 | 空气质量 | 空气净化 |
14.2 MQ-2 烟雾传感器
14.2.1 输出特性
MQ-2 模块提供两种输出:
- 模拟输出 (A0):电压与气体浓度成正比
- 数字输出 (D0):超过阈值输出低电平
14.2.2 数据编码
模拟输出范围: 0V ~ VCC
ADC 值范围: 0 ~ 65535
清洁空气: ADC ≈ 10000-20000
轻度烟雾: ADC ≈ 20000-35000
浓烟雾: ADC ≈ 35000-65535
14.2.3 检测代码
'''
实验:MQ-2 烟雾检测
接线:A0→GP26, D0→GP22
'''
from machine import ADC, Pin
import time
mq2_analog = ADC(26)
mq2_digital = Pin(22, Pin.IN)
def read_smoke():
"""读取烟雾浓度"""
analog = mq2_analog.read_u16()
digital = mq2_digital.value()
# 数字输出:0=超阈值,1=正常
is_alert = digital == 0
return analog, is_alert
# 预热提示
print("传感器预热中,请等待 60 秒...")
time.sleep(60)
print("预热完成")
while True:
analog, is_alert = read_smoke()
if is_alert:
print(f"⚠️ 烟雾警报! ADC: {analog}")
else:
print(f"正常 ADC: {analog}")
time.sleep(0.5)
14.2.4 浓度估算
'''
实验:烟雾浓度估算
注:需要专业标定,此处仅为示例
'''
import math
def estimate_ppm(adc_value, r0=10):
"""
估算 PPM 浓度
r0: 清洁空气中的传感器电阻(需标定)
"""
# 计算传感器阻值比
voltage = adc_value * 3.3 / 65535
if voltage <= 0:
return 0
rs = (3.3 - voltage) / voltage * 10 # 假设负载电阻 10K
ratio = rs / r0
# 使用对数关系估算 PPM(近似公式)
# 不同气体有不同的曲线
ppm = 100 * math.pow(ratio, -2.2)
return max(0, ppm)
14.3 MQ-3 酒精传感器
14.3.1 检测原理
MQ-3 对酒精蒸汽特别敏感,适用于酒精检测:
- 检测范围:0.04-4 mg/L
- 响应时间:< 10 秒
- 恢复时间:< 30 秒
14.3.2 检测代码
'''
实验:酒精检测
'''
from machine import ADC, Pin
import time
mq3_analog = ADC(26)
mq3_digital = Pin(22, Pin.IN)
# 预热
print("传感器预热中...")
time.sleep(60)
# 记录清洁空气基准值
baseline_samples = [mq3_analog.read_u16() for _ in range(10)]
BASELINE = sum(baseline_samples) // len(baseline_samples)
print(f"基准值: {BASELINE}")
# 阈值设定
ALCOHOL_THRESHOLD = BASELINE + 10000
while True:
analog = mq3_analog.read_u16()
digital = mq3_digital.value()
delta = analog - BASELINE
if analog > ALCOHOL_THRESHOLD:
print(f"🍺 检测到酒精! ADC: {analog}, 变化: +{delta}")
else:
print(f"正常 ADC: {analog}")
time.sleep(0.5)
14.3.3 酒驾检测器
'''
实验:简易酒驾检测器
'''
from machine import ADC, Pin, PWM
import time
mq3 = ADC(26)
buzzer = PWM(Pin(21))
led_green = Pin(0, Pin.OUT)
led_yellow = Pin(1, Pin.OUT)
led_red = Pin(2, Pin.OUT)
BASELINE = 20000 # 需要预先标定
# 血液酒精浓度 (BAC) 阈值对应 ADC 值(需标定)
SAFE_LIMIT = BASELINE + 5000 # ~0.02%
WARNING_LIMIT = BASELINE + 15000 # ~0.05%
DANGER_LIMIT = BASELINE + 25000 # ~0.08%
def all_leds_off():
led_green.value(0)
led_yellow.value(0)
led_red.value(0)
def show_result(level):
all_leds_off()
if level == "safe":
led_green.value(1)
buzzer.duty_u16(0)
elif level == "warning":
led_yellow.value(1)
buzzer.freq(500)
buzzer.duty_u16(1000)
time.sleep(0.1)
buzzer.duty_u16(0)
else: # danger
led_red.value(1)
buzzer.freq(1000)
buzzer.duty_u16(5000)
def check_alcohol():
adc = mq3.read_u16()
if adc < SAFE_LIMIT:
return "safe", adc
elif adc < WARNING_LIMIT:
return "warning", adc
elif adc < DANGER_LIMIT:
return "danger", adc
else:
return "extreme", adc
print("酒驾检测器就绪")
print("请对准传感器呼气...")
while True:
level, adc = check_alcohol()
show_result(level)
if level == "safe":
print(f"✅ 安全 ADC: {adc}")
elif level == "warning":
print(f"⚠️ 警告! 可能饮酒 ADC: {adc}")
else:
print(f"🚫 危险! 禁止驾驶 ADC: {adc}")
time.sleep(1)
14.4 空气质量监测
14.4.1 多传感器融合
'''
实验:综合空气质量监测
'''
from machine import ADC, Pin
import time
mq2 = ADC(26) # 烟雾
mq3 = ADC(27) # 酒精
mq135 = ADC(28) # 空气质量
def read_all_sensors():
"""读取所有气体传感器"""
return {
'smoke': mq2.read_u16(),
'alcohol': mq3.read_u16(),
'air_quality': mq135.read_u16(),
}
def calculate_aqi(values):
"""计算空气质量指数(简化版)"""
# 归一化各传感器值
smoke_norm = values['smoke'] / 65535 * 100
aq_norm = values['air_quality'] / 65535 * 100
# 加权平均
aqi = smoke_norm * 0.5 + aq_norm * 0.5
return min(100, aqi)
def aqi_description(aqi):
"""AQI 等级描述"""
if aqi < 20:
return "优秀", "绿色"
elif aqi < 40:
return "良好", "黄色"
elif aqi < 60:
return "轻度污染", "橙色"
elif aqi < 80:
return "中度污染", "红色"
else:
return "重度污染", "紫色"
print("空气质量监测系统启动")
print("预热中...")
time.sleep(60)
while True:
values = read_all_sensors()
aqi = calculate_aqi(values)
desc, color = aqi_description(aqi)
print(f"烟雾: {values['smoke']:5d} "
f"酒精: {values['alcohol']:5d} "
f"空气: {values['air_quality']:5d} "
f"AQI: {aqi:.0f} ({desc})")
time.sleep(2)
14.5 安全报警系统
14.5.1 多级报警
'''
实验:多级气体报警系统
'''
from machine import ADC, Pin, PWM
import time
mq2 = ADC(26)
buzzer = PWM(Pin(21))
led = Pin(0, Pin.OUT)
# 报警阈值
LEVEL_1 = 30000 # 预警
LEVEL_2 = 45000 # 警报
LEVEL_3 = 55000 # 紧急
def alarm_sound(level):
"""不同等级的报警声"""
if level == 1:
# 缓慢间歇
buzzer.freq(500)
buzzer.duty_u16(2000)
time.sleep(0.3)
buzzer.duty_u16(0)
time.sleep(0.7)
elif level == 2:
# 快速间歇
buzzer.freq(1000)
buzzer.duty_u16(3000)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.1)
else:
# 持续警报
buzzer.freq(2000)
buzzer.duty_u16(5000)
def check_gas():
"""检测气体浓度"""
value = mq2.read_u16()
if value >= LEVEL_3:
return 3, value
elif value >= LEVEL_2:
return 2, value
elif value >= LEVEL_1:
return 1, value
else:
return 0, value
print("气体报警系统启动")
while True:
level, value = check_gas()
if level == 0:
buzzer.duty_u16(0)
led.value(0)
print(f"正常 ADC: {value}")
elif level == 1:
led.toggle()
alarm_sound(1)
print(f"⚠️ 预警 ADC: {value}")
elif level == 2:
led.value(1)
alarm_sound(2)
print(f"🔔 警报! ADC: {value}")
else:
led.value(1)
alarm_sound(3)
print(f"🚨 紧急! 立即撤离! ADC: {value}")
14.6 传感器校准
14.6.1 校准方法
'''
实验:MQ 传感器校准
在清洁空气中进行
'''
from machine import ADC
import time
sensor = ADC(26)
def calibrate_r0(samples=100, interval_ms=100):
"""
校准 R0(清洁空气中的传感器电阻)
需要在已知清洁空气中进行
"""
print(f"校准中,采集 {samples} 个样本...")
values = []
for i in range(samples):
values.append(sensor.read_u16())
time.sleep_ms(interval_ms)
if (i + 1) % 10 == 0:
print(f"进度: {i+1}/{samples}")
avg = sum(values) / len(values)
voltage = avg * 3.3 / 65535
# 计算 RS
RL = 10 # 负载电阻 10K
RS = (3.3 - voltage) / voltage * RL
# 清洁空气中 RS/R0 的典型值(来自数据手册)
# MQ-2: ~9.8
# MQ-3: ~60
CLEAN_AIR_FACTOR = 9.8 # 根据传感器型号调整
R0 = RS / CLEAN_AIR_FACTOR
print(f"平均 ADC: {avg:.0f}")
print(f"平均电压: {voltage:.3f}V")
print(f"RS: {RS:.2f}K")
print(f"R0: {R0:.2f}K")
return R0
# 预热
print("传感器预热中,请等待 3 分钟...")
time.sleep(180)
# 校准
r0 = calibrate_r0()
print(f"\n校准完成! R0 = {r0:.2f}K")
print("请将此值保存用于后续计算")
14.7 本章小结
本章介绍了 MQ 系列气体传感器:
- 工作原理:
- 金属氧化物半导体 (MOS)
- 需要预热 1-3 分钟
- 气体使电阻降低
- 传感器类型:
- MQ-2:烟雾/可燃气体
- MQ-3:酒精蒸汽
- MQ-135:空气质量
- 数据编码:
- 模拟输出:ADC 值与浓度成正比
- 数字输出:阈值比较结果
- 应用场景:
- 烟雾报警
- 酒精检测
- 空气质量监测
下一章将学习压力与摇杆传感器。