STM32实战:打造物联网智能充电桩安全监控系统
1. 为什么充电桩需要安全监控系统?
最近几年,小区里的电动车越来越多,充电桩也跟着遍地开花。但你可能不知道,充电桩在封闭空间里工作其实存在不少安全隐患。去年我们小区地下车库就发生过一起充电桩过热引发的险情,幸亏发现及时才没酿成大祸。这件事让我意识到,给充电桩加装安全监控系统真的很有必要。
传统的充电桩大多只关注充电功能本身,很少考虑环境安全因素。但在实际使用中,充电桩周围可能会出现温度过高、湿度过大甚至有害气体泄漏的情况。特别是在地下车库这种通风不良的场所,一旦发生危险气体聚集,后果不堪设想。这就是为什么我们要用STM32开发一套智能安全监控系统。
这套系统的核心功能包括:
- 实时监测环境温湿度(使用SHT-30传感器)
- 检测危险气体浓度(MQ-7传感器)
- 本地声光报警(蜂鸣器+LED)
- 远程数据监控(通过机智云平台)
- 进出车辆计数(红外光电传感器)
我实测下来,这套系统在小区地下车库运行非常稳定,能够提前发现各种潜在危险。比如有一次系统检测到CO浓度异常升高,立即触发了报警,后来发现是旁边一辆燃油车长时间怠速导致的。如果没有这个监控系统,可能等到有人出现不适症状才会被发现。
2. 硬件选型与电路设计要点
2.1 主控芯片选择
STM32F103C8T6是我最终选择的主控芯片,江湖人称"蓝莓派"。这款芯片性价比超高,72MHz主频完全够用,64KB Flash和20KB RAM对于这个项目绰绰有余。更重要的是,它内置了丰富的通信接口:
- 2个I2C接口(接SHT-30和OLED)
- 2个USART(一个接WiFi模块,一个用于调试)
- 1个ADC(采集MQ-7模拟信号)
刚开始我也考虑过用ESP32,毕竟自带WiFi很方便。但实测发现ESP32在强电磁干扰环境下(比如靠近充电桩时)稳定性不如STM32,而且功耗也更高。最终选择了STM32+独立WiFi模块的方案。
2.2 传感器电路设计
传感器部分有三个关键器件需要特别注意:
SHT-30温湿度传感器: 这是数字输出的传感器,通过I2C接口连接。电路设计时要注意:
- 上拉电阻取值4.7kΩ比较合适
- 电源要加0.1μF去耦电容
- 传感器尽量远离主控芯片,避免芯片发热影响测量精度
MQ-7气体传感器: 这个传感器需要特别注意预热时间。硬件设计时:
- 加热电路要单独供电(我用了一个MOS管控制)
- 信号输出端要加RC滤波(我用的是10kΩ+1μF)
- 传感器需要定期校准,我在程序里设置了每24小时自动校准一次
光电传感器: 用于统计车辆进出。这里有个坑要注意:
- 发射管和接收管要成对安装,间距控制在5-10cm
- 最好加装遮光罩,避免环境光干扰
- 信号线要加施密特触发器整形(我用的是74HC14)
3. 软件架构与关键代码解析
3.1 主程序框架设计
整个软件采用前后台架构,主循环负责处理各种任务:
while(1) { userHandle(); // 处理用户输入 gizwitsHandle(¤tDataPoint); // 处理云端通信 timer_loop(); // 定时任务调度 // 传感器数据采集与显示更新 updateGasDisplay(); updateTempHumiDisplay(); // 安全阈值检查 checkSafetyThreshold(); }这里特别要说说timer_loop()的实现。我用了硬件定时器产生1ms时基,然后基于这个时基实现了软件定时器框架。这样做的好处是可以灵活添加各种定时任务,比如:
- 每100ms读取一次光电传感器状态
- 每1秒更新一次OLED显示
- 每5秒上传一次数据到云端
3.2 多传感器数据融合策略
传感器数据不能直接用,需要做一些处理:
温湿度数据: SHT-30的读数比较稳定,但还是做了滑动平均滤波:
#define FILTER_LEN 5 static float temp_history[FILTER_LEN]; static uint8_t filter_index = 0; float get_filtered_temp() { float raw_temp = sht3x_get_temp(); temp_history[filter_index] = raw_temp; filter_index = (filter_index + 1) % FILTER_LEN; float sum = 0; for(int i=0; i<FILTER_LEN; i++) { sum += temp_history[i]; } return sum / FILTER_LEN; }气体传感器数据: MQ-7的读数波动较大,我采用了中值滤波+动态阈值的方法:
int get_gas_level() { static int gas_history[10]; // 采集10个样本 for(int i=0; i<10; i++) { gas_history[i] = mq2_get_gas(); HAL_Delay(50); } // 排序取中值 bubble_sort(gas_history, 10); int median = gas_history[5]; // 动态基线调整 static int baseline = 100; if(median < baseline) { baseline = median; } else if(median > baseline + 50) { baseline += 1; // 缓慢跟踪 } return median - baseline; }4. 云端监控与报警机制实现
4.1 机智云平台接入
选择机智云主要是因为它对STM32的支持很好,提供了完整的SDK。接入过程主要分三步:
- 设备注册: 在机智云平台创建产品,获取Product Key和Product Secret。这两个参数要写在代码里:
#define PRODUCT_KEY "xxxxxxxxxxxx" #define PRODUCT_SECRET "xxxxxxxxxxxx"- 数据点定义: 在平台定义要传输的数据点,比如温度、湿度、气体浓度等。每个数据点都有对应的标识符:
typedef struct { uint8_t alert_status; float temperature; float humidity; uint16_t gas_concentration; // 其他数据点... } dataPoint_t;- 事件处理: 实现平台下发的指令处理,比如修改报警阈值:
void gizwitsEventProcess(eventInfo_t *info) { if(info->event == EVENT_SET_ALERT_THRESHOLD) { max_temp = info->payload[0]; min_temp = info->payload[1]; max_humi = info->payload[2]; // ...其他参数 } }4.2 多级报警策略设计
报警机制我设计了三个级别:
初级预警(黄色警报): 当检测值超过阈值的80%时,OLED显示会变成黄色(如果有彩色屏),但不会触发声音报警。这个主要是给管理人员看的。
中级报警(橙色警报): 超过阈值时,本地蜂鸣器会间歇性鸣叫(每秒响一次),同时LED灯闪烁。数据会上报到云端,APP端会收到推送通知。
紧急报警(红色警报): 当数值达到危险级别时,蜂鸣器会持续鸣响,LED快速闪烁。系统会自动切断充电桩电源(通过继电器),并通过所有可用渠道发送警报。
在实际部署中,这个多级报警机制非常有效。有一次系统检测到温度缓慢上升,在达到初级预警时就通知了物业,后来发现是一个充电器散热风扇故障,及时更换避免了事故发生。
5. 实际部署中的经验分享
5.1 安装位置选择
传感器安装位置很有讲究,经过多次测试我发现:
- 温湿度传感器要安装在距离充电桩30-50cm的位置,太近会受充电桩发热影响,太远又检测不到异常
- 气体传感器最好安装在离地1.2-1.5米的高度,因为大多数有害气体的密度与空气不同
- 光电传感器要正对车辆进出路径,安装高度建议在50-80cm
5.2 抗干扰设计
充电桩周围电磁环境复杂,必须做好抗干扰设计:
电源隔离: 所有传感器供电都通过DC-DC隔离模块,避免传导干扰。我在每个传感器电源入口都加了π型滤波电路(10μF+0.1μF)。
信号隔离: 长距离信号线(比如光电传感器)使用了光耦隔离。I2C总线加了专用的隔离芯片(ADUM1250)。
软件容错: 所有通信协议都加入了重试机制。比如I2C读取失败时会自动重试3次,还失败就标记传感器故障。
5.3 功耗优化技巧
虽然系统接的是市电,但考虑到可能的断电情况,我仍然做了低功耗优化:
- 动态时钟调节: 当没有车辆时,系统会自动降低主频到24MHz:
void enter_low_power_mode() { __HAL_RCC_PLL_DISABLE(); SystemClock_Config_24M(); HAL_SuspendTick(); }- 传感器轮询策略: 不是所有传感器都需要实时监测。我的策略是:
- 温湿度:每10秒采样一次
- 气体传感器:每30秒采样一次(需要预热)
- 光电传感器:持续监测(但采用中断方式)
- 云端通信优化: 正常情况下每5分钟上报一次数据。但当检测到异常时,会自动切换到每分钟上报一次。
