基于STM32的仔猪保温箱自动恒温控制系统设计与实践

发布时间:2026/9/13 22:35:00
基于STM32的仔猪保温箱自动恒温控制系统设计与实践
养过仔猪的朋友基本都体会过“半夜起来看温度”的滋味。初生小猪皮薄毛稀体温调节能力差保温箱里温度稍微掉几度腹泻、压堆、被母猪压死的情况马上就来。早期我用的是灯泡加棉被靠人肉定时巡检温度忽高忽低不说人还熬不住。后来我花了两周时间用一块STM32单片机把保温箱改造成了自动恒温控制系统测温、加热、报警、故障保护全部自动化一个产季用下来稳定不少。这篇就把完整的设计过程、选型理由、软件逻辑和现场调试踩过的坑都记录下来给想做养殖环境控制的朋友提供一点参考。1. 项目分析与系统方案选型1.1 初生仔猪的保温需求和控温目标仔猪跟大猪不一样它出生后体内糖原储备少体温调节中枢又没发育完全环境温度稍微一低就会通过堆积、打颤来维持体温这不仅白白消耗能量还会导致吃奶不足、拉稀、生长迟缓。生产上常用“保温箱红外灯”的方法但红外灯固定功率很难跟随环境温度变化天气暖和时箱内可能烤到40℃寒潮一来又可能只有25℃。所以保温箱控制的第一个核心需求是让箱内温度稳定在一个随日龄下降的目标区间。按比较通行的经验1到3日龄箱内温度保持在32到34℃4到7日龄降到30到32℃8到14日龄28到30℃之后可以继续每周降2℃直到仔猪不需要额外加温。这个目标区间就是后续控制算法里温度的设定依据。除了精准控温设计还必须考虑现场养殖环境的“恶劣程度”。产房里湿度长期很高氨气浓度也不小小猪还会拱、咬、蹭各种线缆和设备。普通电子设备直接塞在箱内大概率一两周就出问题。因此在系统方案设计初期我就定了几条硬性要求传感器要防水耐腐蚀加热设备要远离仔猪可接触范围控制电路最好放到保温箱顶部的夹层里并且要有传感器断线、超温、看门狗这几类故障保护。不能只实现“能加热”还得保证“坏了以后能报警而不是把猪烤了”。1.2 STM32主控与整体系统框架怎么搭主控芯片我选了STM32F103C8T6。这颗MCU属于Cortex-M3内核主频最高72MHzFlash 64KB、RAM 20KB对于测温、控制、报警这些任务来说性能完全溢出。选择它最重要的一点是资料极其丰富CubeMX配置、标准库、HAL库的例程一搜一大把和各类传感器的适配案例也多哪怕零基础也能快速上手。用更贵的G0系列或者国产替代当然也行但自己做项目讲究的是“能稳定跑、有问题查得到”F103C8T6在这个场景里是最稳妥的选择。整体系统按功能可以拆成四个部分感知端、控制端、执行端和人机交互端。感知端用DS18B20防水温度探头测量箱内温度控制端就是STM32最小系统负责读取传感器、执行控温逻辑执行端是加热灯和排风扇加热灯用固态继电器驱动排风扇用普通继电器驱动人机交互端包括OLED显示屏、按键和蜂鸣器用来设定目标温度、切换手动自动模式、显示当前温度和报警状态。电源部分单独设计220V交流先经过EMI滤波和开关电源转成12V或24V再经DC-DC隔离降压给控制板供电避免加热灯启动瞬间的电压跌落干扰单片机。整套框架说白了就是“传感器感知→单片机决策→执行机构动作”没有花哨的东西但每一步都得考虑现场可靠性。2. 硬件平台的搭建与关键元器件选择2.1 STM32最小系统与晶振电容计算STM32最小系统说起来很简单3.3V供电、8MHz外部晶振、复位电路、BOOT引脚配置、SWD调试接口。但实际画板或者做手工板时有几个细节特别容易坑人。先说晶振很多人直接用8MHz晶振加两个22pF电容其实这个电容值应该和晶振的负载电容匹配。晶振负载电容CL的计算公式是CL C1×C2/(C1C2) Cstray其中Cstray是PCB走线和引脚产生的杂散电容一般取3到5pF。如果晶振规格书上标的负载电容是20pF走线杂散4pF那么C1、C2取22pF时CL约为15pF和20pF略有不匹配但大部分情况下还能起振。如果追求精准把电容换成30pFCL就是19pF更接近标称值。我自己习惯先按22pF用调试时用示波器看波形不起振或有谐波再调整。供电部分我用的是一块AMS1117-3.3线性稳压器把5V降到3.3V输入和输出端各加10uF电解电容和100nF陶瓷电容。这里要特别提醒STM32的VDDA引脚最好单独用磁珠和一个1uF电容做滤波因为芯片内部ADC的参考电压就从VDDA进来而产房里开关电源的纹波一般比较大如果VDDA不干净后面DS18B20读数的抖动会比平时大不少。复位电路就是10k电阻上拉加0.1uF电容对地这是标准接法。BOOT0直接接10k下拉到GND从主Flash启动。调试接口保留4针SWD只接SWDIO、SWCLK、GND、3.3V四个信号比JTAG少占引脚还抗干扰。2.2 温度传感器选型为什么我最后选了DS18B20保温箱测温方案常见的有热敏电阻NTC、DS18B20、SHT3x系列数字温湿度传感器甚至还有人用PT100铂电阻。PT100精度高但需要调理电路和基准电阻成本偏高在这个场景里属于杀鸡用牛刀。SHT30精度不错、带I2C接口但传感器探头本身不防水必须在外面加通风帽产房湿度大了还容易凝露。热敏电阻便宜但标定麻烦阻值和温度的关系是近似曲线不同批次还可能有差异用起来心里没底。DS18B20是我最终选定的方案单总线协议只占一个IO口多个传感器还能挂同一条线测温范围-55℃到125℃在养殖场景里绰绰有余12位分辨率下精度可以做到±0.5℃满足保温箱控温需求关键是有很多不锈钢防水封装的成品探头插到箱内壁的支架上就行不用担心小猪咬线和水汽侵蚀。DS18B20的硬件连接非常省事数据引脚接STM32某个GPIO再接一个4.7k上拉电阻到3.3V信号线两端距离不超过3米的话不需要额外处理。如果现场线拉得长建议用屏蔽双绞线屏蔽层单端接地减少电机、继电器启停带来的干扰。还有一个容易忽略的细节单总线协议对时序要求比较严格GPIO必须配置成开漏输出这样才能保证主机释放总线时被上拉电阻拉高。用推挽输出虽然也能工作但时序余量变小线一长或者环境温度一高就容易偶发误码。2.3 加热器驱动电路设计继电器还是固态继电器加热执行机构我一开始用的是传统机械继电器加红外加热灯后来发现机械继电器在频繁开关下触点寿命下降很快而且触点通断瞬间容易产生火花在产房这种可燃粉尘和氨气环境下总觉得隐患不小。第二次改版换成了固态继电器SSR控制信号端用光耦隔离输出端是双向可控硅没有机械触点通断无火花寿命长得多。对于150W左右的加热灯选用10A等级的SSR就足够还能留出余量。如果坚持用机械继电器必须做好两项保护一是继电器线圈两端并一个1N4007续流二极管用来吸收关断瞬间的反向电动势否则驱动三极管很容易被打坏二是触点两端并联一个RC阻容吸收电路也就是几十欧电阻串联几十纳法电容用来抑制触点分断时的电弧。机械继电器的开关逻辑还要注意不要让它在温度临界点频繁通断否则触点温度升高最终会因为烧结或氧化而失效。我在后面的控制算法里专门设计了一个滞回区间同时限制了最短切换间隔这些细节都是从实际故障里学来的。3. 软件逻辑与核心控制算法实现3.1 温度采集滤波与传感器故障识别DS18B20的软件驱动并不复杂但有几个地方不去查资料真的容易卡住。单总线通信的核心是严格的时序初始化时主机拉低至少480us再释放然后检测总线上的应答脉冲写0和写1的时间片不同读时序也有固定窗口。我用HAL库加延时函数实现这里给一个简化版的读取温度主流程复位→发送ROM命令跳过ROM→发送温度转换命令→等待750ms转换完成→复位→跳过ROM→发送读暂存器命令→连续读取9个字节→校验CRC→根据高字节和低字节计算温度。CRC校验特别重要尤其是现场布线长、干扰强的时候没有校验的读数据偶尔会出现一个离谱的跳变值比如突然显示85℃或者负55℃。85℃实际上是DS18B20上电复位的默认温度寄存器值如果读到85℃八成是通信失败程序只读到了复位后没来得及转换的数据。温度数据进控制逻辑之前我加了一个滑动平均滤波取最近10次有效值求平均。为什么不用一阶低通滤波因为在温控场景里一阶滤波的系数需要根据采样周期和对象时间常数去调调不好要么滞后太大要么滤波效果差滑动平均窗口固定数据更直观调试时看到异常值也容易定位。滤波的同时我还做了一个简单的传感器故障识别连续5次CRC错误或者温度值落在0℃到50℃范围之外就判定为传感器故障系统立即停止加热并发出声光报警而不是用错误数据继续控制。这是整个设计里最关键的“兜底”逻辑之一宁可让猪冷一会儿也不能让猪被烤到。3.2 滞回控制与PID温控的取舍很多做温控的人一上来就上PID但保温箱这个对象温度惯性大、时滞明显冬天和夏天的环境温差也很大固定参数的PID非常容易振荡。我自己第一版代码直接照搬了一个位置式PIDKp、Ki、Kd调了一个小时也没找到合适的值箱内温度在设定值附近来回震荡加热灯一会儿全功率一会儿停继电器烧掉一个。后来我换成工程上更常用的滞回控制设定目标温度30℃回差0.5℃那么当箱内温度低于29.5℃时开启加热高于30.5℃时关闭加热。这样加热灯不会在临界点频繁启停控制逻辑简单可靠对保温箱这种对精度要求并不苛刻的场合完全够用。核心控制代码片段如下#define TARGET_TEMP 30.0f #define HYSTERESIS 0.5f #define MIN_ON_TIME 60 // 最短加热时间单位秒 #define MIN_OFF_TIME 60 // 最短关闭时间单位秒 uint8_t heat_on 0; uint32_t last_switch_tick 0; float current_temp; if (heat_on) { if (current_temp TARGET_TEMP HYSTERESIS) { if (HAL_GetTick() - last_switch_tick MIN_ON_TIME * 1000) { heat_on 0; last_switch_tick HAL_GetTick(); } } } else { if (current_temp TARGET_TEMP - HYSTERESIS) { if (HAL_GetTick() - last_switch_tick MIN_OFF_TIME * 1000) { heat_on 1; last_switch_tick HAL_GetTick(); } } } HAL_GPIO_WritePin(HEAT_GPIO_Port, HEAT_Pin, heat_on ? GPIO_PIN_SET : GPIO_PIN_RESET);注意代码里加了最短开关时间限制哪怕温度突然跌破区间也要等上一次动作满60秒后再切换。这个限制对机械继电器尤其重要能显著延长触点寿命。如果以后你想做更高精度的恒温比如实验室或者手术台场景可以在滞回基础上再加入PWM调功用固态继电器接收周期固定、占空比随误差变化的PWM信号本质上是把加热灯从“开/关”变成“平均功率可调”这时候再用增量式PID输出0到100%的占空比控温精度能到±0.3℃以内。但在产房现场环境干扰太多过分追求精度没有实际意义稳定可靠才是我最看重的。3.3 超温保护、看门狗与运行状态机软件不能只在温度偏离区间时去开加热还得把“异常”放在最高优先级。我设计了一个简单但完整的状态机分为正常加热、传感器异常、超温保护、手动模式四个状态。正常加热状态下系统根据滞回算法控制加热灯和排风扇手动模式下操作人员可以通过按键直接打开或关闭加热灯方便清圈或临时观察仔猪情况传感器异常状态下系统立即停止加热点亮报警灯并让蜂鸣器周期性鸣叫超温保护状态下加热灯强制关闭排风扇强制打开同时记录超温时间。这个状态机的好处是任何异常都不会出现“加热灯还继续工作”的失控情况。超温保护除了软件逻辑我在硬件上还加了一个85℃的常闭温度保险丝串在加热灯回路中。软件跑飞或者单片机死机都不可怕串在动力回路的温度保险丝是最后一道物理屏障。软件方面我开启了STM32内部的独立看门狗IWDG喂狗操作放在主循环的固定位置并且严禁在中断里喂狗否则看门狗就失去了作用。关于看门狗还有个坑IWDG时钟来自LSI大约40kHz分频后溢出时间可以算出来。我配了分频系数64、重装载值625溢出时间约1秒这样主循环卡住超过1秒系统自动复位加热引脚恢复为默认电平。同时单片机复位后通过读取RCC标志位来判断复位来源如果检测到是看门狗复位就在OLED上显示一次提示信息方便现场排查是程序死循环还是电源干扰。4. 箱体结构、传感器安装与现场注意事项4.1 保温箱尺寸、材质与电气布局保温箱不是随便拿个木头箱子就行。常见的产房保温箱长度1.1到1.2米宽度0.7到0.8米高度0.6到0.7米一侧开一个供仔猪自由进出的小门顶部做成可打开的盖板。箱体材料我用了双层PVC中空板中间填充了2厘米厚的XPS挤塑板保温性能比单层木板好很多而且表面光滑清洗消毒方便。箱体顶部靠近后部的位置留一个直径15厘米的排风孔安装一个小型轴流风扇既可以在超温时强制排风也能在箱内二氧化碳、氨气浓度升高时定时通风。风扇不要直吹仔猪休息区要在侧面向上倾斜安装让空气先经过加热区再自然回流。电气部分必须遵循一个原则强电和弱电分开走控制板不要放在箱体内部。我把STM32控制板、固态继电器、开关电源都放在箱顶的一个独立防水盒里所有穿过箱体的线都从防水接头进防止仔猪咬线和液体渗漏。加热灯用带防爆网罩的150W红外灯通过链条或挂钩悬在箱内一侧距离箱底至少40厘米避免小猪抬头碰到。灯罩上方要留出至少20厘米的空间否则热量堆积在箱顶容易把板材烤变形。排风口和传感器避开加热灯直射区各自独立布置这样整个保温箱内部形成“一侧加热、一侧休息”的温度梯度猪觉得热了自己爬到凉快的一侧觉得冷了再回到热灯下这种自然行为调节比人工强制恒温更健康。4.2 温度探头安装位置与线缆防咬保护温度传感器安装位置直接决定控温准不准。我第一版直接把DS18B20探头吊在加热灯正下方结果灯一亮探头被近红外辐射直接加热显示温度比实际箱温高不少加热灯反而频繁停猪在下面冻得直叫。后来我把探头移到保温箱的休息区安装在离加热灯侧面至少30厘米的位置探头悬在离箱底5到8厘米的高度正好是仔猪趴卧时背部的高度。这样测到的是仔猪真正感受到的环境温度而不是加热灯表面的辐射温度。如果条件允许可以给探头套一个白色金属辐射罩减少箱壁和灯的辐射影响控温效果会更好。线缆防护是个容易被低估的问题。小猪的牙齿虽小但好奇心极强裸露的传感器线和电源线只要被叼住咬断是分分钟的事。所有箱内走线我都穿上了耐高温波纹管出线口向下弯一个U形弯防止冷凝水顺线流进接头。传感器探头和线缆接头用热缩管加防水胶处理尽量不在箱内留插拔点。箱外连接控制板的线束全部走线槽并固定到箱体侧面避免被母猪踩踏或者小猪拉扯。实际用过就会发现很多所谓“单片机莫名其妙故障”最后查下来就是一根被咬断半截的信号线造成时好时坏。5. 调试中常见的几类故障与解决实录5.1 温度读数跳变和异常值调试时第一个遇到的是DS18B20读数跳跃有时候是正常的31℃下一秒突然跳到25℃再下一秒又回来。排查顺序建议先看硬件再查软件先确认GPIO是否配置为开漏输出数据线上拉电阻是不是4.7k有些便宜模块板载上拉是10k线一长就不稳再检查电源开关电源的输出纹波过大时DS18B20读取时序会出错可以在传感器供电端再加一个10uF电容和100nF电容最后检查程序里的读时序延时是否准确用HAL_Delay配合系统时钟配置不能想当然认为延时函数精确。传感器显示85℃是另一个高频问题。这个值本质上是DS18B20上电后暂存寄存器里的默认值如果转换命令没生效或通信失败程序就会读到它。我调试时发现原因经常是复位脉冲和应答脉冲之间少了延时或者主机在读取时没有按照标准的时隙等待。这个问题最有效的排除方法就是先拿一个逻辑分析仪抓单总线波形看哪些时隙不对。如果没有逻辑分析仪可以降低一个台阶先只读一个传感器确认单点通信正常后再扩展多个传感器共用一条总线。5.2 死机、重启与继电器误动作保温箱工作环境里最大的干扰源不是温度传感器而是加热灯和排风扇启停瞬间的电流变化。我的第一版电控板只要加热灯一关OLED偶尔就会白屏单片机直接复位。后来用万用表量发现220V到开关电源的线路太长且没有滤波感性负载关断时在线上感应出很高的尖峰电压耦合进控制板供电。解决办法是在220V输入端加一个EMI滤波器控制板供电改成隔离型DC-DC模块同时给单片机所有输入输出口串接1k电阻和100nF电容。处理后干扰问题基本绝迹。还有一次系统频繁复位查了很久才发现是看门狗配置有问题。独立看门狗开启后我在ADC中断里也喂了一次狗。按键长按测试时主循环被阻塞中断里的喂狗让系统以为程序还在正常跑结果按键一直按住超过溢出时间系统才无奈复位。这也算是一个比较少见的经验喂狗只能放在确定性最高的主循环固定位置中断里喂狗会破坏看门狗监测主流程超时的意义。另外如果使用了PB3、PB4等引脚连接按键或传感器需要先禁用JTAG只保留SWD否则这些引脚在默认复用状态下电平不受控制很容易出现按键误触发。5.3 加热灯寿命短和继电器打火加热灯频繁开关钨丝在冷热交替下容易断裂这是机械继电器方案最大的问题。一个150W红外灯泡如果每小时开关十几次正常寿命可能从几个月的量级缩短到两三周。除了调整控制算法、拉大滞回区间、设置最短开关间隔之外硬件上最彻底的解决方案就是换固态继电器。固态继电器本身没有机械触点再频繁通断也不会打出火花驱动电流也小控制侧可以直接接STM32的GPIO。买SSR时注意要选过零型还是随机型加热灯属于阻性负载用随机型固态继电器可以对输出电压斩波实现调功功能如果只做开关控制过零型更合适电磁干扰更小。无论哪种输出端都要配一个足够大的散热片哪怕电流很小散热条件差也会让可控硅温升过高。如果暂时不想换SSR至少要在机械继电器触点两端并RC阻容吸收并在线圈两端并续流二极管触点容量选大一档比如实际负载2A继电器选10A。安装时继电器不能紧贴单片机至少隔开5毫米以上否则触点动作时的磁场可能影响旁边MOS管驱动。最后还有一个不起眼的坑加热灯防护网如果不用耐高温材料时间久了会被烤脆碎裂碎片掉进箱内会造成安全隐患一定要选择带陶瓷或铁丝搪瓷防护罩的成品灯并且三个月检查一次。做了差不多一个完整产季我的体会是STM32保温箱这个项目难点不在单片机编程而在“这个设备要到什么样的环境里干活”。你会遇到湿度、氨气、小猪啃咬、电压波动、加热灯寿命各种问题单片机代码反而只占很小一部分。方案从机械继电器改到固态继电器从PID改回滞回控制每一步都是被现场问题逼出来的。如果你也想做类似的项目我建议先把温控目标和安全逻辑想清楚再动手画板写代码不要一上来就堆参数调PID。这个系统后续还可以扩展定时通风、饲料投喂提醒、远程报警等功能只要把STM32的串口或无线模块预留出来功能升级并不难。