3、传感器技术基础:温度传感器(DS18B20/NTC)、湿度传感器(DHT22/SHT30)、压力传感器、空气质量传感器

做暖通空调控制,说白了就是跟各种物理量打交道。温度、湿度、压力、空气质量——这四个参数,是咱们系统感知环境的「眼睛」和「鼻子」。选错传感器,或者用不好,后面写得再漂亮的PID算法都是白搭。

我个人习惯,在项目选型阶段会花至少30%的时间来评估传感器。为什么?因为我在一个新风项目上吃过亏——用了某款便宜的温湿度模块,结果夏天高湿环境下数据直接漂移,导致除湿逻辑乱跳。从那以后,我对传感器选型就格外谨慎。

3.1 温度传感器:DS18B20 与 NTC

温度测量是暖通控制的基础。常用的方案有两种:数字式的DS18B20,和模拟式的NTC热敏电阻。

3.4.1 DS18B20:一线总线的便利与坑

DS18B20 是 Dallas 公司的经典产品。它最大的特点是采用「一线总线」(1-Wire)通信,只用一根数据线就能跟单片机通信,而且支持挂载多个传感器。

核心参数:

  • 测量范围:-55°C ~ +125°C
  • 精度:±0.5°C(-10°C ~ +85°C 范围内)
  • 分辨率:9~12位可配置(默认12位,对应0.0625°C)
  • 供电:3.0V ~ 5.5V,支持寄生供电模式

典型电路:

// DS18B20 连接示意
// VDD -> 3.3V (或5V)
// GND -> GND
// DQ  -> 单片机GPIO (需外接4.7kΩ上拉电阻到VDD)

// 寄生供电模式(节省一根线):
// VDD 和 GND 短接后接GND
// DQ 仍接GPIO + 上拉电阻
⚠️ 我曾经踩过的坑:

DS18B20 的时序要求非常严格。尤其是初始化时序中的「存在脉冲」检测,延时必须精确到微秒级。我早期用软件延时,结果在中断频繁的系统中经常读不到传感器。后来改用硬件定时器配合状态机来驱动一线总线,问题才解决。

另外,如果使用寄生供电模式,在温度转换期间(特别是12位分辨率时,转换时间约750ms),必须将数据线强拉高以提供足够电流。否则转换结果会出错。

代码示例:读取DS18B20温度

// 简化版读取函数(假设已实现底层1-Wire时序)
float DS18B20_ReadTemperature(void) {
    uint8_t tempL, tempH;
    int16_t rawTemp;
    float temperature;

    // 1. 复位并检测存在脉冲
    if (!DS18B20_Reset()) {
        return -999.0;  // 传感器未响应
    }

    // 2. 跳过ROM(单传感器场景)
    DS18B20_WriteByte(0xCC);

    // 3. 启动温度转换
    DS18B20_WriteByte(0x44);
    delay_ms(750);  // 等待转换完成

    // 4. 再次复位
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC);

    // 5. 读取暂存器
    DS18B20_WriteByte(0xBE);
    tempL = DS18B20_ReadByte();
    tempH = DS18B20_ReadByte();

    // 6. 合成温度值
    rawTemp = (tempH << 8) | tempL;
    temperature = rawTemp * 0.0625;

    return temperature;
}

3.1.2 NTC热敏电阻:低成本模拟方案

NTC(负温度系数)热敏电阻,说白了就是温度越高,电阻越小。它成本极低(几分钱一个),响应速度快,但需要配合ADC使用,而且非线性严重。

分压电路设计:

// 典型分压电路
// VCC (3.3V) -> 上拉电阻 R (10kΩ) -> ADC引脚 -> NTC -> GND

// 温度计算公式(Steinhart-Hart方程):
// 1/T = A + B*ln(R) + C*(ln(R))^3
// 其中 T 为开尔文温度,R 为NTC当前电阻值

查表法实现:

// 实际项目中,我更推荐用查表法代替实时计算
// 因为Steinhart-Hart方程涉及浮点运算和对数,MCU吃不消

// 温度-ADC值对照表(示例,10kΩ NTC + 10kΩ上拉,12位ADC)
const uint16_t tempTable[] = {
    // ADC值, 温度(°C * 10)
    4095,  -200,  // 0°C
    3800,  -100,
    3500,     0,
    3100,   100,
    2700,   200,
    2300,   300,
    1900,   400,
    1600,   500,
    1300,   600,
    1100,   700,
     900,   800,
};

