一、传感器基础:光照传感器原理、人体红外传感器原理、温湿度传感器原理
各位同学好,我是老李。做嵌入式这些年,我接触最多的就是传感器。说白了,传感器就是设备的「五官」——光照传感器是眼睛,人体红外是耳朵,温湿度是皮肤。今天咱们就把这三个基础传感器彻底聊透。
1.1 光照传感器原理
光照传感器,核心就是光敏元件。我最早接触的是光敏电阻,那会儿做路灯控制,一到傍晚就犯愁——阈值调高了天没黑就亮,调低了半夜不亮。后来才明白,光敏电阻的响应曲线是非线性的。
常见的光照传感器类型:
| 类型 | 原理 | 典型型号 | 我踩过的坑 |
|---|---|---|---|
| 光敏电阻 | 光照越强,电阻越小 | GL5528 | 温度漂移严重,夏天和冬天阈值不一样 |
| 光电二极管 | 光照产生光电流 | BPW21R | 输出电流极小,需要运放放大 |
| 数字光照传感器 | I2C/SPI直接输出lux值 | BH1750、TSL2561 | BH1750的地址引脚要处理好,否则I2C扫不到 |
我个人习惯用BH1750做室内照明。为什么?因为它直接输出lux值,不用自己算。你想想看,光敏电阻还得查表换算,多麻烦。
核心要点:光照传感器的选型要看应用场景。室外用光敏电阻(便宜耐造),室内用数字传感器(精度高)。
1.2 人体红外传感器原理
人体红外传感器,也就是PIR(Passive Infrared)。它检测的是人体发出的红外辐射。嗯,这里要注意——它检测的是变化,不是静态的热源。
我记得第一次做人体感应灯,把传感器对着暖气片,结果灯一直亮着。后来才意识到,PIR只能检测移动的人体,静止的人它「看不见」。
PIR传感器的工作流程:
- 菲涅尔透镜聚焦红外辐射到热释电元件
- 热释电元件产生电荷变化
- 信号经过放大、比较,输出高低电平
常用的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看变化量,温湿度看绝对值和变化趋势。三个传感器各有脾气,摸透了就能做出好产品。
下一章咱们聊传感器融合的实战——怎么用这些传感器做场景联动。到时候我会拿一个实际项目来拆解,包括代码、电路、调试过程,保证干货满满。