一、传感器基础:光照传感器原理、人体红外传感器原理、温湿度传感器原理

各位同学好,我是老李。做嵌入式这些年,我接触最多的就是传感器。说白了,传感器就是设备的「五官」——光照传感器是眼睛,人体红外是耳朵,温湿度是皮肤。今天咱们就把这三个基础传感器彻底聊透。

1.1 光照传感器原理

光照传感器,核心就是光敏元件。我最早接触的是光敏电阻,那会儿做路灯控制,一到傍晚就犯愁——阈值调高了天没黑就亮,调低了半夜不亮。后来才明白,光敏电阻的响应曲线是非线性的。

常见的光照传感器类型:

类型 原理 典型型号 我踩过的坑
光敏电阻 光照越强,电阻越小 GL5528 温度漂移严重,夏天和冬天阈值不一样
光电二极管 光照产生光电流 BPW21R 输出电流极小,需要运放放大
数字光照传感器 I2C/SPI直接输出lux值 BH1750、TSL2561 BH1750的地址引脚要处理好,否则I2C扫不到

我个人习惯用BH1750做室内照明。为什么?因为它直接输出lux值,不用自己算。你想想看,光敏电阻还得查表换算,多麻烦。

核心要点:光照传感器的选型要看应用场景。室外用光敏电阻(便宜耐造),室内用数字传感器(精度高)。

1.2 人体红外传感器原理

人体红外传感器,也就是PIR(Passive Infrared)。它检测的是人体发出的红外辐射。嗯,这里要注意——它检测的是变化,不是静态的热源。

我记得第一次做人体感应灯,把传感器对着暖气片,结果灯一直亮着。后来才意识到,PIR只能检测移动的人体,静止的人它「看不见」。

PIR传感器的工作流程:

  1. 菲涅尔透镜聚焦红外辐射到热释电元件
  2. 热释电元件产生电荷变化
  3. 信号经过放大、比较,输出高低电平

常用的PIR模块是HC-SR501。我建议新手直接买模块,别自己搭电路。模块上有个可调电位器,用来调节灵敏度和延时时间。

我的调试技巧:HC-SR501的灵敏度不要调到最大,否则猫狗路过都会触发。我一般调到中间偏左,大概3-5米检测距离。

曾经有个项目,客户投诉说灯半夜自己亮。我排查了半天,发现是空调出风口对着传感器吹。热风导致温度变化,PIR误触发。解决方案很简单——把传感器挪个位置,避开风口。

1.3 温湿度传感器原理

温湿度传感器,市面上主流的有DHT11、DHT22、SHT30。它们的原理其实差不多:

  • 温度测量:用NTC热敏电阻或半导体PN结
  • 湿度测量:用电容式湿敏元件,湿度变化引起电容变化

DHT11便宜,但精度差(±2°C,±5%RH)。DHT22精度好一些(±0.5°C,±2%RH)。SHT30是工业级,我最近的项目都在用。

你可能会问:「为什么不用DHT22?」嗯,DHT22的采样间隔是2秒,做快速响应场景不够用。SHT30可以到1ms采样一次。

避坑指南:我曾经在户外项目用DHT11,结果夏天暴晒后读数直接飘到99°C。后来查资料才知道,DHT11的工作温度上限是50°C。户外场景一定要用宽温范围的传感器,比如SHT30(-40°C~125°C)。

温湿度传感器的通信方式:

传感器 通信协议 采样间隔 典型应用
DHT11 单总线 1秒 室内温湿度计
DHT22 单总线 2秒 智能家居
SHT30 I2C 1ms 工业控制、气象站

代码示例——读取SHT30的数据:

// SHT30 I2C读取示例
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(115200);
}

void loop() {
  Wire.beginTransmission(0x44); // SHT30地址
  Wire.write(0x2C); // 测量命令高字节
  Wire.write(0x06); // 测量命令低字节
  Wire.endTransmission();
  
  delay(100);
  
  Wire.requestFrom(0x44, 6);
  if(Wire.available() == 6) {
    uint16_t temp_raw = (Wire.read() << 8) | Wire.read();
    Wire.read(); // 跳过CRC
    uint16_t hum_raw = (Wire.read() << 8) | Wire.read();
    
    float temp = -45 + 175 * (temp_raw / 65535.0);
    float hum = 100 * (hum_raw / 65535.0);
    
    Serial.print("温度: "); Serial.print(temp);
    Serial.print("°C, 湿度: "); Serial.print(hum);
    Serial.println("%");
  }
  delay(1000);
}

这段代码我用了好几年,基本没出过问题。唯一要注意的是,SHT30的I2C地址可能是0x44或0x45,取决于ADDR引脚的电平。

1.4 三种传感器的融合思路

单独用某个传感器,功能有限。但把它们组合起来,就能做很多有意思的事。举个例子:

  • 光照 + 人体:白天光线充足时,人进房间不开灯;晚上光线暗时,人进房间自动开灯
  • 温湿度 + 人体:检测到人离开房间,自动调节空调温度,节能
  • 三合一:根据光照调节窗帘,根据温湿度调节空调,根据人体决定是否执行

我个人习惯在项目初期就把传感器数据统一成结构体,方便后续融合处理:

typedef struct {
  float lux;      // 光照强度,单位lux
  uint8_t pir;    // 人体检测,0或1
  float temp;     // 温度,单位°C
  float hum;      // 湿度,单位%RH
  uint32_t timestamp; // 时间戳
} sensor_data_t;

这样设计的好处是,后续加传感器只需要扩展结构体,不用改业务逻辑。

总结一下:光照传感器看lux值,PIR看变化量,温湿度看绝对值和变化趋势。三个传感器各有脾气,摸透了就能做出好产品。

下一章咱们聊传感器融合的实战——怎么用这些传感器做场景联动。到时候我会拿一个实际项目来拆解,包括代码、电路、调试过程,保证干货满满。