int16_t NTC_GetTemperature(uint16_t adcValue) {
    // 线性插值查找
    for (int i = 0; i < sizeof(tempTable)/sizeof(tempTable[0]) - 2; i += 2) {
        if (adcValue >= tempTable[i+2]) {
            // 插值计算
            int16_t t1 = tempTable[i+1];
            int16_t t2 = tempTable[i+3];
            uint16_t a1 = tempTable[i];
            uint16_t a2 = tempTable[i+2];
            return t1 + (int32_t)(t2 - t1) * (adcValue - a1) / (a2 - a1);
        }
    }
    return tempTable[sizeof(tempTable)/sizeof(tempTable[0]) - 1];
}
💡 我的选型建议:

如果系统中有多个温度测点(比如风管进出风、室内多点),我建议用DS18B20,一线总线可以省IO口。如果只需要一个测点,且成本敏感,NTC+ADC是更经济的选择。但要注意,NTC的精度受限于ADC的位数和参考电压的稳定性。

3.2 湿度传感器:DHT22 与 SHT30

湿度控制是暖通空调的另一个关键。尤其在南方梅雨季,除湿是刚需。我常用的两款传感器是DHT22和SHT30。

3.2.1 DHT22:皮实耐用的单总线方案

DHT22(也叫AM2302)是单总线数字温湿度传感器。它比DHT11精度高得多,而且稳定性好。

参数对比:

参数 DHT22 DHT11
湿度范围 0~100% RH 20~90% RH
湿度精度 ±2% RH ±5% RH
温度精度 ±0.5°C ±2°C
采样周期 2秒 1秒
价格 约15元 约5元

通信协议要点:

// DHT22 单总线协议(与DS18B20不同,注意区分)
// 1. 主机拉低总线至少18ms(启动信号)
// 2. 主机释放总线,等待20-40us
// 3. DHT22拉低总线80us(响应信号)
// 4. DHT22拉高总线80us(准备发送数据)
// 5. 开始传输40位数据(16位湿度 + 16位温度 + 8位校验和)

// 数据位编码:
// 0: 低电平50us + 高电平26-28us
// 1: 低电平50us + 高电平70us
⚠️ 我曾经遇到的坑:

DHT22的启动信号要求拉低至少18ms,这个时间比DS18B20长得多。我刚开始移植代码时,用了DS18B20的时序(480us),结果死活读不到数据。查了半天手册才发现问题。

另外,DHT22的采样周期是2秒,也就是说两次读取间隔不能小于2秒。如果你在循环里不停地读,它会返回旧数据,而且可能造成通信失败。

3.2.2 SHT30:I2C接口的高精度选择

SHT30 是 Sensirion 公司的产品,采用I2C接口。它的精度和长期稳定性都比DHT22更好,当然价格也更高。

核心优势:

  • 精度:湿度±2% RH,温度±0.2°C
  • I2C接口,地址可选(0x44或0x45)
  • 内置加热器,可用于防凝露
  • 响应时间:8秒(63%阶跃)

I2C读写示例:

// SHT30 读取温湿度(简化版)
#define SHT30_ADDR    0x44 << 1
#define CMD_MEASURE   0x2C, 0x06  // 高精度测量命令

void SHT30_Read(float *temp, float *hum) {
    uint8_t data[6];

    // 发送测量命令
    I2C_Start();
    I2C_WriteByte(SHT30_ADDR | 0x00);  // 写
    I2C_WriteByte(0x2C);
    I2C_WriteByte(0x06);
    I2C_Stop();

    delay_ms(15);  // 等待测量完成

    // 读取数据
    I2C_Start();
    I2C_WriteByte(SHT30_ADDR | 0x01);  // 读
    for (int i = 0; i < 6; i++) {
        data[i] = I2C_ReadByte(i < 5);
    }
    I2C_Stop();

    // 计算温湿度
    uint16_t rawTemp = (data[0] << 8) | data[1];
    uint16_t rawHum  = (data[3] << 8) | data[4];

    *temp = -45.0 + 175.0 * rawTemp / 65535.0;
    *hum  = 100.0 * rawHum / 65535.0;
}
💡 我的选型建议:

对于家用空调或新风系统,DHT22的精度已经足够,性价比很高。如果是精密空调或恒温恒湿实验室,我建议用SHT30。另外,SHT30的I2C接口在布线较长时容易受干扰,建议加上拉电阻并缩短走线。

3.3 压力传感器:风压与冷媒压力

在暖通空调中,压力测量主要分两类:风压(用于风管系统)和冷媒压力(用于制冷系统)。

3.3.1 风压传感器:差压与表压

风压传感器通常测量的是差压,比如过滤器前后的压差,或者风管内的动压。

