基于STM32的智慧养猪环境监控系统:从传感器到云平台 1. 项目整体思路为什么用STM32做猪场环境监控1.1 智慧养猪到底解决了什么问题先说结论这套基于STM32的智慧养猪系统本质上是一个典型的环境监测与自动控制终端。很多人一听到智慧养猪就以为是多大的平台工程其实落到硬件上核心就三件事把猪舍里的温湿度、氨气浓度这些关键参数测准根据阈值自动开关风机和加热设备再把这些数据推到云端让养殖户用手机随时看。做这个项目之前我认真算过一笔账。传统猪舍管理最痛的不是设备贵而是人不可能24小时守在猪舍里。夜间气温陡降没人调整风机氨气超标没人发现等到第二天早上进圈猪已经开始打喷嚏、食欲下降。养猪这行有个说法环境控制好了饲料转化率能差出10%以上。这10%摊到一批猪身上就是实打实的利润。所以智慧养猪系统不是花架子它解决的是人不在现场但环境不能失控这个刚需。这个项目非常适合两类人参考。一类是物联网方向的学生拿它做嵌入式毕业设计硬件和软件闭环完整既有STM32底层开发又有云平台对接评委想看的技术点基本全覆盖。另一类是小型养殖场业主或者农创团队想低成本搭一套环境监控系统这个方案零基础也能跟着复现。1.2 系统架构与数据流向设计整个系统的数据流很简单但设计时我特意坚持了一个原则本地优先云端其次。也就是说即使断网、云平台挂了现场设备也必须按照预设逻辑自动运行。这一点在养殖场景里是生死线猪舍环境控制不能依赖网络网络断了风机照常开加热器照常工作这才是合格的系统架构。系统分成三层来设计感知层温湿度传感器采集舍内温湿度氨气传感器采集有害气体浓度光照传感器判断是否需要补光这些都是模拟量或数字量直接进STM32的ADC或I2C接口。决策控制层STM32F103C8T6作为主控运行采集、滤波、阈值判断、控制输出逻辑。本地OLED屏幕实时显示数据按键可以修改报警阈值。执行与远程层继电器模块驱动风机、加热器、水泵和照明ESP8266模块通过串口与STM32通信把数据通过MQTT协议上报到云平台同时接收手机端下发的远程控制指令。选STM32而不用Arduino或者树莓派理由其实很现实Arduino开发快但工业稳定性和接口资源都差点意思尤其是多路ADC采集加继电器控制跑起来心里没底树莓派跑Linux确实强大但成本高、功耗高猪舍这种高湿粉尘环境金贵的板子不敢往里放。STM32F103C8T6这颗芯片零售价几块钱64KB Flash够写完整套逻辑20KB RAM跑传感器采集和协议栈绰绰有余而且资料满天飞遇到问题随便一搜就有答案。更重要的是做这个项目能真正练到定时器、ADC、I2C、USART、中断这些嵌入式基本功做完一个项目这些外设基本都摸透了。2. 硬件选型与关键电路避开那些上电就烧板的坑2.1 主控选型与传感器搭配方案主控我选用STM32F103C8T6最小系统板这是国内用得最泛滥也最稳的一颗料。它的资源分配我列一下方便你对照自己手头的板子规划引脚12位ADC采集氨气传感器输出、光照传感器模拟输出还可以预留一路采集电源电压做监测。USART1预留调试串口接CH340模块打印日志。USART2接ESP8266通信模块。I2C1接OLED屏幕和数字温湿度传感器。I2C2或者软件模拟I2C接BH1750光照传感器避免和OLED抢总线。定时器TIM2做ADC采样定时触发保证采集频率稳定。传感器选型这块我踩过不少坑直接说结论。温度湿度测量建议用SHT30或者DHT22SHT30是I2C接口、精度高温度±0.3℃湿度±2%RH、长期稳定性好价格也就几块钱既然做系统不差这几块我最后选的是SHT30。DHT11虽然便宜到一两块但温湿度精度都很差湿度误差±5%环境波动大一点数据就跳来跳去做自动控制很容易误动作不建议用在正经项目里。氨气传感器我用的MQ137模块。这类半导体气体传感器输出的是模拟电压直接接STM32 ADC采集就行电路最简单。但你要有心理准备MQ系列有几个脾气初次上电需要预热24小时以上才稳定长期使用会有基线漂移而且对温湿度敏感。所以我的做法是软件里做了基线校准同时把温湿度数据参与氨气读数的温度补偿这个后面细说。光照传感器选BH1750I2C接口量程0~65535 lux直接输出数字光照强度不用自己算曲线。用于猪舍照明控制很合适判断白天黑夜自动开关补光灯。各传感器参数对比和选型理由我整理了一张表传感器测量对象接口类型精度/量程选型理由SHT30温湿度I2C温度±0.3℃ 湿度±2%RH精度高长期漂移小自带防凝露能力DHT22温湿度单总线温度±0.5℃ 湿度±2%RH低成本替代方案单总线协议简单DHT11温湿度单总线温度±2℃ 湿度±5%RH仅适合学习上手验证流程MQ137氨气浓度模拟量ADC量程参考模块手册测量硫化氢/氨气响应快BH1750光照强度I2C0~65535 lux数字输出不用标定2.2 继电器驱动与电源抗干扰设计继电器控制是这套系统最容易出问题的环节我建议直接照抄成熟方案STM32的GPIO输出接光耦隔离器PC817光耦输出驱动ULN2003或者三极管再去控制5V继电器线圈。继电器线圈两端必须并联一个1N4007续流二极管方向反着接否则继电器断电瞬间的感应电动势会把驱动管击穿这是新手最容易忽略的细节。很多人贪省事直接用现成的低电平触发继电器模块板载三极管都帮你焊好了光耦也有插上就能用。但要注意市面上的继电器模块触发逻辑是分高电平和低电平两种的买的时候一定看清楚模块丝印。我调试的时候就是因为默认低电平触发上电瞬间STM32的引脚还没初始化完毕IO口处于浮空状态继电器直接咔哒一声吸合了风机在系统启动的瞬间就转了。这种问题在现场很吓人解决方法是程序里第一步就把所有继电器控制引脚初始化为确定的关闭电平并且在硬件上给控制引脚接一个10K下拉或上拉电阻保证上电默认态是安全的。电源部分是整个系统稳定运行的地基。我的方案是220V交流电进开关电源转24V24V给风机、加热器等执行器供电。24V再接一个隔离型DC-DC模块降到5V5V给继电器模块和传感器供电。5V再经AMS1117-3.3V降到3.3V给STM32和ESP8266供电。注意这里有两个关键点一是5V和3.3V之间最好用LDO纹波小ADC采集的数据才稳定二是传感器供电和MCU供电不要共用一组LDOMQ137这种传感器工作时电流变化明显会拉低电压导致单片机复位。我第一版图省事直接用USB线5V供电给整个板子结果继电器一吸合STM32就复位查了半天发现是供电被拉垮。后来换成独立供电方案继电器和MCU供电彻底分开问题才根治。电源这块表我改了三版最终稳定运行的架构是220V交流→24V开关电源→隔离DC-DC 5V→AMS1117 3.3V模数地单点连接。3. 软件框架与核心控制逻辑从裸机调度到自动控制策略3.1 裸机状态机还是RTOS这套系统的软件规模说实话不上RTOS完全够用。系统任务也没几个传感器采集、数据显示、自动控制逻辑、串口通信、看门狗喂狗。用FreeRTOS当然也能跑但F103C8T6只有20KB RAM跑一个精简版RTOS后留给用户代码的空间就紧张了而且任务间同步还要考虑信号量、队列调试复杂度直接翻倍。我的建议是裸机主循环加定时器时间片调度逻辑清楚又省资源。具体做法是这样SysTick配置成1ms中断维护一个系统Tick计数器。主循环里根据Tick值轮询各个任务的时间标志位例如每100ms采集一次传感器每500ms刷新一次OLED每200ms执行一次控制逻辑每50ms处理一次串口接收缓冲区每1000ms检查一次ESP8266连接状态。这样做的好处是任务之间不会互相阻塞任何一个任务卡了其他任务还在跑现场稳定性比大循环里顺序执行好得多。我第一版就是典型的大循环采集传感器—显示—判断继电器—串口收发所有事排队做。结果串口数据量大一点采集周期就变长控制响应变慢调试时很被动。改成时间片调度之后整个系统节奏稳定了问题也变少。如果你后续要加4G模块、加称重传感器、加多个控制策略再考虑上FreeRTOS也不迟。3.2 传感器采集与滤波算法传感器数据最怕的就是毛刺。尤其是猪舍里风机一启动电磁干扰叠加到模拟量上ADC读出来的氨气浓度数值跳来跳去直接用这个数去控制设备就会造成风机频繁启停。所以软件滤波必须做我用的是滑动窗口中值滤波加算术平均的复合方案连续采样10次排序后去掉最大值和最小值剩下8个数求平均。这个组合既滤掉了随机尖峰又保留了真实变化趋势实测效果非常好。ADC采集的代码很简单但有几个细节值得注意。STM32的ADC是12位分辨率参考电压3.3V所以电压值和ADC值的换算关系是电压 ADC值 × 3.3 / 4095。如果你的VREF引脚没有接高精度基准源直接使用板载3.3V供电那么3.3V这一项会有几十毫伏的偏差对氨气这种人眼看不出来的模拟量影响不大但对精密测量就不够用了。我实际使用中用万用表实测了板子3.3V的实际值把这个实际值写进代码里做换算精度提升很明显。SHT30的读取用的是I2C接口调用HAL库的I2C函数每次读6个字节前2字节是温度中间2字节是湿度最后2字节是CRC校验。一定记得做CRC校验环境潮湿时I2C总线偶尔会有错码没有校验的话会出现偶尔一次温度跳到80多度的鬼数据触发加热器误关闭的严重问题。BH1750同样走I2C注意上电后要先发送一次连续高分辨率模式指令然后等120ms再读数据别读太快否则返回的全是0xFF。MQ137氨气传感器的处理麻烦一点。它输出的是模拟电压电压越高表示气体浓度越高。但这个传感器有个特点零点和灵敏度都会随着使用时间漂移。我的处理方法是系统首次校准在洁净空气环境中记录此时ADC采到的基线电压之后定时每天早上4点当判断氨气浓度稳定且风机未启动时平滑更新这个基线值。这样能有效补偿长期漂移。至于电压怎么换算成ppm浓度每个厂家的模块灵敏度不同最好用标准气体标定没有条件的话可以参考手册里的灵敏度曲线做近似线性换算作为控制阈值够用了。说一下定时器输入捕获。我额外加了一路风速传感器用的是霍尔风速计输出频率和风速成正比用STM32的定时器输入捕获功能测脉冲频率再换算成风速。这里正好用到了定时器捕获测频率的经典玩法代码里把TIM2配置成输入捕获模式上升沿触发计算两次捕获的时间差取倒数就是频率。做这个功能的时候顺便把定时器中断、捕获比较这些知识点巩固了一遍。3.3 自动化控制策略滞回控制、联动与告警自动控制策略是整个智慧养猪系统的大脑但别把它想得太复杂核心就一个词滞回控制。所谓滞回就是给开关动作设定一个差值区间避免设备在阈值附近来回翻转。举个例子假设猪舍温度超过28℃需要开风机降温低于25℃需要关风机。如果不做滞回温度到27.99℃风机启动吹一会儿降到28.01℃因为仍然超过28℃风机不会停那还好但如果策略写的是超过28℃开、低于28℃关那么温度在28℃上下波动时风机会疯狂地开了关关了开继电器触点寿命急剧下降电机也受不了。所以我的策略是温度大于28.5℃开风机降到25.5℃以下才会关风机中间这3℃就是滞回区间。各环境参数的联动策略我整理成了表格直接可以在代码里实现控制对象开启条件关闭条件优先级降温风机温度28.5℃ 或 氨气15ppm温度25.5℃ 且 氨气8ppm高加热器温度18℃ 且 湿度非极端高温度21℃中除湿风机湿度75%RH 且 温度15℃湿度65%RH中补光灯光照500 lux 且 时段为白天光照2000 lux 或 夜间定时关闭低报警器温度32℃ 持续30秒 或 氨气25ppm 持续10秒条件解除并持续60秒最高注意我把所有报警条件都加了持续时间判断这是我从实际教训里总结的。最开始报警逻辑是温度一超32℃就响结果中午太阳照到传感器上温度瞬间冲到33℃蜂鸣器猛烈报警其实是误报。加了持续30秒才算数的逻辑之后误报率基本归零。这种防抖思想在处理所有现场信号时都通用不是只有按键消抖才用。定时饲喂功能我用了两个方案。简单方案是直接定时控制下料电机比如早上7点、中午12点、下午6点各转10秒靠时间来控制。进阶方案是加HX711称重传感器每次下料前称一下料斗的重量下料后称一下重量差把实际下料量反馈到云端做精准饲喂。HX711是24位ADC芯片通过串口协议和STM32通信网上资料很多硬件连接就四根线做起来不难。4. 远程监控与数据上云把猪舍环境送到手机里4.1 通信模块选型与MQTT基础远程通信这层我选的是ESP8266模块。这颗Wi-Fi芯片被国内开发者玩出了花资料多到看不完十几块钱一片作为STM32的通信搭档再合适不过。我手头有ESP-01S和ESP-12F两种模块最终用的是ESP-12F因为它的引脚更多、天线性能更好、Flash更大跑AT固件更稳。STM32和ESP8266的连接很简单STM32的USART2 TX接ESP8266的RXDSTM32的USART2 RX接ESP8266的TXD共地波特率我设115200。注意ESP8266是3.3V电平绝对不能直接接5V的TXD否则模块必烧。如果你的STM32板子是5V供电串口TX需要加一个分压电阻或者用电平转换芯片。MQTT协议是现在的物联网标配我拿微信群聊做个类比。服务器就是一个聊天群设备往群里发消息叫发布设备订阅某个话题后群里一旦有相关消息就能收到这叫订阅。每个消息都有主题比如猪舍1号/环境数据设备端发布到这个主题手机端订阅这个主题数据自然就通了。MQTT最厉害的是消息质量等级和遗嘱机制设备断线时服务器能感知到这对远程监控来说太重要了。4.2 STM32端AT指令连接与数据上报实操我用的ESP8266固件是支持MQTT透传的AT固件连接云平台的流程大致是先设Wi-Fi模式、连接路由器、然后配置MQTT参数、建立连接、订阅主题、循环发布消息。AT指令序列我贴出来你照着串口调试助手验证一遍再往STM32里写AT // 测试模块是否响应 ATCWMODE1 // 设置为Station模式 ATCWJAP你的WiFi名,你的WiFi密码 // 连接路由器 ATMQTTUSERCFG0,1,ClientID,用户名,密码,0,0, // 配置MQTT参数 ATMQTTCONN0,bemfa.com,9501,1 // 连接巴法云MQTT服务器 ATMQTTSUB0,设备主题,1 // 订阅控制主题 ATMQTTPUB0,设备主题,{\temp\:\25.6\},1,0 // 发布环境数据不同厂家固件的AT指令格式有差异上面是我手头这个固件的写法你拿到模块后先用串口助手一条条试确认每条指令都返回OK了再写进STM32程序。数据上报的格式我用的是最轻量的JSON字符串。STM32端没有用cJSON库因为场景简单几个字段手拼字符串就够了嵌入式环境能少一个依赖就少一个。举个例子上报的环境数据长这样{temp:25.6,hum:68.5,nh3:8.2,lux:1200,fan:ON,heat:OFF,feed:0}手机端云平台App显示的就是这个JSON解析后的字段。提醒一句字符串拼接时别忘在数据前后加转义字符我一开始调试时JSON格式不对云端一直显示离线后来串口打了原始数据才发现是引号没处理好。断线重连机制是整个远程模块的重点。猪舍环境Wi-Fi信号不稳定是常态路由器和ESP8266偶发断连太正常了。我的处理逻辑是STM32每10秒查询一次ESP8266的MQTT连接状态如果断开就重新走一遍连接流程先连Wi-Fi再连MQTT。同时开启STM32独立看门狗IWDG主循环里喂狗一旦程序卡死在某个阻塞环节看门狗强制复位整个系统复位后再自动重连。这套组合拳做完系统在无人干预的情况下运行几个月不重启完全没问题。5. 现场调试与常见问题排查实录5.1 传感器数据异常排查现场调试遇到最多的问题是传感器数据不对。我把几个典型的坑整理成表基本覆盖了大多数情况现象可能原因排查方法SHT30偶尔读出0xFFI2C总线被干扰或上拉电阻不足检查I2C上拉电阻是否4.7K读数据加CRC校验温度正常湿度一直99%传感器敏感头被水汽凝结或损坏用热风枪吹干传感器检查外壳防水透气膜氨气数值开机就满量程传感器未预热完成或已到期老化初次使用预热24小时记录基线电压判断ADC数值跳变剧烈电源纹波大或地线回路不合理改用LDO供电模拟地与数字地单点连接BH1750读光照一直是0地址错误或模式未设置确认ADDR引脚电平对应地址连续高分辨率模式必须等待120ms最让我头疼的是氨气传感器稳定性的问题。刚开始系统跑着跑着氨气数值会缓慢爬升过几天就到了报警值。我以为是传感器坏了后来才意识到是传感器自身的基线漂移。环境湿度变大、温度升高都会影响半导体传感器的输出。解决的办法就是我前面说的每日基线自校准系统每天凌晨自动记录一个基线值把这个基线作为当天的零点参考漂移问题大大缓解。另外提醒一句任何传感器在猪舍这种高粉尘环境下都要加防护。我给传感器套了透气防尘帽定期拆下来用酒精清洁数据稳定性和传感器寿命提升明显。传感器是易耗品现场多备两套总能用到。5.2 通信掉线、设备重启与大坑实录远程通信掉线的问题排查起来其实有套路。如果ESP8266一直连不上路由器先用手机开热点对比测试能连上说明是现场路由器问题路由器换个位置或者加个信号中继就能解决。如果模块能连上Wi-Fi但连不上MQTT服务器大概率是服务器参数配错了用串口助手打印模块返回的ERROR信息对照AT指令手册逐条排查。我在现场调试时遇到过两次比较隐蔽的问题。第一次是继电器动作的瞬间整个系统直接重启。当时抓破脑袋想了很久最后用示波器量电源轨才发现继电器吸合瞬间在5V电源上产生了一个很大的电压跌落波形持续时间虽然只有几十毫秒但足以让单片机掉电复位。解决方案是把继电器模块供电改为独立的5V隔离电源同时STM32的3.3V电源输入端并一个470uF电解电容和100nF瓷片电容做储能缓冲。改完后再也没出现过继电器动作导致重启的问题。第二次是ESP8266运行一两天之后莫名卡死Wi-Fi断开后重连不上。排查到最后是ESP8266模块自身供电不足。ESP8266在发送数据瞬间电流峰值高达300mA如果供电电流不够模块会随机死机。我开始用AMS1117-3.3V给ESP8266供电根本扛不住后来改成专门的3.3V大电流稳压模块问题彻底解决。所有ESP8266项目都建议直接上5V→3.3V的DC-DC降压模块至少输出1A。5.3 猪舍环境给嵌入式开发者的施工建议最后聊几个现场施工的经验这部分在实验室里永远学不到。防水防潮是第一优先级。猪舍内湿度常年70%以上冲洗猪圈时水枪直接喷到控制箱附近。我的做法是所有电路板正反面涂三防漆传感器接线端子打热熔胶固定控制箱用带密封条的防水箱进出线用防水接头加线槽。涂三防漆之前先确认所有调试工作结束涂完就不能再焊线路了。防鼠防猪拱是第二优先级。猪对新奇的东西充满好奇拱一下控制箱、咬一下线缆都是常事。所有外露线缆必须穿PVC线槽或者金属软管控制箱固定在猪够不着、水溅不到的墙壁高位。继电器线束和传感器线束分开走避免强电电磁干扰耦合到信号线上。电子元器件的温度等级也要注意。我批量采购时就犯过只买民用级元器件的错误。猪舍夏天的温度加上设备自身发热控制箱内部温度能到50℃以上民用级芯片的标称工作温度上限一般是70℃看着够用但长期在温度临界边缘运行寿命衰减很严重。所以控制箱内部加了一个风扇温度超过45℃自动启动排风元器件尽量选工业级贵不了多少稳定性完全不是一个档次。调试工具方面强烈建议在STM32程序里预留一套串口命令调试接口平时用USART1输出分级日志LOG_INFO打印常规状态LOG_DEBUG打印传感器原始ADC值LOG_ERROR打印异常事件。现场排查问题的时候一根串口线和手机串口助手App就能看到系统内部状态比带着笔记本到处跑方便太多。资料这块我把全套工程文件整理好了完整原理图、PCB文件、STM32源码工程标准库版、ESP8266 AT指令配置文档、巴法云平台接入配置说明、外壳3D打印图纸都在里面。需要参考的读者在评论区给我留言或者私信我我看到都会发。做这个项目的过程中我自己也踩了不少坑我把这些经验全部写进了资料里的调试笔记希望能帮你少走弯路。