宠物保温箱恒温控制系统设计笔记
记录 PetBoxX 项目从不稳定到 ±0.1°C 恒温的全过程——硬件结构、PID 调参、热安全联锁、多箱型固件管理、风扇资质测试。
硬件结构
┌─────────────────────┐
│ PTC 加热器(顶部) │ 220V 交流,TRIAC 相位控制
│ PWM 风扇(中部) │ 12V DC,RPM 反馈
│ ABS 导风口(底部) │ 将热风横向分散到箱壁
└─────────────────────┘
↓
宠物保温区
控制核心是 ESP32,通过 MQTT 上报传感器数据(SHT30 温湿度)到云端 MySQL,同时接收远程调参指令。PTC 加热器额定功率分 100W / 200W / 300W / 400W 四档;箱体分三型:
| 型号 | 内部尺寸 | 外部尺寸 | 推荐功率 |
|---|---|---|---|
| S | 35×26×22 cm | 40×30×36 cm | 200W |
| M | 45×31×27 cm | 50×35×40 cm | 300W |
| L | 57×39×30 cm | 63×43×45 cm | 300W |
为什么用 PID?
保温箱的热力学本质是一阶惯性系统:
C · dT/dt = P_heater - P_loss
- C:箱体热容(空气 + 箱壁 + 宠物)
- P_heater:PTC 实际输出功率
- P_loss:与室温的温差散热
当系统达到稳态(dT/dt ≈ 0),加热功率正好补偿散热。PID 控制器的职责就是在动态过程中自动寻找这个平衡点,同时抑制扰动(开门、室温变化、宠物活动)。
PID 控制算法详解
基本公式
u(t) = Kp·e(t) + Ki·∫e(t)dt + Kd·de/dt
| 项 | 作用 | 当前参数 |
|---|---|---|
| Kp(比例) | 立即响应误差,误差越大输出越大 | 2.0 |
| Ki(积分) | 消除稳态误差,累积历史偏差 | 0.08 |
| Kd(微分) | 预测趋势,抑制过冲 | 6.0 |
实现细节(离散化):
// 温度变化率(低通滤波,避免噪声放大)
dTdt = α · dTdt_prev + (1 - α) · (t_meas - t_prev) / dt;
// PID 三项
p_term = Kp * err;
i_term += Ki * err * dt; // 积分累积
d_term = -Kd * dTdt; // 微分取负(dT/dt 正 → 减少输出)
u = p_term + i_term + d_term;
u = clamp(u, 0, 100); // 输出限幅
抗积分饱和(Anti-Windup)
积分项在输出饱和时继续累积会导致解饱和滞后("积分饱和"),表现为超调后长时间无法冷却。解决方案:条件积分——只在输出未饱和时累积积分:
if (!u_clamped) {
i_term += Ki * err * dt;
}
参数调节心得
| 现象 | 原因 | 调整方向 |
|---|---|---|
| 温度持续振荡 | Kp 过大 / Kd 过小 | 降 Kp,升 Kd |
| 稳态误差大 | Ki 不足 | 升 Ki |
| 超调后恢复慢 | Kd 过大压制了恢复速度 | 适当降 Kd |
| 响应速度慢 | Kp 过小 | 升 Kp |
控制状态机
控制器根据误差(err = setpoint - T_measured)和温度变化率(dT/dt)切换七种状态:
err ≥ 4°C ──→ BOOST 高功率急速加热,风扇 26~40%
err > 0.3°C ──→ HEAT 标准 PID 加热
|err| ≤ 0.3°C ──→ HOLD 低功率维持,风扇最低档
err < -0.3°C ──→ COOL 切断加热,自然冷却
特殊状态(叠加触发):
STALL: err > 0.3°C 且 dT/dt < 0.015°C/s 持续 5s → 增强输出冲破热平衡
FREEZE: |err| ≤ 0.1°C 且 |dT/dt| ≤ 0.0035°C/s → 暂停加热,节能静默
COAST: 接近目标时提前减速,防止过冲
设定值斜坡(SP Ramp)
冷启动时若直接给目标温度(如 37°C),err 突然达到 10°C 以上,BOOST 会以最大功率加热,极易过冲。解决方案:渐进式设定值,以 5.5°C/min 速率逼近目标:
sp_used = min(sp_used + ramp_rate · dt, sp_user)
箱体型号与缩放参数
不同尺寸的箱体,热容和散热面积不同,需要对 PID 输出做线性缩放:
| 参数 | S class | M class | L class |
|---|---|---|---|
| BOX_HEAT_SCALE | 0.87 | 1.00 | 1.15 |
| BOX_FAN_SCALE | 0.93 | 1.00 | 1.10 |
| BOX_RAMP_SCALE | 0.80 | 1.00 | 1.20 |
| BOX_DB_SCALE | 0.90 | 1.00 | 1.10 |
BOX_HEAT_SCALE 影响所有热量输出上限,例如: - M 类 BOOST 功率上限:160W - L 类 BOOST 功率上限:184W(多 15%)
一个真实的 Bug:两台箱子(一台 M 型,一台 L 型)早期都编译为 L class 固件。M 型箱子实际热容更小、温度变化更快,却用了 L 型参数:
| 参数 | 错误(L) | 正确(M) | 偏差 |
|---|---|---|---|
| 近目标热量帽 | ~132W | ~115W | +17W |
| BOOST 上限 | 184W | 160W | +24W |
| 风扇最低档 | 17.6% | 16% | 略偏高 |
结果:近目标时多送 15% 功率 → 过冲幅度更大 → ±0.4°C 振荡。修正箱型后恢复至 ±0.1°C。
热安全联锁
问题根源
ABS 塑料导风口的热变形温度(HDT)约为 80~100°C。当 PTC 以高功率运行而风扇转速很低时,PTC 出口热风温度远超安全值:
ΔT = P / (ṁ × Cp)
P = 157W,ṁ(风扇 15% ≈ 极低风量)→ ΔT 轻松超过 60°C
若室温 25°C,PTC 出口温度 > 85°C → ABS 开始软化变形
实际案例:旧版 Staged 控制以 157~200W 功率运行,风扇固定在 15~19%(安全联锁代码缺失),ABS 导风口在数小时后变形。
解决方案:风扇-功率硬耦合
// 热安全联锁:风扇转速不足时限制加热功率
if (fan_cmd < 5.0f) heat_cmd = 0.0f; // 风扇停转 → 禁止加热
else if (fan_cmd < 15.0f) heat_cmd = fminf(heat_cmd, pct_for_power_w(30.0f)); // 低风 → 最多 30W
else if (fan_cmd < 25.0f) heat_cmd = fminf(heat_cmd, pct_for_power_w(90.0f)); // 中风 → 最多 90W
// 25% 以上:不限制
这段代码在所有功率输出前执行,无论控制算法处于哪种状态,都不可绕过。
风扇特性曲线的影响
不同型号风扇的 PWM-RPM 特性曲线差异极大,是生产调试中最主要的变量之一。实际遇到过以下几类:
平台区型(常见):在某个 PWM 区间(如 20~35%)转速几乎不随占空比变化,超过阈值后陡升至高转速。
RPM
3200 | ╱
| ╱
1496 | ─────────────╱
1380 | ╱───
|
└──────────────────────────────→ PWM%
20% 35% 40%
陡峭曲线型(如 ARCTIC P9):低 PWM 区间几乎不转,需要 20%~25% 以上才进入有效转速区间,无法使用固定的低 HOLD PWM 运行。
固速型:PWM 信号对转速几乎无影响,风扇以内部固定速度运转(约 1350~1450 RPM)。温控仅依赖 PTC 调节,风扇充当固定循环气流源。
这种多样性促成了风扇资质测试的开发——通过标准化的自动测试流程,为每台设备确定安全可用的运行参数,见下节。
BOOST 跨越平台区问题:BOOST 状态风扇设定 26~40%,跨越了平台区与陡升区的边界,风量变化非线性,导致 PTC 出口温度估算偏差。目前通过设定 BOOST_FAN_MIN = 26%(固定值,不随箱型缩放)确保始终超出安全门限(25%)。
风扇资质测试(Fan Qualify Test)
生产过程中不同批次风扇特性差异极大,手动摸索每台设备的安全运行参数费时且容易出错。风扇资质测试通过标准化自动流程,一次运行输出可直接应用的控制参数。
测试流程
测试分两阶段:安全扫描 + 自适应 HOLD 搜索。
第一阶段:安全扫描(3 步)
| 步骤 | PWM | 最低 RPM 要求 | 说明 |
|---|---|---|---|
| 1 | 100% | ≥ 1500 | 确认风扇可高速运行 |
| 2 | 50% | ≥ 1000 | 确认中速稳定性 |
| 3 | 25% | ≥ 300 | 仅确认不失速 |
任意步骤未达最低 RPM → 等级 unsafe,整体失败。每步在给出 PWM 后等待 4~5 秒稳定,再测量 3 秒取均值。
第二阶段:自适应 HOLD 搜索
从低到高遍历候选 PWM(5%、8%、10%、12%、15%、20%、25%、30%、35%、40%),寻找落入 700~1200 RPM 理想区间的最低 PWM 点,作为 HOLD 运行点。
找到后,在此 PWM 下执行冷启动测试: 1. 停转风扇 3 秒(模拟真实冷启动场景) 2. 给目标 HOLD PWM,等待 12 秒稳定 3. 测量 8 秒取均值,RPM ≥ 700 方通过
控制等级(Control Grade)
| 等级 | 含义 | HOLD PWM |
|---|---|---|
good |
普通风扇,低 PWM 即进入理想区间 | ≤ 10% |
adjusted |
需适当提高 HOLD,仍在合理范围 | 11%~20% |
high_hold |
陡峭曲线风扇(如 ARCTIC P9),需较高 HOLD 进入理想区间 | > 20% |
high_airflow |
高转速风扇,25% 以上已超理想上限,使用降级 HOLD | 25%~40% |
weak_hold |
无法找到稳定 HOLD 点 | — |
unstable |
安全扫描中转速不稳定 | — |
unsafe |
安全扫描未达最低 RPM 要求 | — |
tach_fault |
FG 测速线路故障(无法读取 RPM) | — |
推荐参数与一键应用
测试通过后,系统自动推荐三个运行参数:
- HOLD PWM:找到的最低稳定点,用于 HOLD 状态持续低速循环
- NEAR PWM:50% 步骤测得的 RPM 对应 PWM,用于接近目标温度时的中速循环
- FAST PWM:100% 步骤 PWM(高于 NEAR),用于 BOOST / 快速升温阶段
管理后台支持一键应用:同时写入 ESP32 NVS 运行时参数与 LCD 屏端保存配置,无需分步手动操作。每次测试结果持久化到数据库,可随时回溯历史记录对比。
案例:ARCTIC P9 风扇(high_hold)
ARCTIC P9 在 20% PWM 以下几乎不转,需要约 25% 才进入 700~1200 RPM 理想区间,测试结果等级 high_hold。HOLD 时能耗相比普通风扇偏高,但温控效果稳定,实测符合要求。
案例:固速型风扇(unsafe)
部分风扇内部有自己的调速机制,PWM 信号对转速几乎无效,始终运行在固定约 1350~1400 RPM。这类风扇在 100% 步骤仍低于 1500 RPM 门限,得到 unsafe 等级。实际观察中,固速型风扇配合 PTC 单独控温稳态偏差约 ≤ 0.5°C,但固件的风扇调速策略完全失效,目前由运营团队人工评估是否上线。
FAN_CAN_STOP 的陷阱
早期代码中 FAN_CAN_STOP = true:当温度极稳定时,控制器进入 FREEZE 状态,同时允许风扇停转(静音优先)。但热安全联锁规定:风扇停转 → 加热功率降为 0。
于是出现了慢速振荡循环:
温度稳定 → 风扇停 → 加热禁止
↓
温度慢慢下降(散热)
↓
err 超门限 → 风扇重启 → 加热恢复
↓
温度回升 → 稳定 → 风扇再停 → …
周期约 10~20 分钟,幅度约 ±0.2~0.3°C。设置 FAN_CAN_STOP = false 后,风扇始终维持最低档(由风扇资质测试确定的 HOLD PWM),加热可随时响应,振荡消失。
传感器偏置与校准策略
SHT30 贴近 PTC 加热器出口安装,读数比箱内平均温度高 1~2°C。这是结构性偏置,不是传感器误差。
错误的校准方式:一次性施加 -1.8°C 校准偏移 → 控制器突然"看到" 1.8°C 误差 → BOOST 以 157W 猛冲 → 风扇仍在低速 → ABS 导风口再次变形。
正确的校准方式:每次调整不超过 -0.5°C,间隔 30 分钟,观察温度曲线是否重新稳定后再调下一步。
多固件构建流程
不同箱型、不同 PTC 功率需要单独编译固件。脚本自动替换源文件宏、编译、上传,构建完成后还原源文件:
VARIANTS=(
"1.1.10-200w-S PETBOX_PTC_POWER_200W PETBOX_BOX_CLASS_S"
"1.1.10-300w-M PETBOX_PTC_POWER_300W PETBOX_BOX_CLASS_M"
"1.1.10-300w-L PETBOX_PTC_POWER_300W PETBOX_BOX_CLASS_L"
)
每次构建三个变体,通过 OTA(空中升级)分发到对应设备。版本号编码了 PTC 功率和箱型,方便日志排查。
调试经验总结
- 先对齐箱型:错误的 BOX_CLASS 是参数缩放根源,所有调参工作应在正确箱型下进行。
- 热安全联锁是硬约束:不能为了性能绕过它,宁可温控慢一点,也不能烧熔塑料件。
- FAN_CAN_STOP 默认关闭:静音优先的代价是引入慢振荡,生产环境不值得。
- 校准要渐进:传感器偏置是系统性的,但补偿动作会触发控制器响应,必须小步走。
- 看实际功率而非占空比:TRIAC 占空比和实际瓦数之间有非线性关系(PTC 冷态阻抗低,热态阻抗高),分析时用换算后的瓦数更直观。
- 数据驱动:所有调参决策均基于 MySQL 历史遥测数据(温度、风扇 RPM、加热档位、控制模式),不靠直觉。
- 先跑风扇资质测试:每台新设备接线后第一步跑风扇资质测试,确定 HOLD / NEAR / FAST PWM 参数后再调温控。不同批次风扇曲线差异足以导致热安全联锁误触或 HOLD 失速,不能假设参数通用。
PetBoxX 项目持续迭代中,当前稳定版本:1.1.10。