常用类型:

  • MEMS差压传感器:如Sensirion SDP8xx系列,I2C接口,精度高
  • 模拟输出传感器:如Honeywell HSC系列,0.5~4.5V输出
  • 低成本方案:MPXV7002DP,模拟输出,量程±2kPa

应用场景:

// 过滤器堵塞检测
// 在过滤器前后各安装一个取压口,连接到差压传感器
// 当差压超过设定阈值(如250Pa),发出清洗报警

#define FILTER_ALERT_PRESSURE  250  // Pa

void CheckFilterStatus(void) {
    uint16_t adcValue = ADC_Read(CH_PRESSURE);
    float pressure = ADC_To_Pressure(adcValue);  // 转换为Pa

    if (pressure > FILTER_ALERT_PRESSURE) {
        SetAlert(ALERT_FILTER_CLOGGED);
    }
}

3.3.2 冷媒压力传感器:高压与低压

制冷系统中,冷媒压力直接关系到系统运行状态。高压侧(冷凝压力)和低压侧(蒸发压力)都需要监测。

关键参数:

参数 低压侧 高压侧
典型压力范围 0~1.5 MPa 0~3.5 MPa
传感器类型 绝对压力 绝对压力
输出信号 0.5~4.5V 或 4~20mA 0.5~4.5V 或 4~20mA
⚠️ 安全提醒:

冷媒系统压力高,传感器安装必须使用专用接头,并确保密封。我曾经见过一个项目,因为使用了不匹配的密封圈,导致R410A冷媒泄漏,整个系统报废。另外,传感器量程选择要留有余量,一般按最大工作压力的1.5倍选型。

3.4 空气质量传感器:CO₂与PM2.5

随着人们对室内空气质量的关注,CO₂和PM2.5传感器在新风系统中越来越普及。

3.4.1 CO₂传感器:NDIR原理

非色散红外(NDIR)是主流方案。它利用CO₂对特定波长(4.26μm)红外光的吸收特性来测量浓度。

推荐型号:

  • MH-Z19B:国产,UART接口,量程0~5000ppm,性价比高
  • SenseAir S8:瑞典品牌,精度高,长期稳定性好
  • SCD30:I2C接口,集成温湿度,适合高端应用

MH-Z19B 读取示例:

// MH-Z19B 读取CO₂浓度(UART通信)
uint16_t MHZ19B_ReadCO2(void) {
    uint8_t cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
    uint8_t resp[9];

    UART_Send(cmd, 9);
    delay_ms(10);

    if (UART_Receive(resp, 9) == 9) {
        // 校验和验证
        uint8_t checksum = 0;
        for (int i = 1; i < 8; i++) {
            checksum += resp[i];
        }
        checksum = 0xFF - checksum + 1;

        if (resp[8] == checksum) {
            return (resp[2] << 8) | resp[3];
        }
    }
    return 0xFFFF;  // 读取失败
}

3.4.2 PM2.5传感器:激光散射原理

激光粉尘传感器通过测量颗粒物对激光的散射光强来推算浓度。

常用型号:

  • PMS5003:攀藤科技,UART接口,可输出PM1.0/2.5/10
  • SPS30:Sensirion,I2C/UART,精度高,寿命长
💡 我的经验:

空气质量传感器对安装位置很敏感。CO₂传感器要避免安装在通风口附近,否则读数会偏低。PM2.5传感器要避免安装在油烟或水蒸气直接接触的地方。我在一个厨房新风项目中,把PM2.5传感器装在了灶台正上方,结果数据一直爆表——其实是水蒸气干扰了激光散射。

3.5 传感器选型总结

说了这么多,最后给个总结性的建议。你想想看,选传感器其实就是在精度、成本、接口、可靠性之间做权衡。

传感器类型 推荐型号 接口 适用场景
温度 DS18B20 1-Wire 多点测温、风管温度
温度 NTC (10kΩ) 模拟 单点测温、成本敏感
温湿度 DHT22 1-Wire 室内温湿度、新风系统
温湿度 SHT30 I2C 精密控制、恒温恒湿
风压 SDP8xx I2C 过滤器监测、风量控制
冷媒压力 4~20mA型 模拟 制冷系统监控
CO₂ MH-Z19B UART 新风系统、空气质量监测
PM2.5 PMS5003 UART 空气净化、新风系统

嗯,传感器这块就讲到这里。下一章我们会聊信号调理电路,也就是怎么把这些传感器的信号变成单片机能读懂的干净数据。到时候我会讲讲我在ADC采样上踩过的那些坑——保证让你少走弯路。