ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于STM32的仓库环境监控系统:温湿度粉尘联动控制与上云实现

基于STM32的仓库环境监控系统:温湿度粉尘联动控制与上云实现 做仓库环境监控这个项目说实话不是我主动挑的属于被现实逼出来的活。朋友在南方做电子元器件仓储每年梅雨季纸箱长霉、引脚氧化损失看得见。市面上买的成品环境监控仪要么太贵要么数据封闭没法跟自己的通风设备联动。所以就有了这套基于STM32的仓库环境控制系统温湿度采集用SHT30粉尘监测用GP2Y1010AU0F控制核心用STM32F103自动通风除湿靠继电器控制风机和除湿机最后用ESP8266把数据传到云平台手机随时能看。整套硬件成本压到两百块以内功能能顶住成品设备七八成而且控制逻辑全是自己的想怎么调就怎么调。写这篇东西的出发点很明确不是给你贴一份别人跑通的毕业设计代码而是把整个项目从选型、接线、写驱动、整定控制策略到上云的完整链路讲一遍。适合三类人——刚开始做STM32综合项目、需要一个完整参考的学生仓库车间现场想做低成本环境监控的工程师以及纯粹想玩物联网设备联动的爱好者。核心思路就一句话先让本地闭环稳定运行再考虑上云。1. 项目核心仓库环境控制到底要解决什么问题1.1 需求拆解温度、湿度、粉尘三者不是孤立的很多新手做类似项目容易犯一个错把各个传感器数据采上来、传上云就觉得任务完成了。实际仓库环境控制真正难的点在于搞清楚温湿度、粉尘和通风设备之间的联动关系。我朋友那个仓库是砖混结构的老库房靠北墙那排货架距离地面不到一米一到梅雨季墙面直接渗水。实测下来湿度常年85%RH以上温度倒还好24到28℃徘徊。这个湿度下纸箱会在48小时内吸潮变软铜引脚两周就开始发绿。粉尘又是另一条线——叉车进出带起的灰、纸箱碎屑加上电子元件的静电吸附通风不好时粉尘浓度能到0.3mg/m³以上比室外的0.15mg/m³限值翻了一倍。所以这个系统的需求不是把数采上来而是温度过高或过低时报警电子元器件一般要求15到35℃湿度超过设定阈值时自动开启除湿机或强排风机粉尘浓度超标时自动开启排风降低颗粒物积聚所有数据远程可见方便值班人员不看现场也能判断。这三件事不是各自独立跑的。比如夏天下午仓库温度高、湿度低你开着除湿机做无用功不如直接开排风机通风而梅雨季外面湿度95%开风机不但不除湿反而把湿气往里带这时候必须靠除湿机。控制逻辑里要考虑这些工况差异不能简单写一个超阈值就开的if。1.2 系统架构与数据流向整个系统的数据流我设计成这样传感器SHT30温湿度、GP2Y1010粉尘采集物理量通过I2C和ADC接口进入STM32F103STM32跑控制策略根据阈值和回滞区间输出继电器控制信号驱动排风机、除湿机、加热器同时把采集结果和处理状态通过USART发给ESP8266ESP8266以STA模式连WiFi通过TCP透传把数据推给云平台。这个架构看起来简单但有一个关键设计点上云链路和本地控制链路完全解耦。什么意思如果WiFi断了、云平台挂了STM32本地闭环控制照常运转该通风通风该除湿除湿只是远程看不了数据而已。控制决策放在本地MCU上而不是依赖云端下发这是工业控制的基本素养——工程现场最怕的就是网络一断设备就罢工。1.3 为什么是STM32ESP8266而不是其他方案市面上的替代方案不少我也认真比对过。用ESP32单芯片行不行行而且性能更强。但ESP32的GPIO直接驱动继电器、接粉尘传感器、跑I2C逻辑上完全可行开发效率还更高。我为什么没选它一个是仓储环境里设备长时间通电STM32F103的稳定性和抗干扰口碑更好5V容忍的IO设计也便于和外围电路匹配另一个是用户基础——如果你想把这套方案给到别人维护会STM32的人比会ESP32的更多。用STM32做控制核心、ESP8266只当一个无线透传模块分工明确调试时也容易定位问题。用纯ArduinoWiFi模块也能实现但这套方案在大数据量并发上传、多传感器管理、后续扩展比如加Modbus接库房PLC时明显力不从心。STM32F103在这类中等复杂度的控制系统中属于性价比和生态成熟度都很均衡的选择。2. 硬件选型与电路设计2.1 主控、传感器的选型对比先说我最终确定的硬件清单主控STM32F103C8T6最小系统板72MHz64Pin LQFP封装板载8MHz晶振和USB这个型号是STM32项目的入门标配资料多、问问题也容易找到人。温湿度SHT30I2C接口精度±0.3℃、±2%RH价格十几块比DHT11那坑爹的±5%RH强太多。粉尘夏普GP2Y1010AU0F也有国产替代型号原理一样利用光学散射检测PM浓度输出模拟电压。无线ESP-01SESP8266刷AT固件版低成本性能够用。执行2路继电器模块控制220V排风机和除湿机交流接触器外置。选型时有几个权衡值得说。DHT11不是不能用是看场景——仓库除湿控制如果湿度误差±5%RH实际60%和65%在控制上没区别但如果你卡着55%的阈值判定开机关机误差就会导致设备频繁误动作。SHT30贵不了几块钱精度和稳定性好一大截这种钱不值得省。粉尘传感器则是没得选GP2Y1010是市面上最容易买到、资料最多的普及型方案PM2.5激光传感器精度更高但价格到两百以上仓库这种场景没必要。2.2 温湿度模块SHT30的接线与测量注意事项SHT30接STM32的I2C1也就是PB6SCL和PB7SDA地址默认为0x44。上拉电阻直接用模块板载的如果自己画板记得加两个4.7kΩ上拉。接线清单如下VCC接3.3VSHT30是3.3V供电接5V会烧模块GND接GNDSCL接PB6SDA接PB7。实操中有个问题SHT30外壳上那个烧结滤膜很薄别用手摸、别用酒精泡。我第一版把传感器直接裸露在仓库里半个月后数据开始漂拆下来发现滤膜上糊了一层灰导致湿度读数偏高。后来加了个PVC通风小盒子盒子底部开孔传感器悬空安装不接触金属支架数据就稳了。2.3 粉尘传感器GP2Y1010的驱动电路与ADC采集GP2Y1010AU0F是光学粉尘传感器原理不复杂内部一个红外LED和一个光电二极管LED发出的光被空气中的颗粒散射后打到光电二极管上输出一个与粉尘浓度大致成正比的模拟电压。但这个传感器有一个非常容易踩的坑LED必须由外部MCU以脉冲方式驱动而且在脉冲发出去之后的特定时间点采样不是断电后直接读电压就行。典型驱动参数LED驱动脉冲周期10ms脉宽0.32ms。在脉冲开始后的0.28ms处输出电压达到与粉尘浓度相关的稳定值此时ADC采样最准。也就是说每次采样的时序是拉高LED引脚→延时280μs→读ADC→拉低LED引脚→延时40μs。电路上要注意两点。第一LED端需要串联一个150Ω限流电阻并在LED两端并联一个220μF电容用来稳定脉冲期间的供电不然输出抖动很大。第二ADC的输入电压范围0到3.3V传感器输出在干净环境下约0.6V粉尘浓度高时能到3V以上可以直接接STM32的ADC引脚我用PA0不需要额外放大。浓度换算的经验公式粉尘浓度(mg/m³) (输出电压 - 零点电压) / 0.5其中零点电压是干净环境下实测值我取0.6V0.5V对应0.1mg/m³是典型灵敏度。注意这个换算不是严格线性的不同批次传感器差异不小如果是生产环境用建议拿一台标准粉尘仪做一次现场标定套一个二次多项式修正。2.4 继电器与执行设备自动通风除湿的物理基础继电器模块是这套系统真正碰强电的地方安全上怎么谨慎都不为过。我用的继电器模块是低电平吸合型光耦隔离控制信号从STM32出来接模块的IN端。因为模块自带光耦和ULN2003驱动STM32的GPIO直接驱动没问题不需要外加三极管。但有一个逻辑要搞清楚这种模块在MCU上电瞬间、GPIO还没配置完成时IN端默认浮空模块内部下拉电阻会把输入拉成低电平——继电器吸合220V设备直接通电这是相当危险的坑。处理办法有两个一是全板设计时让默认工作方向是断电即设备停二是在STM32启动代码最开始main函数第一行甚至时钟初始化之前就把控制引脚强制拉高然后再初始化外设。我习惯二靠代码而不是靠硬件默认状态来保证安全。排风机和除湿机都是220V交流设备中间必须加交流接触器继电器触点只负责控制接触器线圈不要直接接通大功率负载。接触器线圈电压用380V驱动的话还要加中间继电器这里就用220V线圈的接触器继电器触点控制220V到接触器线圈没问题。2.5 ESP8266上云模组的接线与供电ESP-01S模组一共8个引脚实际要接的只有VCC、GND、TX、RX外加一个CH_PDEN拉高。接线如下ESP8266 TX → STM32 PA10USART1_RXESP8266 RX → STM32 PA9USART1_TXESP8266 VCC → 3.3V必须单独供见下ESP8266 GND → GNDCH_PD → 3.3V使能拉高。曾踩过一次大坑WiFi模块疯狂重启表现为串口输出乱码和不断打印ready一开始以为是固件坏了刷了几次没用最后用示波器量VCC发现3.3V被拉到了2.1V。原因就是ESP8266的电流峰值接近300mASTM32最小系统板上的LDO芯片根本喂不饱它。解决方法是外接一个AMS1117-3.3稳压模块从5V降压单独给ESP8266供电并并在电源端加470μF电解电容。这条经验值得所有做ESP8266项目的朋友记住。3. 软件实现从驱动到策略再到上云3.1 工程结构与资源分配用标准库写STM32F103程序工程结构如下STM32-EnvControl/ ├── Core/ // 启动文件、系统初始化 ├── HAL/ // 我封装的驱动层 │ ├── sht30.c/h // I2C温湿度驱动 │ ├── gp2y1010.c/h // 粉尘采样驱动 │ ├── relay.c/h // 继电器控制 │ └── esp8266.c/h // AT指令对接 ├── App/ │ ├── env_ctrl.c/h // 控制策略主逻辑 │ └── cloud_report.c/h // 数据上报拼包 └── main.c定时器资源分配也要提前规划TIM1做ADC采样的LED脉冲定时10ms周期TIM2做1秒系统心跳采集、控制、上报各自挂在这个心跳下TIM4做串口超时判断。如果不提前规划定时器后面代码越写越乱改一项功能牵一发动全身。3.2 温湿度采集与粉尘采样代码SHT30通过I2C读取一次测量命令后延时50ms读数。核心代码如下// sht30.c —— 触发测量 uint8_t SHT30_Measure(float *temp, float *humi) { uint8_t buf[6]; // 高可重复性测量命令 0x2C, 0x06 uint8_t cmd[2] {0x2C, 0x06}; I2C_Write_Data(SHT30_ADDR, cmd, 2); delay_ms(50); if (I2C_Read_Data(SHT30_ADDR, buf, 6)) { return 1; // 读取失败 } // 原始数据转温度和湿度 uint16_t st (buf[0] 8) | buf[1]; uint16_t srh (buf[3] 8) | buf[4]; *temp -45.0f 175.0f * (float)st / 65535.0f; *humi 100.0f * (float)srh / 65535.0f; return 0; }粉尘采样的时序代码// gp2y1010.c —— 单次采样 float GP2Y1010_ReadDust(void) { uint16_t adc_val 0; GPIO_SetBits(GPIOB, GPIO_Pin_1); // LED开 delay_us(280); // 等输出稳定 adc_val ADC_GetAverage(ADC_CHANNEL_0, 8); GPIO_ResetBits(GPIOB, GPIO_Pin_1); // LED关 delay_us(40); float volt (float)adc_val * 3.3f / 4096.0f; float dust (volt - 0.6f) / 0.5f; return dust 0 ? 0 : dust; }注意ADC那里8次采样取平均是必需的粉尘传感器的输出本身有噪声单次采样抖动很大。另外每次采样之间必须保证10ms间隔也就是采样函数每秒最多跑100次我实际放在每秒系统心跳里跑一次就行完全够用。3.3 自动通风除湿阈值加回滞别让继电器频繁跳控制策略是整个系统的灵魂。一开始我写的是最简单的超阈值就开、回落到阈值就关if (humi 70.0f) relay_on(RELAY_DEHUMIDIFIER); if (humi 70.0f) relay_off(RELAY_DEHUMIDIFIER);跑了一天就发现继电器咯咯地响——湿度在阈值附近上下跳动设备几分钟启停一次接触器触点肉眼可见地发热。后来查资料才明白这正是工业控制里强调的回滞控制要解决的问题。所谓回滞就是让开启阈值和关闭阈值之间留出死区避免在设定点附近产生震荡。最终控制策略如下控制对象开启条件关闭条件说明除湿机湿度≥65%RH湿度≤55%RH死区10%RH避免频繁启停排风机粉尘≥0.15mg/m³粉尘≤0.10mg/m³排尘优先和除湿不冲突排风机温度≥32℃温度≤28℃高温辅助散热加热器温度≤10℃温度≥12℃低温保护仓库冬天可加这套阈值配合回滞的写法工程上都叫双位控制实现的本质就是每次判断时用的是当前值和对应方向的历史状态。代码上我维护了一个小的状态机// env_ctrl.c —— 除湿控制逻辑 if (dev-humi DEV_HUMI_ON) dev-dehum_state STATE_ON; if (dev-humi DEV_HUMI_OFF) dev-dehum_state STATE_OFF; relay_set(RELAY_DEHUMIDIFIER, dev-dehum_state STATE_ON);核心思路是状态只由两个阈值决定一旦进入开启状态即使湿度跌到64.9%也不关必须跌到55%以下才认为工况真的变好了。这样继电器一天动作次数从几十次降到两三次设备寿命和电费都省了。3.4 ESP8266上云AT指令流程与透传ESP8266上云最直接的方式是用AT固件做TCP透传。我用的ESP-01S出厂默认带AT固件串口波特率默认115200但STM32的USART1我配置到1152008N1。关键的指令流程# 1. 测试模块应答 AT # 返回 OK # 2. 设为STA模式也支持APSTA但仓库里固定WiFi就行 ATCWMODE1 # 3. 连接WiFi返回 WIFI CONNECTED 后还要等几秒拿到IP ATCWJAPSSID,PASSWORD # 4. 按照平台文档建立TCP连接这里是巴法云的服务器地址和端口 ATCIPSTARTTCP,bemfa.com,9501 # 5. 开启透传模式 ATCIPMODE1 # 6. 开始透传之后串口收到的数据都原样发给服务器 ATCIPSEND # 返回 透传模式下MCU只需要拼好报文往串口发ESP8266就负责转到服务器。这个模式省去了每次发送前先ATCIPSEND的握手过程代码简单很多。断开或异常时串口会主动打印类似CLOSED的关键字这时候需要在STM32端做好重连逻辑不能死等。我在STM32端封装了一个简单的状态机来处理ESP8266上电后先置位透传再发首条数据之后每秒发送一次发送间隔里如果收到CLOSED标志就跳回ATCIPSTART重连。这样WiFi断了之后能自动恢复不用每次人去按复位键。3.5 云端平台选择与数据上报格式云端平台我对比过巴法云、OneNET、自建服务器。OneNET功能全也有免费额度但对这种单个库房监控来说配置流程太沉自建服务器成本高还得维护最后选了巴法云。巴法云的优点是注册简单、有一个TCP网关端口不需要走完整MQTT协议的OpenSSL握手ESP8266的AT指令就能直接对接对MCU算力几乎没有额外负担。而且它自带简易数据面板和微信小程序查看手机端不用自己开发。报文格式上巴法云的私有MQTT协议在透传通道里发送的格式类似topicstm32_env_01cmd1data25.6,62.3,0.08第一次发送后平台会按topic自动创建主题之后数据就能在面板里看到了。不同平台对报文格式要求有差异以对应云平台的接入文档为准。如果你不想依赖某一个物联网平台也可以直接把TCP连接指向自己租的服务器ESP8266端代码完全不用改只换IP和端口就行。数据上报频率我设的是10秒一次这个频率对温湿度和粉尘这种慢变量完全够用。太频繁不仅耗流量还会让云平台面板曲线密密麻麻没有可读性太慢又看不出换气效果。10秒是我测试下来比较舒服的折中。4. 联调、参数整定与现场部署4.1 从零到一的联调顺序联调最忌讳的是把所有模块一次性都接上然后通电出了问题根本不知道从哪里查。我习惯按这个顺序来第一步只烧最小点灯程序确认STM32最小系统正常然后接SHT30读回温度和湿度拿一个标准温湿度计对比误差。第二步接粉尘传感器把传感器对着干净空气和一根点燃的香烟烟头分别测确认输出有变化。第三步接继电器带灯泡测试确认控制逻辑能正确翻转电平。第四步接ESP8266先用USB转TTL单独调试AT指令确认网络和平台能通。第五步STM32和ESP8266联调确认透传数据能实时出现在云面板。第六步接上真实的220V风机和除湿机在小范围实验库房跑一整天观察启停次数和数据曲线。每一步都确认了再做下一步半天时间就能把整条链路跑通。4.2 控制参数整定回滞区间和采样周期参数整定纯粹是现场经验的活。温度和粉尘阈值的回滞可以给5%到15%湿度我给的是10%RH。要注意回滞区间的方向和判断逻辑的关系——比如除湿开启阈值是65%、关闭是55%如果意外写成开启55%、关闭65%那设备永远在超过阈值时停、回落后开结果就是湿度越高设备越不开彻底失控。这种逻辑错误在代码审查时很难发现但写参数时很容易犯。采样周期也要讲究温度变化很慢1秒采一次没问题湿度在通风口附近会快速变化1秒采样可能跳变2%RH所以我在采集程序里对湿度做滑动平均取最近10次数据的平均值参与控制判断。这个处理效果非常明显抖动的曲线一下子平滑了。实测调试记录初始参数开启65%RH、关闭60%RH继电器每小时动作4次偏多调整为开启68%RH、关闭55%RH后继电器每小时动作不到1次粉尘阈值0.15mg/m³开启、0.10mg/m³关闭排风机在大车入库后约3分钟启动15分钟后浓度回落到阈值以下自动停。4.3 现场安装要点传感器安装位置是最影响实测效果的环节。排风机出口附近装粉尘传感器测出来的永远是排风管道里的负压抽过来的新鲜空气数据是假的装在温控死角的传感器湿度永远比平均湿度高。我的做法是粉尘传感器吊装在仓库中央柱子上距离地面约1.5米避开人员走动区域和风道直吹温湿度传感器装在远离门窗、远离发热设备的货架内侧不直接贴在金属架上。另外所有传感器不要放在阳光直射处也不要紧贴墙面墙角的气流是静止的数据没有代表性。控制箱放在仓库北墙配电箱旁边箱体做防尘处理进线口用防水接头锁紧。ESP8266的天线注意不要贴近金属控制箱外壳否则WiFi信号会衰减我实测外壳屏蔽后信号强度从-55dBm掉到-75dBm云平台数据就开始偶尔掉线。5. 常见问题与排查技巧实录5.1 典型问题速查表下面这些问题是做这个项目最容易遇到的把排查思路列出来现场遇到可以照方抓药现象可能原因排查思路ESP8266反复打印乱码/重启供电不足或电源纹波大用AMS1117单独供电加470μF电容量VCC是否稳定在3.3VWiFi能连但数据不显示报文格式不对或topic传错先用串口助手手动发AT指令确认平台能收到数据湿度读数稳定偏高传感器装在通风死角或贴着墙面换安装位置远离墙角和金属支架继电器频繁吸合回滞区间太窄或采样抖动加滑动平均把回滞区间加到10%RH以上粉尘浓度恒定0ADC采样时序不对确认LED脉冲的280μs延时是否生效零点电压是否取错上电瞬间设备误启动GPIO上电默认电平导致继电器吸合在main第一行强制把控制引脚拉高SHT30读取返回错误I2C总线上拉失效或地址错误检查4.7kΩ上拉电阻确认地址是0x44还是0x455.2 独家避坑经验第一所有串口通信STM32和ESP8266之间必须做超时保护不要用死等阻塞的方式接收AT响应。ESP8266在WiFi信号差的时候一条AT响应可能分成几段才能收完没有超时机制的话MCU会卡在串口接收上整个控制逻辑停摆。我实测过最坏情况一条ATCIPSEND卡了4秒才返回如果不做超时这4秒内温湿度控制完全失联。第二通讯协议报文里尽量不要用中文和特殊字符ESP8266在透传模式下对非ASCII字符处理不是很好偶尔会截断。我之前在topic里带了一个下划线加中文后缀结果云平台数据只更新温度不更新粉尘查了很久才发现是topic编码问题改成纯字母数字加下划线后一切正常。第三继电器模块的240V强电线尽量走独立线槽不要和信号线绞在一起。我在实验室跑功能时没注意把24V继电器线圈线和SHT30的I2C线绑在一个线束里结果每次继电器吸合湿度就跳3%RH。换成屏蔽线并分开布线后干扰消失。第四ESP8266固件如果出现AT无响应ATRESTORE后无法回到正常状态优先怀疑供电和串口电平其次才考虑刷固件。一上来就重刷固件容易把原厂AT固件刷坏在联网资料和购买渠道不透明的板子上尤其容易踩坑。这套系统从画电路到跑通用了大约一周之后在朋友仓库连续运行了两个月除了梅雨季最严重那几天除湿机偶尔报警之外整体稳定。我个人实操下来最大的体会是环境控制这类项目稳定压倒一切新功能少加参数保守设传感器装好供电扎实比什么都强。如果后续想在这个基础上扩展方向也明确——加声光报警器在本地直接提醒值班员、把数据接入已有的ERP系统、或者加第二只SHT30做温湿度对比验证都是顺着现有架构自然生长出来的能力。
返回列表