2、常见传感器原理:温度传感器(DS18B20)、湿度传感器(DHT11)、压力传感器(BMP280)、红外传感器(HC-SR501)

做物联网采集,传感器就是我们的「眼睛」和「耳朵」。

这一章,我挑四个最常用的传感器,跟你聊聊它们的脾气秉性。说白了,搞懂它们,你就能搞定市面上八成以上的环境采集需求。

2.1 温度传感器 DS18B20 —— 一根线搞定温度

DS18B20 这玩意儿,我用了快十年了。它最大的特点就是——省线。

你想想看,传统的模拟温度传感器,至少得三根线:电源、地、信号。DS18B20 呢?一根数据线就够了。它用的是 1-Wire 总线,数据线和电源线复用,甚至还能从数据线上「偷电」工作(寄生供电模式)。

核心参数:
  • 测温范围:-55°C ~ +125°C
  • 精度:±0.5°C(-10°C ~ +85°C 范围内)
  • 分辨率:9~12 位可配置(默认 12 位,0.0625°C)
  • 通信接口:1-Wire(单总线)
  • 每个芯片有唯一 64 位 ROM 编码,支持多颗挂在同一总线上

我习惯用 12 位分辨率,虽然转换时间要 750ms,但精度够用。如果你对实时性要求高,可以降到 9 位,转换时间只有 93.75ms。

2.1.1 硬件连接

DS18B20 只有三个引脚:GND、DQ(数据)、VDD。标准接法很简单:

  • VDD 接 3.3V 或 5V
  • GND 接地
  • DQ 接 MCU 的 GPIO,同时上拉一个 4.7kΩ 电阻到 VDD
我的经验: 如果线长超过 5 米,上拉电阻可以换成 2.2kΩ。我曾经在一条 20 米的线上挂过 8 颗 DS18B20,上拉电阻用了 1kΩ,照样稳定工作。

2.1.2 通信时序

1-Wire 的时序其实挺讲究的。我刚开始调的时候,被它的时序坑过好几次。核心就三个动作:

  1. 复位脉冲: 主机拉低总线 480μs 以上,然后释放。DS18B20 会在 60μs 内拉低总线作为应答。
  2. 写时序: 写 0 拉低 60μs,写 1 拉低 1~15μs 然后释放。
  3. 读时序: 主机拉低 1~15μs 后释放,在 15μs 内采样总线电平。
// DS18B20 读取温度的核心代码片段
uint8_t ds18b20_reset(void) {
    uint8_t presence;
    GPIO_LOW();                 // 拉低总线
    delay_us(480);              // 保持 480μs
    GPIO_RELEASE();             // 释放总线
    delay_us(60);               // 等待 60μs
    presence = GPIO_READ();     // 读取应答信号
    delay_us(420);              // 等待剩余时间
    return presence;            // 0 表示存在
}

float ds18b20_read_temperature(void) {
    uint8_t temp_lsb, temp_msb;
    int16_t raw_temp;
    
    ds18b20_reset();
    ds18b20_write_byte(0xCC);   // 跳过 ROM 检测(单颗传感器)
    ds18b20_write_byte(0x44);   // 启动温度转换
    
    delay_ms(750);              // 等待转换完成(12 位分辨率)
    
    ds18b20_reset();
    ds18b20_write_byte(0xCC);
    ds18b20_write_byte(0xBE);   // 读取暂存器
    
    temp_lsb = ds18b20_read_byte();
    temp_msb = ds18b20_read_byte();
    
    raw_temp = (temp_msb << 8) | temp_lsb;
    return raw_temp * 0.0625;   // 12 位分辨率下,每个 LSB 代表 0.0625°C
}
避坑指南: 我曾经在批量生产时发现,有些 DS18B20 在第一次上电后读到的温度是 85°C。别慌,这是芯片的默认上电值。解决方案很简单:上电后先发一次转换指令,等 750ms 后再读,就正常了。

2.2 湿度传感器 DHT11 —— 便宜但够用

