从PID到二分法:定值控制的15次优化全记录 一句话: 定值控制从 PID 弃用改二分法又做了 15 次迭代优化——过充、误停、收敛慢、精度差每个问题一次修复一次实测。最终收敛从 36s 降到 3.8s过充从 135% 降到 1% 以内。适合谁读做恒温、恒压、稳流这类稳定到目标值的控制、被 PID 调参和迭代调优折腾的嵌入式工程师。先想一个场景调恒温热水器想象把热水器设定在 40°C 并保持住你会遇到一串问题一打开第一把火开太大水温冲到 60°C过充水温稳定后你又改了设定结果又是从头来一遍大冲跳变水会自然降温漂移需要持续小调热水器还有安全保护温度异常就自动停机安全逻辑——但偶尔它把正常波动也误判成异常自己停了误停。这篇记录的定值控制优化就是把这串问题逐个解决的过程——从 PID 一路改到二分法又做了 15 次迭代。每次改了什么、为什么改、实测效果如何一次说清楚。一、为什么弃用 PID最早用的是位置式 PIDP20、I3输出直接写。实测发现两个问题增益耦合系统增益由输入信号强度决定弱输入下输出-测量斜率只有 0.007强输入下是 0.046差 6 倍。一套 PID 参数在不同工况之间要么超调要么太慢按工况调参又违背通用初衷。查表失效标定数据有限查表覆盖不全。决定弃用 PID改二分法定值控制。二分法不需要模型、不需要增益先验天然自适应。二、二分法基础版v1搜索区间 [0,400]0.3s/步设中点输出 → 等稳定 → 读测量值比较 → 收缩区间 收敛 → 保持 → 微调闭环固定步进 5/0.3s连续 20 次停机兜底上板能用但问题一串。三、15 次优化迭代记录① 稳定运行几秒后自动关闭v2现象稳定运行 ~6 秒后自动停机。排查保持微调每 0.3s 检查测量值只要在 ±0.1 阈值外就计数不区分方向20 次6s触发停机兜底。测量有噪声来回抖但每笔都记正常状态被当成调不动。修复① 修正计数改为同方向才累加——方向一变偏大↔偏小清零重来噪声来回抖永远攒不满② 真故障单向漂移调不动照样 20 次停机。② 死区太粗精度不达标v3需求是稳定在 ±0.01原来死区 0.1。收紧到 0.01——但这一步暴露了后面的连锁问题。③ 首次使能过充 135%v4现象目标 2一使能测量值冲到 4.689过充 135%。根因二分法初始化直接在 [0,400] 中点起步——第一拍设 200高目标无所谓低目标直接打穿。修复起点改为小区间 [0,100]中点 50起步低目标不过充高目标靠区间扩展上去见④。④ 3/11 目标被误杀v5现象通道 1 目标 3、通道 4 目标 11 频繁 FAIL但这两个值明明可达实测上限 12/20。根因200 起步时测量过冲 → hi 被提前收缩 → lo 追上来区间收窄5触发区间收敛判定 → 误判输出不够停机。搜索起点过冲把搜索空间锁死了。修复起点 50 后 hi 不再被过冲收缩同时加区间扩展——区间收敛但测量未达标时hi 50 继续搜上限 400扩到顶仍不够才停机。⑤ 运行中改目标跳变过充v6现象稳定运行中改目标值输出瞬间跳 200。根因目标变化走Init()从零搜索第一拍又设中点 200。修复新增Retune()——目标变化时以当前输出 ±100为新区间重搜第一拍输出保持不动。过充消除。⑥ 运行中切通道不生效v7现象屏上切通道显示变了实际还是旧的。修复切通道时若正在运行自动全关回空闲状态机下一拍自动重新加载新通道配置重新搜索收敛。⑦ 收敛 36 秒太慢v8~v11这是最折腾的一段。最初目标 1.3 要 36s 才进 ±0.01v8 快搜搜索步 0.3s→0.05s。无效——实际还是 0.1s/步。v9 查调用粒度发现二分法挂在主循环100ms的时基标志上宏写多少都被压成 100ms/步。宏值 ≤ 调用间隔时全部无效。v10 加 50ms 时基新增 50ms 时基标志二分法 50ms 粒度调用。搜索真正提速。v11 试 0.02s调用粒度改 10ms 步进 20ms——失败。测量瞬态还没建立就读数二分方向误判搜索失控推到顶格。认识了硬件下限测量建立时间 ~100ms50ms 是可靠下限。⑧ 高目标精度达不到 ±0.01v12~v13现象低目标能进 ±0.01高目标511偏差 0.020.03。根因高值区斜率大固定 0.5 步进对应 0.025 的跳变一跳就跳过死区窗口在边缘振荡。修复动态步进——实时估计斜率搜索步进天然产生 Δ测量/Δ输出 样本滤波 死区过滤 限幅步进 0.01 ÷ 斜率限制在合理范围。每次修正变化正好落在死区。插曲连续测试时高目标又偏——排查发现斜率状态跨组污染上一组的斜率滤波值带到下一组重新搜索时重置斜率基准解决。⑨ 50ms 间隔还是慢v14——最隐蔽的 Bug现象微调间隔已改 50ms收敛还是 20s。用测试脚本跟踪输出值发现每 2 秒才变一次——微调根本没按 50ms 跑根因保持延迟判断和微调节奏共用了同一个时间戳变量。微调更新变量后下一次延迟判断把它当成进保持时刻——还没到 1.5sbreak。微调实际每 2.5s 才执行一次50ms 间隔形同虚设。修复延迟用独立变量。收敛从 36s 直接掉到 5.7s。⑩ 偏差分级步进v15大偏差0.05时步进 ×3 快速拉回小偏差正常精收敛。收敛进一步降到 3.8~5.1s。⑪ 高值漂移误停v16保持延迟从 2.5s 压到 1s 后高值保持期自动关闭——高值热漂移还没稳定微调追不上同方向 60 次3s误停。修复① 延迟回 1.5s②修正有效性检查——修正后偏差缩小 ≥30% 才算有效清零计数只有修正无效测量不动/更差才累计停机。真故障 3s 兜底保留。四、最终结果指标初始最终收敛到 ±0.0136s3.8~5.1s首次使能过充135%≤1%误停/误杀频发13/13 全过稳定精度±0.1±0.01切换/改目标不生效/跳变全部正常五、经验总结先修测量再谈控制传感器系数没标定前所有精度结论都是噪声。换硬件后增益变了 2 倍多系数更新才谈 ±0.01。调用粒度是隐藏约束宏值 ≤ 调度周期时调宏等于没调——先查谁在调用它、多久调一次。一个变量被两处用早晚出事时间戳变量复用导致微调被压成 2.5s 节奏这类 Bug 靠读代码发现不了要靠实测输出曲线。测量噪声决定控制下限死区 0.01 成立的前提是噪声 0.01——先测噪声再定死区。硬件漂移是控制追不动的测量通道 0.8%/2min 的慢漂移控制能追修正速率 40 倍余量但要给足收敛时间。六、七个经典技巧速查表上面 15 次迭代沉淀出的七个可复用技巧每个解决一类典型问题技巧解决的问题核心思路起点小区间第一拍打穿过充 135%初始区间 [0,100] 起步低目标不过充区间扩展搜索空间被过冲锁死区间收敛但未达标时 hi50 继续搜扩到顶才停机动态步进固定步进跳过死区实时估计斜率步进 目标变化 ÷ 斜率限幅偏差分级大偏差收敛慢偏差 0.05 时步进 ×3 快速拉回同方向计数噪声误触发停机方向一变清零只有连续同方向调不动才算故障修正有效性追漂移被误杀偏差缩小 ≥30% 才算有效修正无效才累计增量重搜改目标跳变过充以当前输出 ±100 重开区间第一拍输出不动组合使用效果收敛 36s→4s过充 135%→1%误停全消精度 ±0.01。核心思想控制算法的问题一半出在测量噪声/瞬态一半出在判据什么时候算收敛、什么时候算故障——算法本身只是骨架判据才是灵魂。实测对比PID弃用→二分法15次迭代36s收敛→3.8s过充135%→0.2%误停频发→13/13全过有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。下一篇死区 静默期两个被低估的 PID 优化——PID 控制的另一面