4、传感器选型与接口:加速度传感器(MPU6050)、门磁传感器、温湿度传感器(DHT22)、电平转换电路
好,咱们进入第四讲。这一讲我打算把整个系统里用到的几个关键传感器,一个一个拎出来说清楚。
选传感器这事儿,说白了就是「够用、稳定、好买」。我在项目里吃过不少亏,比如选了某个冷门型号,结果供货周期八周起步,项目差点黄了。所以这次我选的,都是市面上烂大街、资料多、不容易翻车的型号。
4.1 加速度传感器:MPU6050
电梯运行状态监测,加速度是核心数据。电梯启动、制动、匀速、颠簸、急停,全看加速度波形。
为什么选MPU6050?
- 六轴数据:三轴加速度 + 三轴陀螺仪。电梯里其实陀螺仪用得少,但留着做姿态解算也不亏。
- I2C接口:两根线搞定,省IO口。
- 内置DMP:可以直接输出四元数,省得你自己算欧拉角。
- 便宜:淘宝几块钱一片,坏了不心疼。
关键参数:
| 参数 | 值 |
|---|---|
| 加速度量程 | ±2g / ±4g / ±8g / ±16g |
| 陀螺仪量程 | ±250 / ±500 / ±1000 / ±2000 °/s |
| ADC分辨率 | 16位 |
| 通信接口 | I2C(地址0x68或0x69) |
| 工作电压 | 3.3V ~ 5V(但逻辑电平是3.3V) |
接线方式:
MPU6050的VCC接3.3V,GND接地,SCL接主控的SCL引脚,SDA接SDA引脚。注意,AD0引脚接地时I2C地址是0x68,接VCC时是0x69。如果你像我一样,板子上挂了好几个I2C设备,记得检查地址冲突。
我的经验:MPU6050上电后默认是休眠状态,必须往电源管理寄存器(0x6B)写0x00才能唤醒。我第一次用的时候忘了这茬,读回来的数据全是0,查了半天才发现。
代码示例(初始化部分):
// MPU6050初始化
void MPU6050_Init(void) {
I2C_WriteByte(MPU6050_ADDR, 0x6B, 0x00); // 唤醒
I2C_WriteByte(MPU6050_ADDR, 0x1C, 0x00); // 加速度量程 ±2g
I2C_WriteByte(MPU6050_ADDR, 0x1B, 0x00); // 陀螺仪量程 ±250°/s
I2C_WriteByte(MPU6050_ADDR, 0x1A, 0x03); // 低通滤波 44Hz
}
这里我设了44Hz的低通滤波,为什么?电梯的振动频率一般不会超过几十赫兹,44Hz够用了,还能滤掉高频噪声。你想想看,如果滤波设得太高,数据毛刺多,后面算法处理起来就费劲。
4.2 门磁传感器
电梯门开关状态,这个信息太重要了。电梯能不能走,门没关好绝对不能动。门磁传感器就是干这个的。
选型要点:
- 干簧管型:便宜、无源、寿命长。我推荐这种。
- 霍尔型:需要供电,但抗干扰更好。
- 机械微动开关:容易坏,不推荐。
我选的是干簧管门磁,就是那种一个磁铁加一个干簧管,门关上时磁铁靠近,干簧管导通;门打开时断开。简单粗暴,几乎不会坏。
接线方式:
干簧管一端接GND,另一端接主控的GPIO(内部上拉)。门关上时,GPIO读到低电平;门打开时,读到高电平。
注意:干簧管有常开和常闭两种,买的时候看清楚。我习惯用常开型,门关时导通。另外,磁铁和干簧管的安装距离别超过1cm,否则灵敏度不够。
代码示例(读取门状态):
uint8_t Door_GetState(void) {
return HAL_GPIO_ReadPin(DOOR_GPIO_Port, DOOR_Pin);
// 返回0:门关,返回1:门开
}
就这么简单。但实际项目中,我建议加个软件消抖。电梯门开关时会有机械抖动,直接读可能会误判。我曾经遇到过,门明明关好了,但抖动导致系统以为门没关,电梯不走,维保人员查了半天。
4.3 温湿度传感器:DHT22
电梯机房里的温湿度,对设备寿命有影响。温度太高,变频器容易过热保护;湿度太大,电路板容易结露短路。
为什么选DHT22而不是DHT11?
| 参数 | DHT11 | DHT22 |
|---|---|---|
| 温度精度 | ±2°C | ±0.5°C |
| 湿度精度 | ±5% | ±2% |
| 采样周期 | 1秒 | 2秒 |
| 价格 | 便宜 | 稍贵 |
我个人习惯用DHT22。虽然贵几块钱,但精度高出一大截。电梯机房温度变化不大,但湿度监测需要准一些,否则容易误报。
接线方式:
DHT22有四个引脚:VCC(3.3V~5V)、DATA、NC(空脚)、GND。DATA引脚需要接一个4.7kΩ上拉电阻到VCC。注意,DHT22是单总线协议,时序要求比较严格。
避坑指南:DHT22的采样周期是2秒,也就是说,你两次读取之间至少间隔2秒,否则数据会出错。我曾经在循环里每100ms读一次,结果读出来的数据全是乱的。后来查手册才发现这个坑。
代码示例(读取温湿度):
uint8_t DHT22_Read(float *temp, float *humi) {
uint8_t data[5] = {0};
// 主机发送起始信号
DHT22_Pin_Low();
delay_ms(18);
DHT22_Pin_High();
delay_us(30);
// 等待响应
if (DHT22_Pin_Read() == 0) {
while (DHT22_Pin_Read() == 0); // 等待拉高
while (DHT22_Pin_Read() == 1); // 等待拉低
// 读取40位数据
for (int i = 0; i < 40; i++) {
while (DHT22_Pin_Read() == 0);
delay_us(40);
if (DHT22_Pin_Read() == 1) {
data[i/8] |= (1 << (7 - (i % 8)));
}
while (DHT22_Pin_Read() == 1);
}
// 校验
if ((data[0] + data[1] + data[2] + data[3]) == data[4]) {
*humi = ((data[0] << 8) | data[1]) / 10.0;
*temp = ((data[2] << 8) | data[3]) / 10.0;
return 1;
}
}
return 0;
}
这段代码看着长,其实核心就是单总线时序。注意那个40微秒的延时,太短或太长都会导致数据错位。我建议用逻辑分析仪抓一下波形,确认时序对不对。
4.4 电平转换电路
嗯,这里要重点说一下。很多传感器是5V供电,但主控(比如ESP32、STM32)是3.3V逻辑电平。直接连?烧IO口是小事,烧芯片就麻烦了。
为什么需要电平转换?
- 3.3V主控的IO口耐压通常只有3.6V,5V信号直接灌进来会烧。
- 5V传感器可能不识别3.3V的高电平,导致通信失败。
常用方案:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 电阻分压 | 便宜、简单 | 只能单向、带载能力弱 |
| MOS管双向转换 | 双向、高速 | 需要两个电阻 |
| 专用电平转换芯片 | 稳定、多通道 | 贵、占地方 |
我个人习惯用MOS管方案,一个2N7002加两个10kΩ电阻,成本几分钱,效果很好。电路图如下:
// 单向电平转换(5V -> 3.3V)
// 5V传感器TX ---[10k]--- 3.3V主控RX
// |
// GND
// 双向电平转换(I2C用)
// 5V侧 ---[10k上拉]---||---[10k上拉]--- 3.3V侧
// MOS管(2N7002)
// G极接3.3V
// S极接5V侧
// D极接3.3V侧
注意:I2C总线是开漏输出,必须用双向电平转换。单向分压电路用在I2C上会出问题。我刚开始做的时候不懂,用电阻分压接了MPU6050,结果通信时好时坏,查了三天才发现是电平不匹配。
实际接线建议:
- MPU6050:3.3V供电,不需要电平转换。
- DHT22:可以3.3V供电,但5V供电时DATA引脚需要电平转换。
- 门磁传感器:干簧管是无源器件,直接接GPIO,不需要电平转换。
好了,这一讲的内容就是这些。传感器选型看似简单,但每个细节都可能影响系统稳定性。下一讲咱们开始讲通信方案,LoRa模块怎么配、怎么组网,到时候见。
本章小结:
- MPU6050:六轴加速度+陀螺仪,I2C接口,注意唤醒和滤波设置。
- 门磁传感器:干簧管型,简单可靠,注意消抖。
- DHT22:高精度温湿度,单总线协议,注意采样周期。
- 电平转换:MOS管方案性价比最高,I2C必须用双向转换。