DHT11 是入门级湿度传感器的代表。说实话,它的精度一般,但胜在便宜、接口简单。一个项目如果对湿度要求不高,用 DHT11 准没错。

核心参数:
  • 湿度测量范围:20% ~ 90% RH
  • 湿度精度:±5% RH
  • 温度测量范围:0°C ~ 50°C
  • 温度精度:±2°C
  • 采样周期:1 秒(两次读取间隔至少 1 秒)
  • 通信接口:单总线(自定义协议,非 1-Wire)

2.2.1 通信协议

DHT11 的协议跟 DS18B20 不一样,它用的是自己的一套单总线协议。数据格式是 40 位:

  • 8 位湿度整数部分 + 8 位湿度小数部分
  • 8 位温度整数部分 + 8 位温度小数部分
  • 8 位校验和

校验和的计算很简单:前四个字节相加,取低 8 位,等于校验和就对了。

// DHT11 读取数据流程
uint8_t dht11_read_data(uint8_t *humidity, uint8_t *temperature) {
    uint8_t data[5] = {0};
    
    // 主机发送起始信号
    GPIO_LOW();
    delay_ms(18);       // 拉低至少 18ms
    GPIO_HIGH();
    delay_us(30);       // 拉高 20~40μs
    
    // 等待 DHT11 响应
    if (GPIO_READ() == 0) {  // DHT11 拉低总线
        while (GPIO_READ() == 0);  // 等待拉高
        while (GPIO_READ() == 1);  // 等待拉低(准备发送数据)
        
        // 读取 40 位数据
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 8; j++) {
                while (GPIO_READ() == 0);  // 等待数据开始
                delay_us(40);              // 在 40μs 时采样
                if (GPIO_READ() == 1) {
                    data[i] |= (1 << (7 - j));
                }
                while (GPIO_READ() == 1);  // 等待数据结束
            }
        }
        
        // 校验
        if ((data[0] + data[1] + data[2] + data[3]) == data[4]) {
            *humidity = data[0];
            *temperature = data[2];
            return 1;  // 成功
        }
    }
    return 0;  // 失败
}
我的经验: DHT11 的时序要求比较宽松,但有一点要注意——两次读取间隔必须大于 1 秒。我见过有人用 500ms 轮询,结果数据全是乱的。另外,DHT11 对湿度变化响应很慢,别指望它能捕捉到「开窗瞬间」的湿度变化。

2.3 压力传感器 BMP280 —— 气压与海拔的精确测量

BMP280 是博世出品的气压传感器,精度很高。我一般在做气象站或者无人机高度计的时候用它。它支持 I2C 和 SPI 两种接口,我习惯用 I2C,省引脚。

核心参数:
  • 压力范围:300 ~ 1100 hPa
  • 压力精度:±1 hPa(相对精度 ±0.12 hPa)
  • 温度精度:±1.0°C
  • 接口:I2C(地址 0x76 或 0x77)或 SPI
  • 功耗:2.7μA(超低功耗模式)

2.3.1 校准参数

BMP280 出厂时,每个芯片都有独立的校准参数,存储在寄存器 0x88~0xA1 中。读取压力数据时,必须用这些参数做补偿计算。说白了,不校准的话,读出来的数据就是废的。

// BMP280 校准参数结构体
typedef struct {
    uint16_t dig_T1;
    int16_t  dig_T2;
    int16_t  dig_T3;
    uint16_t dig_P1;
    int16_t  dig_P2;
    int16_t  dig_P3;
    int16_t  dig_P4;
    int16_t  dig_P5;
    int16_t  dig_P6;
    int16_t  dig_P7;
    int16_t  dig_P8;
    int16_t  dig_P9;
} bmp280_calib_t;

