第4章 传感器接口设计:烟雾传感器、温度传感器、气体传感器接口电路

各位同学,咱们今天聊聊传感器接口。这是消防报警系统的“五官”,传感器接不好,后面算法再牛也白搭。我这些年调试过的传感器接口电路,少说也有几十种,踩过的坑能写本书。今天就把核心经验分享给你们。

4.1 烟雾传感器接口:光电式与离子式的选择

烟雾传感器,消防系统里最关键的传感器。市面上主流就两种:光电式和离子式。

光电式烟雾传感器,原理很简单——烟雾颗粒散射红外光。我习惯用MQ-2或者DS18B20这类模块?等等,MQ-2其实是气体传感器。烟雾传感器我推荐GP2Y1010AU0F,夏普的经典款,便宜又好用。

接口电路长这样:

// GP2Y1010AU0F 典型接口
// VCC -> 5V (注意不是3.3V!)
// LED -> GPIO (需要PWM驱动,频率约30Hz)
// OUT -> ADC输入 (0-3.6V输出)
// GND -> GND

// 驱动代码片段
void smoke_sensor_init(void) {
    // 设置LED引脚为输出
    GPIO_Init(LED_PIN, GPIO_MODE_OUTPUT);
    // 设置ADC通道
    ADC_Init(ADC_CHANNEL_0);
}

uint16_t read_smoke_level(void) {
    // 点亮LED
    GPIO_Set(LED_PIN, HIGH);
    // 等待280us(数据手册要求)
    delay_us(280);
    // 读取ADC值
    uint16_t adc_val = ADC_Read(ADC_CHANNEL_0);
    // 熄灭LED
    GPIO_Set(LED_PIN, LOW);
    // 等待40us
    delay_us(40);
    return adc_val;
}

避坑指南:我曾经在项目里直接用3.3V给GP2Y1010AU0F供电,结果输出值一直偏低,查了两天才发现是供电电压问题。这货必须用5V供电,输出范围0-3.6V,直接接3.3V的ADC没问题,但供电不能省。

离子式烟雾传感器,比如NIS-07,灵敏度更高,但有个致命缺点——含有放射性物质镅-241。虽然剂量很小,但出口和环保认证非常麻烦。我个人建议,除非特殊要求,否则优先选光电式。

4.2 温度传感器接口:数字式 vs 模拟式

温度传感器,消防系统里用来检测环境温度异常。我常用的方案有两种:

类型 代表型号 接口方式 精度 功耗
数字式 DS18B20 单总线(1-Wire) ±0.5°C 极低
模拟式 LM35 模拟电压输出 ±0.5°C
数字式 SHT30 I2C ±0.3°C 极低

DS18B20是我用得最多的。单总线协议,一根线就能传数据,省IO口。但要注意——单总线时序要求严格,延时必须精确。

// DS18B20 单总线读取温度
// 注意:延时函数必须精确到微秒级

uint8_t ds18b20_reset(void) {
    uint8_t presence;
    // 拉低总线480us
    GPIO_Set(DS_PIN, LOW);
    delay_us(480);
    // 释放总线
    GPIO_Set(DS_PIN, HIGH);
    delay_us(60);
    // 读取存在脉冲
    presence = GPIO_Read(DS_PIN);
    delay_us(420);
    return presence; // 0表示存在
}

float read_temperature(void) {
    uint8_t temp_lsb, temp_msb;
    int16_t temp_raw;
    
    ds18b20_reset();
    ds18b20_write_byte(0xCC); // 跳过ROM
    ds18b20_write_byte(0x44); // 启动转换
    
    // 等待转换完成(12位精度需750ms)
    delay_ms(750);
    
    ds18b20_reset();
    ds18b20_write_byte(0xCC);
    ds18b20_write_byte(0xBE); // 读取暂存器
    
    temp_lsb = ds18b20_read_byte();
    temp_msb = ds18b20_read_byte();
    
    temp_raw = (temp_msb << 8) | temp_lsb;
    return temp_raw * 0.0625; // 转换为摄氏度
}

小技巧:低功耗设计时,DS18B20有个省电模式——平时让传感器处于休眠状态,需要读数时再唤醒。我习惯每10秒唤醒一次,读取温度后立即休眠,这样平均功耗能降到微安级别。

4.3 气体传感器接口:电化学式与半导体式

气体传感器,消防系统里用来检测一氧化碳、可燃气体等。这里分两类:

半导体式气体传感器,比如MQ-7(一氧化碳)、MQ-2(可燃气体)。这类传感器有个特点——需要加热。加热电流能到几百毫安,对低功耗设计是个挑战。

我建议的做法是:

  • 平时关断加热电源(用MOS管控制)
  • 每30秒开启加热,稳定后读数
  • 读数完成后立即关断
// MQ-7 低功耗驱动方案
// 使用N沟道MOS管控制加热器电源

void gas_sensor_power_control(uint8_t on) {
    if(on) {
        GPIO_Set(HEATER_CTRL_PIN, HIGH); // 开启加热
        delay_ms(1000); // 等待稳定
    } else {
        GPIO_Set(HEATER_CTRL_PIN, LOW);  // 关断加热
    }
}

uint16_t read_gas_concentration(void) {
    uint16_t adc_val;
    
    // 开启加热
    gas_sensor_power_control(1);
    
    // 读取气体浓度
    adc_val = ADC_Read(GAS_ADC_CHANNEL);
    
    // 关断加热
    gas_sensor_power_control(0);
    
    return adc_val;
}

注意:我曾经在项目里犯过一个低级错误——加热器关断后立即读取传感器,结果读到的是残留气体值,不是真实浓度。后来加了100ms的放电时间才解决。嗯,这里要注意,传感器输出电容需要时间放电。

电化学式气体传感器,比如CO-BF,精度高、功耗低,但价格贵。接口电路需要运放做电流-电压转换,因为电化学传感器输出的是微安级电流。

// 电化学传感器接口电路参数
// 运放:LMV321(低功耗轨到轨)
// 反馈电阻:10kΩ
// 偏置电压:Vref = VCC/2

// 输出电压 = 传感器电流 × 反馈电阻
// 例如:1μA × 10kΩ = 10mV

4.4 多传感器融合的接口设计要点

消防报警系统通常要同时接烟雾、温度、气体三种传感器。接口设计上,我总结了几条经验:

  1. 电源隔离:传感器供电和MCU供电要分开,用LDO或DC-DC隔离。我习惯用AMS1117-3.3给MCU供电,传感器单独用一组电源。
  2. ADC通道分配:如果MCU内置ADC通道不够,可以用外部多路复用器(比如CD4051)。但要注意——切换通道后要等稳定时间。
  3. 信号调理:传感器输出信号通常很微弱,需要放大和滤波。我习惯加一级RC低通滤波,截止频率设在10Hz左右,滤掉工频干扰。
  4. ESD保护:传感器接口是暴露在外的,必须加TVS管和限流电阻。我曾经吃过亏——没加保护,一次雷击把三个传感器接口全烧了。

核心要点:传感器接口设计,说白了就是三件事——供电稳、信号准、保护全。供电不稳,读数飘;信号不准,报警误;保护不全,板子烧。这三条做到了,传感器接口就成功了一大半。

好了,这一章的内容就到这里。下一章咱们聊聊无线通信模块选型与接口设计,到时候我会讲讲LoRa和NB-IoT在消防系统里的实际应用经验。有什么问题,咱们课后交流。