// 温度补偿计算(返回 0.01°C 精度的温度值)
int32_t bmp280_compensate_temperature(int32_t adc_T, bmp280_calib_t *calib) {
    int32_t var1, var2, T;
    
    var1 = ((((adc_T >> 3) - ((int32_t)calib->dig_T1 << 1))) * 
            ((int32_t)calib->dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((int32_t)calib->dig_T1)) * 
              ((adc_T >> 4) - ((int32_t)calib->dig_T1))) >> 12) * 
            ((int32_t)calib->dig_T3)) >> 14;
    
    t_fine = var1 + var2;
    T = (t_fine * 5 + 128) >> 8;
    return T;  // 返回 0.01°C 精度的温度值
}
避坑指南: 我曾经在户外项目中发现,BMP280 在阳光直射下,温度读数会偏高 5~8°C,导致气压补偿出错。解决方案是:把传感器放在百叶箱里,或者加一个遮阳罩。另外,BMP280 对气流敏感,别把它放在通风口旁边。

2.4 红外传感器 HC-SR501 —— 人体检测的经典方案

HC-SR501 是基于热释电红外(PIR)原理的人体感应模块。它检测的是人体发出的红外辐射(波长 8~14μm)。说白了,只要有人经过,它就能感应到。

核心参数:
  • 检测距离:3~7 米(可调)
  • 感应角度:< 120°(锥形区域)
  • 工作电压:4.5~20V(常用 5V)
  • 输出信号:高电平 3.3V,低电平 0V
  • 延时时间:5~200 秒(可调)
  • 封锁时间:2.5 秒(触发后锁定,防止重复触发)

2.4.1 硬件配置

HC-SR501 模块上有两个可调电位器:

  • Sx(灵敏度): 调节检测距离,顺时针增大,逆时针减小
  • Tx(延时): 调节输出高电平的持续时间,顺时针延长

还有一个跳线帽,用来选择触发模式:

  • H(重复触发): 只要有人在感应区内,输出一直保持高电平
  • L(单次触发): 检测到人后输出高电平,延时结束后自动恢复低电平
我的经验: 做智能灯控时,我习惯用 H 模式。这样人一直坐在那里,灯不会灭。但做安防报警时,用 L 模式更合适,触发一次报警就够了,避免重复报警烦人。

2.4.2 使用注意事项

HC-SR501 有几个坑,我踩过,你注意一下:

  1. 上电稳定时间: 模块上电后需要 30~60 秒的稳定时间,期间会误触发。我一般在上电后延时 60 秒再读取数据。
  2. 热源干扰: 空调出风口、暖气片、甚至阳光直射都会导致误触发。安装时避开这些热源。
  3. 检测盲区: 正对传感器方向移动,检测效果最好。如果人从侧面横向移动,灵敏度会下降。
// HC-SR501 读取示例(简单轮询)
#define PIR_PIN   GPIO_PIN_5

void pir_init(void) {
    gpio_set_mode(PIR_PIN, GPIO_INPUT);
    delay_ms(60000);  // 等待 60 秒稳定时间
}

uint8_t pir_detect_motion(void) {
    return gpio_read(PIR_PIN);  // 高电平表示检测到人
}

2.5 四种传感器对比总结

我把这四种传感器放在一起对比一下,方便你选型:

传感器 测量对象 接口类型 精度 典型应用 参考价格
DS18B20 温度 1-Wire ±0.5°C 环境测温、工业监控 3~5 元
DHT11 温湿度 单总线 ±5% RH / ±2°C 室内环境监测 2~4 元
BMP280 气压/温度 I2C/SPI ±1 hPa / ±1°C 气象站、高度计 5~8 元
HC-SR501 人体红外 数字输出 N/A 人体感应、安防 3~5 元

2.6 知识体系图:传感器选型与通信概览

下面这张图,我把四种传感器的通信方式、数据流向和典型应用场景串起来了。你一看就明白:

传感器数据采集知识体系 MCU 主控 DS18B20 温度 DHT11 温湿度 BMP280 气压 HC-SR501 红外 1-Wire 单总线 I2C/SPI GPIO 典型应用场景 环境监测 | 智能家居 | 气象站 | 安防报警 | 工业自动化

嗯,四种传感器讲完了。每种都有自己的脾气,但摸透了之后,你会发现它们其实都很「听话」。选型的时候,记住一句话:没有最好的传感器,只有最合适的传感器


公众号:蓝海资料掘金营,微信deep3321