用户拍板 COIL_L_MIN_UH=25 (43nF 口径) - 频率窗上限 171→153kHz (f@25µH=153.5k; 153=L25.16µH 正常/154=L24.84µH 偏小) - L<25µH(f>153k) → 断开级快闪 (判定/指示/防抖 5s 逻辑不变) - 提示: 现场 21/23µH 测试线圈(f≈164k>153k)将再入断开快闪区, 需换 ≥30µH - test 边界 153/154; 4 测试全绿 语法0 error; spec V2.39 / manual / devlog V2.58
98 KiB
DLD154V4B 开发日志
MCU: AT32F421F8P7 (Cortex-M4, 120MHz) | 线圈通道: 1路 | 调试口: TTL Tx
2026-09-04 — 最低电感量下限 20µH → 25µH(固件 V4.36.22)
用户拍板:COIL_L_MIN_UH 20 → 25(43nF 口径)。
- 频率窗上限 171→153kHz(f@25µH = sqrt(2.533e7/(25×43)) = 153.5k;153k=L 25.16µH 正常 / 154k=L 24.84µH 偏小)
- L<25µH(f>153kHz)→ 断开级快闪(判定/指示逻辑不变)
- 注意:现场 21/23µH 测试线圈(f≈164k > 153k)将再次进入断开级快闪区——如需继续用需换 ≥30µH 线圈
- test 边界:153 正常 / 154 偏小;全绿 语法 0 error、4 测试全绿;REV 4.36.22;spec V2.39 / devlog V2.58。
2026-09-04 — 电感量下限判定防抖加长 1s→5s(固件 V4.36.21)
用户需求:电感量下限(L<20µH → 断开级快闪)重要,但要确保不误检,判定时间可以加长。 防抖 COIL_FAULT_HOLD_TICKS 100→500 tick(1s→5s,TaskLoop.h 宏):
- 越界置位与恢复清除都走 5s 连续确认(防起振/瞬态 f 冲高 171k 误报断开级快闪)
- 判定线不变(18~171kHz / L≥20µH)
- test 全用例同步 5s 语义(499 不置位/500 置位) 语法 0 error、4 测试全绿;REV 4.36.21;spec V2.38 / devlog V2.57。
2026-09-04 — 最低工作电感量 COIL_L_MIN_UH=20µH,低于则按线圈断开指示(固件 V4.36.20)
用户需求:设定最低电感量工作值(默认 20µH,43nF 低频档口径,宏定义), 当线圈电感量低于该值时,车检器黄灯快闪、以"线圈断开状态"来指示。
- 新增
COIL_L_MIN_UH 20(TaskLoop.h);频率窗上限 125→171kHz(=20.06µH, 43nF: L=2.533e7/(f²×43))——20~38µH 小线圈(含现场 21/23µH 测试线圈)转为可正常工作 coil_fault==2(f>171kHz, L<20µH)归入黄灯模式1 断开级快闪(200ms toggle), 与 !LOOP_OK/reconn_stab 同级;一长一短(模式5)仅保留给coil_fault==1(L 偏大 f<18kHz)- coil_monitor 防抖不变(越界/恢复 1s);继电器/判定逻辑不受影响(仅指示级)
- test 边界:171 正常 / 172(L<20µH) 偏小;L 偏大 17;全绿 语法 0 error、4 测试全绿;REV 4.36.20;spec V2.37 / devlog V2.56。
2026-09-04 — 故障补偿触发幅度量化说明(文档 V2.55,无代码改动)
用户要求文档给出"多大的环境变化触发黄灯常亮"的具体数字。 代码核实:触发 = dev=CAPVD−Origin > +4×dlt(纯比例制)连续 2s(ENV_WARN_WAIT=200, 黄灯预判锁存)→ 连续 7s(ENV_RESYNC_WAIT=700)学习替换 Origin → 空闲 2s 黄灯灭。 换算(L∝Xn²,dL/L≈2×dXn/Xn):SENS=3 触发幅度 +0.15% Xn ≈ 等效电感量上升 +0.31%; SENS=0 为 +2.06% Xn ≈ +4.11%。仅处理 L 上升方向;L 下降=车辆语义冻结(10s 兜底更新)。 spec 4.4.2 补量化表(分 SENS 档);manual 4.x 故障补偿补一句。
2026-09-04 — 低Q 释放抗抖(固件 V4.36.19)
固件版本:V4.36.19。devlog 修订 V2.54。spec V2.35 / manual 已同步。
问题:43nF 低频、高灵敏、低Q(50µH 以下) 线圈——金属板感应边界反复试探 (快释放停住→缓慢离开),触发高度稳定但释放高度越拉越远,最终绿灯长亮释放不了; 高Q 无此问题。关键旁证:开 DEBUG 打印复现不了、禁打印可复现——PRINT 阻塞 把 vd1_task 样本间隔从 10ms 拉到 50ms+,等效低通,抖动被平均。
根因:释放带回仅 dlt_rel=23 counts(0.018%@128k)≈ 低Q 抖动 σ(±15~25),
快值直接判释放(CAPVD>Origin-23 连续 5 样本)在边界试探时被抖动反复打断
→ 释放点外移/卡死。
修复(Q 分档,高/中Q 零影响):
rel_release_hit():低Q(g_q_lo, f>100kHz) 用 g_rel_smooth(τ≈50ms, REL_ALFA=46,复刻打印平均效应)判释放- 低Q 释放带回 ×1.5(REL_BAND_LO_MULT=150,23→~35)提前释放留 σ 余量
- g_rel_smooth:IIR 后每样本跟随;CAPVD=0/重连/INIT 归零;Car_In snap=CAPVD 语法 0 error、4 测试全绿。
2026-09-04 — 频率窗下界 20→18kHz(固件 V4.36.18)
固件版本:V4.36.18(cmcng.h:FIRMWARE_VER="4.36.18",REV=18)。devlog 修订 V2.53。
COIL_F_OK_MIN_KHZ 20 → 18:合理窗 18~125kHz(@43nF ≈ L 47µH~1.15mH), 放行更大电感线圈(如双/大尺寸地感)。test_coil_range 镜像+边界 17 偏大/18 正常。 顺带修正 spec 参数表历史滞后(MAX_KHZ 115→125、COIL_CAL_C_NF 68→43)。
2026-09-04 — 安全复位观感勘误:绿灯镜像继电器后复位指示变化(文档 V2.52,无代码改动)
用户板测确认:SW5=ON 金属板压 >4 分钟 → 安全复位正常触发(Origin 重学压板值, 离开后黄灯长亮故障补偿即证据);"没进入复位模式"是观感差异:
- 旧版绿灯=判稳/有车指示 → 安全复位后 stable=0 绿灯灭 → 复位可见
- V4.36.4 起绿灯=默认继电器(RLY2)镜像 → 复位期间 RLY 刷新挂起(不关断) → 绿灯随继电器保持亮 → 观感"没复位";过一辆车(Car_In 清 LC_Reset)恢复刷新 机制无回归(重连/判稳门控改动未影响安全复位链:Car_In→LC_HOLD→50ms 步进 4800×240s→LC_Reset)。 已同步 manual 4.5(重写为实际行为)与 spec(LC_Reset 勘误注 + SW5 极性说明)。
2026-09-04 — 修复上电无线圈黄灯不闪(固件 V4.36.17)
固件版本:V4.36.17(cmcng.h:FIRMWARE_VER="4.36.17",REV=17)。devlog 修订 V2.51。
用户板测反馈(V4.36.16)
- 上电未接线圈:期望黄绿双闪 → 接线圈自检黄绿双闪 → 自检完同灭;实际黄灯全程没闪
- 上电已接线圈:绿灯闪黄灯不闪 ✓ 通过
根因
断开分支置位条件 if (g_loop_power_up_state && !g_disconnect_active)——
上电 phase(power_up=0,判稳未完成)故意不置 disconnect_active(断开计数不记上电前)。
V4.36.16 把黄灯模式1 的 !power_up 兜底去掉后,上电无线圈黄灯失去触发源。
改动
黄灯模式1 条件 → !loop1_LOOP_OK || g_reconn_stab(ISR 5ms 实时读载波状态):
- 上电无线圈 LOOP_OK=0 → 快闪 ✓(需求1 黄绿双闪恢复)
- 上电有线圈/判稳中 LOOP_OK=1 → 不闪 ✓(需求2 保持)
- 接线圈 LOOP_OK=1 → 黄灯灭 ≤ 绿灯判稳时长 ✓
- 运行中断开:载波缺失 5ms 即闪(原依赖 loop_task 150ms 置位 → 黄灯反应加快)
- 运行中重连判稳 g_reconn_stab → 闪(需求3 不变)
验证
- 语法 0 error;4 组单测全 PASS
- 待板级复测:上电无线圈应黄绿双闪;插线圈黄灯即停绿灯慢闪;有线圈上电黄灯全程不闪
2026-09-04 — 上电自检与线圈重连灯语义分离(固件 V4.36.16)
固件版本:V4.36.16(cmcng.h:FIRMWARE_VER="4.36.16",REV=16)。devlog 修订 V2.50。
用户需求(三条语义区分)
- 上电无线圈:绿灯+黄灯都闪 → 接线圈后黄灯闪时长 ≤ 绿灯闪,自检结束(判稳)绿灯灭黄灯也灭
- 上电已接线圈:绿灯闪(自检),黄灯不闪
- 非上电(运行中)线圈重连:黄灯接管(判稳门控快闪) —— 保持 V4.36.15 模式
现状问题(V4.36.15 副作用)
- 上电首次 LOOP_OK 上升沿 → 确认重置 → VD_FLAG==0 → 误触发判稳门控: 低Q 线圈蠕变把黄灯拖到 2s+,而绿灯判稳 ~1.3s 先停 → 黄灯比绿灯闪得久(违反需求 1)
- 上电有线圈时黄灯因
!power_up也快闪(违反需求 2)
改动
- 黄灯模式1 条件去
!g_loop_power_up_state:黄灯只随"载波问题":g_disconnect_active || g_reconn_stab;上电无线圈由 loop_task 断开分支置 disconnect_active 覆盖(仍双闪);上电有线圈/判稳中黄灯不闪(需求 2 ✓) - 判稳门控触发加
g_loop_stable:仅运行中(判稳完成)重连触发; 上电/安全复位(stable=0)确认重置不判稳 → 上电黄灯不被蠕变拖长(需求 1 ✓: 接线圈 → 100ms 确认 → disconnect_active 清 → 黄灯灭 ≤ 绿灯判稳时长) - 运行中重连(stable=1, VD=0):判稳门控照常 → 黄灯接管(需求 3 ✓ 不变)
验证
- 语法 0 error;4 组单测全 PASS
- 待板级:上电无线圈/有线圈各看一次灯序;运行中拔插确认黄灯接管不变
2026-09-04 — 重连判稳门控(固件 V4.36.15)
固件版本:V4.36.15(cmcng.h:FIRMWARE_VER="4.36.15",REV=15)。devlog 修订 V2.49。
现场问题(用户 21µH/164kHz 无车拔插, V4.36.14 + LO 抑制 1500ms)
重连 confirmed+blank 正常触发,但 blank(1500ms) 结束瞬间 enter_try → Car_In(假车 1.5s):
- 重连直锁首样本 128335(比稳定空场 128450 低 ~115 counts)
- 低Q 起振蠕变 ~2.2s:Value 128335→128367(窗末)→128443(2.5s)→128448(稳定)
- 窗结束时 CAPVD 128367 dev=-98 < -dlt49 → 判车;蠕变爬完 dev 回带 → 释放
- 用户 3000ms 仍偶现(蠕变时长与插头/线圈状态相关,非固定)→ 固定窗治标
机制(用户思路: 确认收到稳定值才动作, 否则黄灯续闪)
无车断开重连(VD_FLAG==0)→ 判稳门控:
- 值稳定检测:200ms 步进 |ΔCAPVD| ≤ dlt/2 → 连续 3 步(600ms) 无漂移
- 回带确认:|CAPVD-Origin| ≤ dlt(空场语义;浅车/蠕变尾 dev 超带不完成)
- 通过 → Origin 对齐当前空场 + CAPVD_slow 同步 + dlt 重算 → 放行 (消除"新空场≠旧 Origin"基线差——根治窗末假车)
- 不稳期间:进入判定挂起 + 黄灯快闪保持(用户要求)
- 强车例外:CAPVD < Origin-8×dlt(真车深压)→ 不等判稳立即放行
- 5s 兜底:超时强制放行(dev 深由正常进入判定接管,避免永久无输出)
有车断开重连(VD_FLAG=1,保持路径输出中)不判稳:重连后走离开判定。
验证
- 语法 0 error;4 组单测全 PASS
- 宏:STABILIZE_STEP_TICKS 20 / STABILIZE_STEPS_OK 3 / STABILIZE_MAX_MS 5000
待板级验证
- 21µH/46µH 无车拔插多次:不再出现窗末/窗后 Car_In 跳变;
串口应见
stab gate on→ (蠕变中可多次stab wait)→stab done Origin->xxx - 判稳期黄灯快闪、判稳完成后黄灯灭
- 判稳期真车压上:
stab bypass strong_car→ 立即 Car_In - 有车断开重连行为不变(保持输出→离开释放)
- 136µH 高Q 正常重连:判稳快通过(~1s 内),无感
2026-09-04 — 重连确认窗漏网路径修复(固件 V4.36.14)
固件版本:V4.36.14(cmcng.h:FIRMWARE_VER="4.36.14",REV=14)。devlog 修订 V2.48。
现场复现(用户 21µH/164kHz 线圈, 临时改 LO 抑制 3000ms 测试)
日志三段重连仅第一段跳:disconnect(cnt=1) → 4s 后 enter_try/Car_In/Car_OFF(1.96s), 前后无 reconnect confirmed / reconn_blank 打印 → 假车没走抑制窗。
根因:确认窗漏网路径(LOOP_OK0 拍级竞态)
重连上升沿用 ISR(5ms) 维护的 loop1_LOOP_OK0,而主循环断开时 150ms 慢 tick:
插头抖动(断开↔恢复数拍)可使 LOOP_OK0 停在 1 → 恢复时 !LOOP_OK0 不触发
→ 跳过 candidate/确认窗/blank → CAPVD 不重置、直接正常判定 → 插回瞬态
(CAPVD 大跌 700+ counts) 判假车跳输出。干净断开→干净重连则走窗被抑制(②③无跳)。
改动
loop_task while 顶部主循环拍级(10ms)自身上升沿检测:
if (loop1_LOOP_OK && !g_prev_ok) { g_prev_ok = 1; candidate=1; cnt=0; }
else if (!loop1_LOOP_OK) g_prev_ok = 0;
任何 0→1 恢复(无论 LOOP_OK0 状态)都强制进确认窗 + blank 抑制; 确认窗内掉线仍取消候选(抖动免疫保留)。ISR LOOP_OK0 维护保留(供安全复位路径,不再驱动候选)。
验证
- 语法 0 error;4 组单测全 PASS(重连在主循环,无单测耦合;待板级验证)
待板级验证
- 21µH(或 46µH) 快速抖动拔插:每次恢复都应看到
loop_reconnect confirmed+reconn_blank, 无直接 Car_In 跳输出(尤其"断开几拍又恢复"的抖动场景) - 正常拔插重连:行为同 V4.36.13(100ms 确认 + 分档抑制)
- 抑制窗值:git 基线 LO=1500ms(用户临时 3000 是否转正待定)
2026-09-04 — 一长一短 灭 100→300ms(固件 V4.36.13)
固件版本:V4.36.13(cmcng.h:FIRMWARE_VER="4.36.13",REV=13)。devlog 修订 V2.47。
dur[4] {180,20,20,140} → {180,60,20,140} = 长亮 900ms / 灭 300ms / 短亮 100ms / 灭 700ms 循环(总周期 2.0s)。
2026-09-04 — 黄灯一长一短 长亮 300→900ms(固件 V4.36.12)
固件版本:V4.36.12(cmcng.h:FIRMWARE_VER="4.36.12",REV=12)。devlog 修订 V2.46。
电感量故障告警(模式5 一长一短)时序:dur[4] {60,20,20,140} → {180,20,20,140}
= 长亮 900ms / 灭 100ms / 短亮 100ms / 灭 700ms 循环(长亮 300→900ms,总周期 1.8s)。
2026-09-04 — 低Q 重连抑制窗 400→1500ms(固件 V4.36.11)
固件版本:V4.36.11(cmcng.h:FIRMWARE_VER="4.36.11",REV=11)。devlog 修订 V2.45。
RECONNECT_BLANK_Q_LO_MS 400 → 1500(低Q f>100k 重连起振抑制窗)。
Q 分档终值:高Q 200ms / 中Q 300ms / 低Q 1500ms(1.5s)。
2026-09-04 — 绿灯镜像勘误:RLY1→RLY2 默认继电器(固件 V4.36.10)
固件版本:V4.36.10(cmcng.h:FIRMWARE_VER="4.36.10",REV=10)。devlog 修订 V2.44。
用户勘误
绿灯指示继电器指反了。产品两个继电器:
- 默认继电器 RLY2 (PA5):恒随车辆存在(VD_FLAG)——绿灯应指示它
- RLY1 (PA6):带脉冲的继电器(拨码3 设置是否启用脉冲信号) V4.36.4 实现镜像了 RLY1 → 若 RLY1 配为脉冲模式,平时不吸合 → 绿灯不随默认继电器 → 观感"反了"
改动
poll_green_led 稳定后镜像对象 RLY1_GPIO->odt → RLY2_GPIO->odt;
注释与文档同步。自检慢闪、断开保持(RELAY_HOLD_MS 保持段 RLY1/RLY2 同 ON)逻辑不变。
2026-09-04 — 频率窗上限 115→125kHz(固件 V4.36.9)
固件版本:V4.36.9(cmcng.h:FIRMWARE_VER="4.36.9",REV=9)。devlog 修订 V2.43。
COIL_F_OK_MAX_KHZ 115 → 125:线圈频率合理窗 20~125kHz(43nF 板口径 L≈38µH 起)。
演进链:120@68nF实验 → 92@68nF → 92@43nF(过严) → 108 → 115 → 125。
test_coil_range 边界 125/126 全绿;spec V2.25 / manual 故障表已同步。
2026-09-04 — 进入/释放确认按 Q 档分档(固件 V4.36.8)
固件版本:V4.36.8(cmcng.h:FIRMWARE_VER="4.36.8",REV=8)。devlog 修订 V2.42。
用户拍板(Q 分档心智沿用到有/无车判定)
V4.36.5~7 重连抑制分档效果好 → 用户提出沿用到日常判定减少误判。 分析结论:dlt 已比例化(Origin×SensTable>>16)无需分档;真正与 Q(噪声抖动)相关的是 进入确认样本数 与 释放确认样本数。
改动(A+B 两处)
| Q 档 | 频率 | 进入确认(样本) | 释放确认(样本) |
|---|---|---|---|
| 高Q | f≤80k | 3 | 3(维持原响应) |
| 中Q | 80~100k | 4 | 4 |
| 低Q | f>100k | 5 | 5(防假进入/输出抖落) |
- 新增
update_q_confirm_need():每样本按空场频率calc_freq_khz(Origin, LPCNT)更新g_entry_need/g_release_need(Origin=0 归高Q 3,不干扰上电判稳) - 进入确认:
loop1_entry_cnt >= ENTRY_CONFIRM→>= g_entry_need - 释放确认:
loop1_cnt_release >= 3→>= g_release_need - 宏:ENTRY_CONFIRM_HI/MID/LO、REL_CONFIRM_HI/MID/LO(TaskLoop.h)
权衡
- 低Q(高频小L):进入/释放各 +20ms(5 vs 3 样本)——判车延迟 50ms@10ms,几乎无感
- 高Q(低频大L):行为零变化(仍 3 样本快响应)
- 真车误判面:进入抖动需持续 ≥5 样本(50ms) 压低超 dlt 才误判——低Q 空场抖动若远小于 dlt 则无感
验证
- 语法 0 error;4 组单测全 PASS(判定确认在主路径,无单测耦合;待板级验证)
- 前置声明修正 1 处(static 定义在使用后)
待板级验证
- 低Q 小线圈(46µH) 反复慢速压车/移走:进出响应正常(无漏检/无抖动),时间略长 20ms 无感
- 高Q 线圈(136µH) 行为与 V4.36.7 完全一致
- 行人/铁板边缘扫过:误判应比 3 样本版更少
- DBG 观察 Car_In/Car_OFF 打印节奏
2026-09-04 — 断开保持/抑制窗参数调整(固件 V4.36.7)
固件版本:V4.36.7(cmcng.h:FIRMWARE_VER="4.36.7",REV=7)。devlog 修订 V2.41。
用户拍板参数:
RELAY_HOLD_MS:500 → 1000(有车断开继电器保持超时 1s)RECONNECT_BLANK_Q_HI_MS:100 → 200(高Q f≤80k 抑制窗)RECONNECT_BLANK_Q_MID_MS:200 → 300(中Q 80~100k 抑制窗)RECONNECT_BLANK_Q_LO_MS:400 不变(低Q f>100k)
Q 分档终值:高Q 200ms / 中Q 300ms / 低Q 400ms;有车断开继电器保持 1s。
2026-09-04 — 高Q 档抑制窗 0→100ms(固件 V4.36.6)
固件版本:V4.36.6(cmcng.h:FIRMWARE_VER="4.36.6",REV=6)。devlog 修订 V2.40。
V4.36.5 中高Q(≤80kHz) 为 0ms 不抑制;用户要求高Q 也保留 100ms 兜底窗
(覆盖插头接触/轻瞬态,虽实测 136/210µH 无问题)。
改动:RECONNECT_BLANK_Q_HI_MS 0 → 100;分档 else 分支引用该宏。
Q 分档终值:高Q(f≤80k) 100ms / 中Q(80~100k) 200ms / 低Q(f>100k) 400ms
2026-09-04 — 重连起振抑制窗 按 Q 分档(固件 V4.36.5)
固件版本:V4.36.5(cmcng.h:FIRMWARE_VER="4.36.5",REV=5)。devlog 修订 V2.39。
现象(用户板级报告)
线圈重连测试:30/46/47/50µH 小电感线圈无车拔插,插回瞬间继电器跳一下(绿灯闪一下)= 输出一下又释放; 136µH、210µH 无此问题。手头无中间规格线圈。
根因(Q 代理分析)
Q∝ωL/R∝1/f(R 近似常数):低 L → 高 f → 低 Q(30µH@140k: Qrel 4.2;210µH@53k: Qrel 11.1)
- 低 Q 起振慢、幅度弱 → 插回瞬间前几窗测量 Xn 严重偏差(幅度未稳捕获异常)→ 假"有车"
- 高 Q 起振快样本干净 → 不触发
- 100ms 重连确认窗只保证载波存在,不保证幅度稳定 → 需要额外"起振抑制"
改动(Q 分档抑制, 用空场频率代理 Q)
| Q 档 | 频率 | 对应 L(@43nF) | 抑制窗 |
|---|---|---|---|
| 低 Q | f>100kHz | <~59µH | 400ms(实测 46~50µH 必跳档) |
| 中 Q | 80~100kHz | 59~92µH | 200ms |
| 高 Q | ≤80kHz | ≳92µH | 0ms(136/210µH 实测无需) |
- 分档点:vd1_task 首样本直锁(重连重置 CAPVD=0 后第一样本)用
calc_freq_khz(loop1_Origin, loop1_LPCNT)(Origin=断开前同线圈空场基线 → f 即 Q 档; 上电 Origin=0 → f=0 → 高Q 0ms 不影响正常判稳) - 抑制动作:进入确认段加 g_reconn_blank_ms==0 条件——抑制期不累计 entry_cnt(假样本凑不满确认), 其余逻辑(IIR 收敛/冻结/环境/离开)照常 → 真车在抑制期压深也不丢,抑制结束立即正常累计
- 倒计时:vd1_task 每样本 -10ms
- 宏可调:RECONNECT_Q_HI/MID_F_KHZ 分界 + RECONNECT_BLANK_Q_{HI/MID/LO}_MS
权衡
- 无车拔插重连:假跳输出消除(低Q 多等 ~400ms 才允许判车——本应如此,起振收敛中)
- 重连瞬间真车压上:判车延迟 ≤ 抑制窗(低Q ~400ms + 进入确认延时),道闸场景可接受
- 高 Q(136/210µH)行为零变化
验证
- 语法 0 error;4 组单测全 PASS(抑制在 vd1_task 进入判定,无单测耦合;待板级验证)
待板级验证
- 30/46/47/50µH 无车拔插重连:继电器不再跳(EVT|reconn_blank 400ms 打印确认档位)
- 136/210µH 拔插:无 reconn_blank 打印、无跳(高Q 0ms)
- 中档 60~90µH(如手头有):应打 reconn_blank 200ms
- 抑制期真车压上:抑制结束正常判车(仅延迟 ~400ms)
2026-09-04 — 绿灯=继电器状态指示(固件 V4.36.4)
固件版本:V4.36.4(cmcng.h:FIRMWARE_VER="4.36.4",REV=4)。devlog 修订 V2.38。
现场误判(用户报告)
车压线圈拔线测试:继电器实际未释放(V4.36.3 保持逻辑工作正常),但绿灯灭了——
原 poll_green_led 在 g_disconnect_active 时强制绿灯灭(黄灯快闪负责故障指示),
而继电器在有车断开时保持吸合 → 灯(灭)与继电器(吸)脱节 → 误判"继电器立刻释放"。
改动
绿灯语义改为 = RLY1 继电器实际输出状态(稳定后):
- 读
RLY1_GPIO->odt & RLY1_PIN(与 RLY1_ON/OFF 宏同源 = 真实驱动状态) - 吸合(高) → 绿灯亮(PA9 低电平点亮);释放 → 绿灯灭
- 删除
g_disconnect_active强制灭分支 → 断开时绿灯跟随继电器:- 有车断开保持(RELAY_HOLD_MS)期间 → 绿灯保持亮(与继电器一致)
- 断开超时释放/无车断开 → 绿灯灭
- 自检/判稳期(INI_LOOP/!power_up/!stable)保持 200ms 慢闪(就绪过程指示,该阶段继电器未驱动)
输出覆盖(模式自适应)
- 存在模式:有车/离开延时输出 → RLY1 吸合 → 绿灯亮;无车 → 灭
- 脉冲模式:进出脉冲输出中 → 绿灯短亮;平时灭(真实输出指示)
验证
- 语法 0 error;4 组单测全 PASS(绿灯为 poll 层,无单测耦合;待板级验证)
待板级验证
- 车压线圈拔线:绿灯保持亮 500ms(与继电器同步)→ 超时释放后灭
- 车压快速拔插(<500ms):绿灯不掉,车走继电器释放 → 绿灯灭
- 上电判稳期:绿灯慢闪 → 稳定后灭(无车)/ 有车亮
- 脉冲模式:进出车时绿灯短亮脉冲
2026-09-04 — 有车断开继电器保持 500ms(固件 V4.36.3)
固件版本:V4.36.3(cmcng.h:FIRMWARE_VER="4.36.3",REV=3)。devlog 修订 V2.37。
拍板机制(2026-09-03)
线圈断开前感应有车且继电器输出中时,断开后不立即释放,改为保持 RELAY_HOLD_MS:
- 500ms 内重连 + 感应有车 → 继电器继续有车输出(无缝,从未掉电)
- 500ms 内重连 + 感应无车 → 继电器释放(vd1_task 正常离开判定,几十~数百 ms)
- 500ms 超时仍断开 → 继电器强制释放(防真故障无限保持)
- 无车断开(VD_FLAG=0)→ 立即释放(原行为,安全刚需)
宏可调:RELAY_HOLD_MS(TaskLoop.c 前部宏区,ISR 使用)
实现要点
- 保持计时在 TMR15 ISR(5ms tick):
!LOOP_OK && VD_FLAG && power_up && !hold_done→ RLY1/2 保持 ON + cnt+=5,满 500ms 强制 OFF + hold_done=1(防重复抖动) - loop_task 断开分支:有车断开(VD_FLAG && power_up)不立即 OFF(释放交给 ISR 兜底),无车断开照旧立即 OFF
- 重连确认重置(V4.36.2 100ms 窗)后清 cnt/done
- 审查修复:超时释放后若不查 hold_done,每 5ms 会先 ON 再 OFF → 100Hz 继电器抖动 → 已加
!g_relay_hold_done防护
行为时序
[运行 有车 VD=1 RLY ON] ──断开──▶ RLY 保持 ON (黄灯快闪照常)
├─ <500ms 重连 → 100ms 确认窗 → vd1_task: 有车→续持 / 无车→释放
└─ ≥500ms 仍断 → RLY 强制释放 (hold_done=1)
验证
- 语法 0 error;4 组单测全 PASS(保持逻辑在 ISR/主循环,无单测耦合;待板级验证)
待板级验证
- 车压线圈时拔线:继电器保持 500ms → 仍断则释放(黄灯快闪全程)
- 车压线圈时快速拔插(<500ms):继电器不掉 → 车走正常释放
- 无车断线:继电器立即释放(无变化)
- RELAY_HOLD_MS 改 100/1000 复测节奏
2026-09-04 — 线圈重连确认窗 100ms(固件 V4.36.2)
固件版本:V4.36.2(cmcng.h:FIRMWARE_VER="4.36.2",REV=2)。devlog 修订 V2.36。
背景(抗干扰性分析结论)
断开/重连链路原设计:RF 恢复第 1 拍即触发重连重置(清断开标记 + CAPVD=0 重收敛), 存在三个裸奔点:
- 接触不良抖动(断开↔恢复几十 ms 交替)→ 每个边沿重复计数 + 反复重收敛
- 首样本直锁绕过斜率限幅(CAPVD==0 直锁 Value)→ 恢复首拍毛刺直接进基线
- 断开判定 5ms 无防抖——但释放速度是安全刚需,保持现状不加防抖
改动(确认窗方案)
- RF 上升沿仅进入候选(g_reconn_candidate),不再立即重置
- 载波连续恢复 10×10ms=100ms(RECONNECT_CONFIRM_TICKS=10)才确认重连:
- 清断开标记(黄灯从快闪切 N 短闪/灭)
- CAPVD=0 / CAPVD_slow=0 强制重收敛(首样本此时载波已稳定 100ms → 干净)
- env 复位 + env_resync_abort()
- 确认窗内:disconnect_active 保持 1 → 黄灯维持快闪、断开计数不重复; 不跑 vd1_task(等载波稳定)
- 任何掉线(else 分支)→ 取消候选、计数清零 → 抖动免疫(每次恢复重新计满窗才确认)
行为变化
| 场景 | V4.36.1 | V4.36.2 |
|---|---|---|
| 正常断开→重连 | 恢复即重置 | 恢复后 ~100ms 确认重置(EVT |
| 接触不良抖动 | 每 cycle 计数+1、反复重收敛 | 候选被反复取消,不计数不重置,恢复稳定后才确认一次 |
| 恢复首样本 | 可能含毛刺直锁 | 载波稳定 100ms 后重建,干净 |
| 上电首次接线圈 | 恢复即进入 | 多 100ms 候选(判稳 1.3s+ 流程内可忽略) |
验证
- 语法 0 error;4 组单测全 PASS(重连逻辑在主循环 loop_task,无单测耦合;待板级验证)
待板级验证
- 拔插线圈:快闪持续到重连确认后切短闪/灭(比旧版多 ~100ms)
- 手动快速抖动插头:断开计数不应乱跳(≤真实断开次数)
- 重连后检测正常(Origin 沿用旧值;若断开期间环境大改走 2s/7s 环境学习)
2026-09-04 — 版本体系增加修订号:4.36.1(固件 V4.36.1)
固件版本:V4.36.1(cmcng.h:FIRMWARE_VER="4.36.1",MAIN=4/SUB=36/REV=1)。devlog 修订 V2.35。
拍板(2026-09-03)
版本号增加第三段修订号 REV:
- 格式:
MAIN.SUB.REV(当前 4.36.1) - MAIN/SUB 由产品定(开发不自行递增子版本)
- 后续小改动/参数调整只递增 REV(4.36.1 → 4.36.2 → …),主/子版本留给产品规划(大功能/协议变更等由用户拍板 bump)
改动
- cmcng.h:FIRMWARE_VER "4.36"→"4.36.1";新增
FIRMWARE_VER_REV 1 - main.c:启动日志新增版本打印行(便于现场确认修订号)
fw:4.36.1 main=4 sub=36 rev=1 hw:3.00 - spec V2.17 / devlog V2.35
验证
- 语法 0 error(TaskLoop.c + main.c)
说明
- 本条目内容为版本体系调整(无参数/行为变化);V4.36.1 与 V4.36 功能等价
- 后续 V4.36.x 的调整均以此编号续增;待产品定新 MAIN/SUB 时再升
2026-09-03 — 频率窗上限 108→115kHz(固件 V4.36)
固件版本:V4.36(cmcng.h:FIRMWARE_VER="4.36" + MAIN=4/SUB=36)。devlog 修订 V2.34。
拍板(2026-09-03)
COIL_F_OK_MAX_KHZ:108 → 115(43nF 三极管板口径)
- 115kHz @ C_eff43 ≈ L 44µH
- 放行 ~48µH 小线圈(43nF 板理论 f≈111kHz,此前 108k 会误报)
- 合理窗:20 ~ 115kHz
改动
- TaskLoop.h:COIL_F_OK_MAX_KHZ 108→115(注释同步)
- tests/test_coil_range.c:镜像宏 115,边界 115/116(115 正常、116 → L偏小)
- 版本 V4.35→V4.36;spec V2.15 / manual V2.11→V2.12 / devlog V2.34
验证
- test_coil_range 5 场景 ALL PASS(边界 19/20/115/116)
- 语法 0 error
待现场验证
- 各典型线圈(LCR 40~1000µH 矩阵)在 43nF 三极管板扫 f 对照窗判定
2026-09-03 — 频率窗上限复核:92→108kHz(固件 V4.35,43nF 板口径)
固件版本:V4.35(cmcng.h:FIRMWARE_VER="4.35" + MAIN=4/SUB=35)。devlog 修订 V2.33。
修正(2026-09-03)
V4.33 拍 92kHz 时测试数据在 0Ω 实验板(C_eff=68);产品基准回到三极管库存板(43nF)后 同线圈 f ×1.257,92k 对应 L≈70µH(0Ω 板口径 30µH)→ 40~70µH 正常线圈会误报。
COIL_F_OK_MAX_KHZ:92 → 108(43nF 板口径,108kHz ≈ L 50µH,保留最小合理线圈)
| 板型 | C_eff | 92k 对应 L | 108k 对应 L |
|---|---|---|---|
| 三极管库存板(产品,43) | 43 | ~70µH | ~50µH |
| 0Ω 实验板(68) | 68 | ~30µH | ~44µH |
改动
- TaskLoop.h:COIL_F_OK_MAX_KHZ 92→108(注释含 43nF 板口径与复核缘由)
- tests/test_coil_range.c:镜像宏 108,边界 108/109(108 正常、109 → L偏小)
- 版本 V4.34→V4.35;spec V2.14 / manual V2.11 / devlog V2.33
验证
- test_coil_range 5 场景 ALL PASS(边界 19/20/108/109)
- 语法 0 error
待现场验证
- 48µH 线圈(43nF 板 ~111kHz)——仍略高于 108k 上限?LCR 复核实际值后确认是否需要再放宽
2026-09-03 — 产品基准回到三极管库存板:COIL_CAL_C_NF 68→43(固件 V4.34)
固件版本:V4.34(cmcng.h:FIRMWARE_VER="4.34" + MAIN=4/SUB=34)。devlog 修订 V2.32。
决策(2026-09-03)
不改电路,沿用三极管库存板(R19 在 / R27 空贴,拨码经三极管开关控制第二颗 33nF):
- 低频档(66nF 名义)实测 C_eff≈43nF(41.3~45.5,2 台×5 颗线圈)
- 固件标定
COIL_CAL_C_NF:68 → 43 - R19拆/R27焊0Ω 的实验改动仅作机理验证(确认并联未全量并入因三极管动态阻抗 ~160Ω),0Ω 板实测 68.4 不用于产品基准
风险与缓解(沿用三极管板的长期稳定性)
- 43nF 为三极管动态等效(非纯电容):随温度/β/信号幅度漂移(估计 Δf ±1.5~4% 跨温域)
- 车检算法不受影响(Xn 比值 + Origin 自适应吸收缓慢漂移)
- ⚠ 温度骤变可能触发环境黄灯/学习;频率窗边界附近线圈可能抖动告警
- 缓解:待温度实验量化;出厂抽检标定 C_eff 批一致性;频率窗按 43nF 口径复核(见下)
⚠ 频率窗口径提醒(92kHz × 43nF 板)
| 板型 | COIL_CAL_C_NF | f=92kHz 对应 L | f=120kHz 对应 L |
|---|---|---|---|
| 三极管库存板(现产品) | 43 | ~70µH | ~41µH |
| 0Ω 实验板(V4.33 拍 92 时的数据语境) | 68 | ~30µH | ~26µH |
V4.33 拍 92kHz 时测试数据在 0Ω 板(68nF);产品回到 43nF 板后同线圈 f ×1.257, 48µH 线圈:0Ω板 88kHz(窗内) → 三极管板 ~111kHz(窗外误报) → 若需保留 ~50µH 最小合理线圈, 上限应 ~108kHz 或按现场实测复核(待用户确认窗口口径:按 L 还是按 f)。
改动
- TaskLoop.h/TaskLoop.c:COIL_CAL_C_NF 68→43(注释含两板口径)
- 版本 V4.33→V4.34;hardware-change-notes 产品决策注记;devlog V2.32
验证
- 语法 0 error;coil_range/env/red_breath/power_on_stable 全 PASS(L 估算不参与单测断言)
待办
- 现场用三极管库存板复核频率窗(尤其 40~70µH 小线圈是否应正常)
- 温度实验:-20/25/70°C 测同线圈拨码 ON 的 f 漂移
2026-09-03 — 线圈频率窗上限 120→92kHz(固件 V4.33)
固件版本:V4.33(cmcng.h:FIRMWARE_VER="4.33" + MAIN=4/SUB=33)。devlog 修订 V2.31。
拍板(2026-09-03)
线圈电感量告警频率窗上限收窄:COIL_F_OK_MAX_KHZ 120 → 92(默认低频档口径)
- 合理窗:20 ~ 92kHz(对应 L≈30µH(f=92k, C_eff68)~ 930µH(f=20k))
- f > 92kHz → L 偏小告警(一长一短,g_coil_fault=2)
背景推测
92kHz 接近 33nF 档与低频档歧义区上沿附近(33nF 档常见线圈 f 更高),上限压低可减少高频小线圈误报窗口;具体现场动机以用户口径为准。
改动
- TaskLoop.h:COIL_F_OK_MAX_KHZ 120→92(注释同步)
- tests/test_coil_range.c:镜像宏 92,边界用例 120/121→92/93
- 版本 V4.32→V4.33;spec V2.12 / manual V2.10 / devlog V2.31
验证
- test_coil_range 5 场景 ALL PASS(边界 19/20/92/93:92 正常、93 → L偏小)
- 语法 0 error
待现场验证
- 原 f 在 92
120kHz 间的线圈(如 L≈3044µH@66nF 档)现在会告警 L 偏小——确认这批线圈是否确实不合理或需另行放行
2026-09-03 — 黄灯一长一短模式时序调整(固件 V4.32)
固件版本:V4.32(cmcng.h:FIRMWARE_VER="4.32" + MAIN=4/SUB=32)。devlog 修订 V2.30。
拍板(2026-09-03)
电感量告警黄灯一长一短模式节奏调整(原 V4.26 拍板 200/100/100/800ms):
长亮 300ms → 灭 100ms → 短亮 100ms → 灭 700ms → 循环
(长亮+100ms,末段灭 800→700ms,总周期 1.1s→1.2s 变 1.2s→1.2s?实际 200+100+100+800=1.2s → 300+100+100+700=1.2s 总周期不变,节奏感更明显)
改动
- TaskLoop.c poll_yellow_led() 模式 5:
dur[4] = {40,20,20,160}→{60,20,20,140}(5ms/tick = 300/100/100/700ms) - 注释同步;版本 V4.31→V4.32;spec V2.11 / devlog V2.30 / design doc §6 注记
验证
- 语法 0 error;coil_range/env/red_breath/power_on_stable 测试不受影响(模式时序为 poll 层常量,无单测耦合)
待现场验证
- 超范围线圈(或 f 边界测试)观察:一长(300ms) 一短(100ms) 节奏,总周期 1.2s
2026-09-03 — 故障补偿时序再调:预判2s + 补偿7s(固件 V4.31)
固件版本:V4.31(cmcng.h:FIRMWARE_VER="4.31" + MAIN=4/SUB=31)。devlog 修订 V2.29。
拍板规格(2026-09-03,V4.30 基础上现场手感再收紧)
- 黄灯预判 3s → 2s(ENV_WARN_WAIT 300→200):高位持续 2s 黄灯预判锁存常亮
- 故障补偿 8s → 7s(ENV_RESYNC_WAIT 800→700):累计 7s 高位进入基线学习
- 恢复确认保持 2s(ENV_RECOVER_WAIT 200 不变)
时序:2s 黄灯亮 → 7s 触发学习 → 6s(3×200tick)学完替换 → 2s 确认灭;总恢复 ~15s
验证(test_env_resync.c 同步,5 场景 ALL PASS)
| 场景 | 期望 | 实测 |
|---|---|---|
| 永久变化 | warn@200 / applied@~1300 / 替换后 200tick 灭 | warn_at=200 ✓ applied_at=1300 ✓ 灭 ✓ |
| 瞬态 6s(<7s) | 锁存不学, 空闲 2s 灭 | ✓ |
| 学习期压线 | 搁置不退出 → 学完替换 | ✓ (applied_at=1301) |
| 不稳学习 | 预算放弃, 不污染 | abort ✓ Origin 不变 ✓ |
| 替换后稳态 | 无重复学习 | ✓ |
待现场验证
- A 拿走:~2s 黄灯亮 → ~13s 基线切 B → ~15s 黄灯灭
- 补偿触发提前到 7s:持续 7~10s 强磁干扰会触发学习(原 10s/8s 边界继续提前)——黄灯 2s 预警先亮
2026-09-03 — 故障补偿时序调整:预判3s + 补偿8s + 恢复2s(固件 V4.30)
固件版本:V4.30(cmcng.h:FIRMWARE_VER="4.30" + MAIN=4/SUB=30)。devlog 修订 V2.28。
拍板规格(2026-09-03)
故障补偿节奏整体提速、现场手感更紧凑:
- 预判 3 秒(ENV_WARN_WAIT 500→300):高位持续 3s 黄灯预判锁存常亮(原 5s)
- 故障补偿 8 秒(ENV_RESYNC_WAIT 1000→800):累计 8s 高位进入基线学习(原 10s)
- 新环境稳定 +2 秒(ENV_RECOVER_WAIT 500→200):学习完成原子替换 Origin 后,空闲连续 2s 恢复确认 → 黄灯灭(原 5s)
总恢复:~21s → ~16s(3s 预判 → 8s 触发 → 6s 学习(3×200tick) → 2s 确认灭)
改动
- ENV_WARN_WAIT 500→300(~5s→~3s) / ENV_RESYNC_WAIT 1000→800(~10s→~8s) / ENV_RECOVER_WAIT 500→200(~5s→~2s)
- tests/test_env_resync.c 重写(镜像与固件逐分支一致:学习中压线=搁置不退出、学习仅高位段计数、abort 后循环重触发语义)
- 版本 V4.29→V4.30;spec V2.9 / devlog V2.28
验证(5 场景 ALL PASS)
| 场景 | 期望 | 实测 |
|---|---|---|
| 永久变化 | warn@300 / applied@~1400 / 替换后 200tick 灭 | warn_at=300 ✓ applied_at=1400 ✓ 灭 ✓ |
| 瞬态 7s(<8s) | 锁存不学, 空闲 2s 灭, 二次 7s 再锁存 | ✓ |
| 学习期压线 | resync 保持=搁置, 走后再学完替换 | ✓ (applied_at=1401) |
| 不稳学习 | 预算 30s 放弃, 不污染, 黄灯保持 | abort=1 ✓ Origin 不变 ✓ warn=1 ✓ |
| 替换后稳态 | 无重复学习, 恢复确认后灭 | ✓ |
待现场验证
- A 拿走:~3s 黄灯亮 → ~14s 基线切 B(黄灯仍亮)→ 空场稳定 ~16s 黄灯灭
- ⚠ 补偿触发提前到 8s:持续 8~10s 的强磁干扰会触发学习(原 10s 边界)——现场观察确认可接受
2026-09-03 — C_eff 标定定稿 68(0Ω 板低频档)+ 硬件疑点闭环(固件 V4.29)
固件版本:V4.29(cmcng.h:FIRMWARE_VER="4.29" + MAIN=4/SUB=29)。devlog 修订 V2.27。
硬件修复(用户操作)
拨码接通第二颗 33nF 的开关电路:三极管上 5.1K 电阻改为 0Ω。 (该三极管用于拨码档位时断开/接通电容。)
修复效果(0Ω 板低频档实测)
| 打印 f | 打印 L(66名义) | LCR 实际 L | C_eff 反推 |
|---|---|---|---|
| 52 kHz | 141 µH | 136 µH | 68.9 nF |
| 127 kHz | 23 µH | 23 µH | 68.3 nF |
| 88 kHz | 49 µH | 48 µH | 68.1 nF |
C_eff = 68.1~68.9nF(均值 68.4)≈ 名义 66nF → 第二颗 33nF 现在真正并联进回路。
闭环结论(V4.28 的 43 作废)
V4.28 标定的 43nF 是 5.1K 旧板带病特性:5.1K 电阻在三极管开关通路造成 未饱和导通/压降 → 第二颗 33nF 只等效并入 ~8.6nF(两档 C_eff 比仅 1.25 非 2.0)。 换 0Ω 后开关全导通 → 低频档 C_eff 回到 ~68(≈66+分布)。
改动
- COIL_CAL_C_NF 43 → 68(0Ω 板量产默认);注释记录 43 作废原因
- 高频档(33nF)标定仍记 34(旧板数据;0Ω 板待复测,若开关只控并联支路则不受影响)
- 版本 V4.29;spec V2.8 / devlog V2.27 / design doc v0.6
验证(用 68 回代)
52k→138µH(实136 +1.3%) 127k→23µH(实23 +0.4%) 88k→48µH(实48 +0.2%) 残差 ≤1.5%(用名义 66 则 +3~4%,68 更贴 LCR)
待确认
- 0Ω 板 33nF 档 C_eff 复测(预期仍 ~34,若开关只控并联支路)
- 量产切换 0Ω 电阻后按 68 标定
2026-09-03 — 电感量估算引入 C_eff 标定(固件 V4.28)
固件版本:V4.28(cmcng.h:FIRMWARE_VER="4.28" + MAIN=4/SUB=28)。devlog 修订 V2.26。
问题(现场实测,V4.27 频率已对齐后)
打印 L 与实际 LCR 实测仍有 1.5 倍系统性偏差(实际/打印 1.461.64):
| 打印 f | 打印 L | LCR 实测 L | C_eff 反推 |
|---|---|---|---|
| 64 kHz | 93 µH | 136 µH | 45.5 nF |
| 113 kHz | 30 µH | 48 µH | 41.3 nF |
| 114 kHz | 29 µH | 46 µH | 42.4 nF |
| 107 kHz | 33 µH | 50 µH | 44.3 nF |
| 163 kHz | 14 µH | 23 µH | 41.5 nF |
根因
L_uH = 2.533e7/(f_kHz²×C_nF) 里 C 用了名义档位电容 66nF,但振荡回路 等效谐振电容 C_eff ≈ 43nF(41.3~45.5,均值 42.97)——与标称明显不符 (可能振荡拓扑/布局/电容实际值造成)。频率真实 + LCR 真实时,偏差收敛到 C 一个参数。
改动
- TaskLoop.h:新增
COIL_CAL_C_NF 43(标定等效谐振电容,出厂默认=5 组实测均值);COIL_DEF_C_NF 66保留为名义口径(不再参与计算) - coil_l_uH():公式改用 COIL_CAL_C_NF;EVT 文案去掉 (C66/×2C33)
- 版本 V4.28;spec 参数表 + devlog + design doc v0.5
验证(用 43nF 回代 5 组)
64k→144µH(+5.7%) 113k→46µH(-3.9%) 114k→45µH(-1.5%) 107k→51µH(+2.9%) 163k→22µH(-3.6%) 残差 ±6% 内(含 LCR 测量/频率取整噪声),"粗略值"够用;可标定收口。
标定指引(想更准)
拿 13 颗 LCR 实测已知的线圈(建议覆盖 60160kHz),串口读 f,代入
C_eff = 2.533e7/(f_kHz² × L_LCR) 多颗取均值 → 改 COIL_CAL_C_NF 重新编译即可。
待现场验证
- V4.28 打印 L 应与 LCR 接近(±6% 内);如需更准按指引标定
- 若用 33nF 档(高频)测试数据多,可再单独标一组高频档 C_eff(当前 5 组混档均值)
2026-09-03 — 频率测量 4 倍偏差修正(固件 V4.27)
固件版本:V4.27(cmcng.h:FIRMWARE_VER="4.27" + MAIN=4/SUB=27)。devlog 修订 V2.25。
问题(用户现场实测对比示波器)
DBG 打印低频 7kHz / 高频 9kHz;示波器实测 30.23kHz / 36.82kHz——固件少算 4 倍 (30.23/4=7.56、36.82/4=9.21,整数截断吻合)。
根因(两处 2 倍叠加)
calc_freq_khz常数 60000 按 60MHz 计数时钟假设;实际 TMR3 计数时钟 = sclk = 120MHz (HEXT×10、AHB÷1、APB1÷1,见 at32f421_clock.c)- 输入捕获配置
TMR_CHANNEL_INPUT_DIV_2(每 2 个信号边沿捕获一次 → Xn 翻倍); board.c 算出的g_input_div从未参与频率换算
→ Xn = 2×120MHz/f_real → f_print = 60000/Xn = f_real/4。 spec §4.1.2 曾把"DIV_2"误述为"120MHz→60MHz 时钟"——实际是边沿计数分频, 不是时钟分频;等效采样率是 240M/周期而非 60M/周期。
改动
calc_freq_khz:60000 → 240000(240000 = 120MHz×DIV_2 的 kHz 口径;注释完整推导)coil_l_uH:改用修正后 f_kHz 计算(L_uH = 2.533e7/(f_kHz²×C_nF)),DBG/EVT 用同一 _fk- 版本 V4.26→V4.27;spec §4.1.2 流程文字更正;devlog 解读表同步 240000
影响面(重要)
- 旧日志全部 f/L 需 ×4 修正:如"16.3kHz→L1445µH 超限"实为 65.2kHz→L≈90µH 正常线圈
- V4.26 线圈告警窗口(20~120kHz)判定随 calc 同步用真实频率,行为自洽;此前据 "16.3kHz 案例"的结论需按真实频率重新评估(该案例实为测频 bug 假象)
- LPCNT 自适应窗口/CAPVD/dlt/灵敏度等基于 Xn 比值,不受影响
验证
- gcc -fsyntax-only 0 error;tests/env_resync/coil_range/power_on_stable/red_breath 全 PASS
- 待现场:串口 f ≈ 示波器(低频 30.23 / 高频 36.82);L 打印 ≈420µH@30.2kHz(默认 66nF 档)
2026-09-03 — 线圈电感量告警 + 故障补偿提速(固件 V4.26)
固件版本:V4.26(cmcng.h:FIRMWARE_VER="4.26" + MAIN=4/SUB=26)。devlog 修订 V2.24。
背景
DLD154V4 线圈振荡两级频率(33/66nF 拨码,拨码不引 IO)。现场抓到 f=16.3kHz(Xn=3681) 超范围 线圈(L≈1.44mH@66nF),检测异常难排查 → 要求对不合理电感量自动告警。 另:环境重校准(V4.24/25)补偿总时长 ~66s 偏长 → 拍板提速。
拍板规格(2026-09-03)
- 按默认低频档计算,频率合理范围 20 ~ 120 kHz,出界即判定电感量不合理 → 告警(不做档位判定/灰带)
- 告警形式:黄灯一长一短(长亮200ms/灭100ms/短亮100ms/灭800ms 循环)
- 黄灯优先级:线圈断开快闪 > 故障补偿(学习补偿)常亮 > 电感量不合理一长一短 > 线圈断开 N 短亮 > 灭
- 故障补偿黄灯常亮(等待学习)时间 60s → 10s(ENV_RESYNC_WAIT 6000→1000)
改动
- TaskLoop.c:新增 coil_monitor()(稳定+无车空闲由无车主路径调用;Origin 反推空场 f; f<20kHz→L偏大 / f>120kHz→L偏小,1s 防抖置位/清除;EVT|coil_fault/coil_ok)
- poll_yellow_led():新增模式5(一长一短 40/20/20/160 tick);优先级 1>4>5>3>2
- ENV_RESYNC_WAIT 6000→1000(5s 预判 → 10s 学习 → ~16s 替换 → 空闲 5s 确认灭,总 ~21s)
- TaskLoop.h:COIL_F_OK_MIN_KHZ=20 / COIL_F_OK_MAX_KHZ=120 / COIL_DEF_C_NF=66
- 行尾修复:V4.24~25 编辑期间源文件行尾被写成多 CR(\r\r\r\r\n),本次统一规范化回标准 CRLF
- DBG 周期打印(2s)增加 L 粗估字段(coil_l_uH(): Xn 精确反推,默认 66nF 档;拨 33nF 档结果 ×2):
DBG|t=2000ms f=16kHz L=1445uH Xn=3681 ...;EVT|coil_fault 同步改用 Xn 算法(精度优于 f 整数反推)
验证
- tests/test_coil_range.c 5 场景:L偏大/偏小 1s 防抖置位、恢复 1s 防抖清除、边界 19/20/120/121、抖动不误报 ALL PASS
- tests/test_env_resync.c(ENV_RESYNC_WAIT=1000):永久变化 applied_at=1600tick、瞬态<10s 不学、 锁存保持、打断重算、放弃不污染 ALL PASS
- gcc -fsyntax-only 0 error
待现场验证
- 超范围线圈(如 f=16.3kHz)应黄灯一长一短;正常 100
300µH 线圈(f 20120k 内)不误报 - 故障补偿总时长 ~21s;环境高位 10s 即学(铁块静止 >10s 会被学入,黄灯常亮提示请勿移动目标)
- 电感告警阈值边界用标定线圈(100µH/300µH)实测微调
2026-09-02 — 环境异常黄灯预判:5s 常亮提示将进入重学(固件 V4.25)
固件版本:V4.25(cmcng.h:FIRMWARE_VER="4.25" + MAIN=4/SUB=25)。devlog 修订 V2.23。
背景
V4.24 环境重校准的黄灯常亮只在进入学习后(dev>+4dlt 高位累计满 60s)才点亮, 前 60s 操作员无任何可视反馈,不知道检测器是否已感知环境变化。
改动
- 黄灯模式4 条件(poll_yellow_led):
g_env_resync || g_env_warn - 新增
ENV_WARN_WAIT = 500 tick(~5 s)+ENV_RECOVER_WAIT = 500 tick(~5 s)(TaskLoop.h 文件级宏) - 预判锁存状态机(g_env_warn):
- 高位(dev>+4dlt)连续 5 s →
g_env_warn=1,黄灯预判常亮(提示"环境已重大变化") - 锁存:回摆/目标靠近(wait 清零)不灭灯——只有环境回到正常空闲(dev 未进进入线)连续 5 s(恢复确认)才解除、黄灯灭
- 累计满 60 s 才真正进入重校准学习(学习期间黄灯保持常亮,学完替换 Origin 后仍需恢复确认 5 s 才灭)
- 高位重现 → 恢复确认计时清零,黄灯继续常亮
- 高位(dev>+4dlt)连续 5 s →
- 预判 ≠ 学习:短时瞬态(60 s 内回摆)只亮黄灯、不触发学习
验证
- tests/test_env_resync.c 扩展:预判点亮时刻 = 500 tick;回摆后黄灯保持常亮;稳定 5 s 后解除;高位重现再锁存;打断/放弃后锁存保持
- 5 场景 ALL PASS;gcc
-fsyntax-only0 error
待现场验证
A 拿走场景:约 5 s 黄灯常亮(此后回摆也不灭)→ ~60 s 自动重学 → 替换完成 → 环境稳定再 5 s 黄灯灭、检测高度恢复。
2026-09-02 — 环境重校准:现场永久环境变化自动恢复基线(固件 V4.24)
固件版本:V4.24(cmcng.h:FIRMWARE_VER="4.24" + MAIN=4/SUB=24)。devlog 修订 V2.22。
现场现象(V4.22 实测复现,DBG/EVT 串口日志)
线圈旁金属板 A 上电 → 稳定后 Origin 学低;A 拿走 → CAPVD 弹回真空场, 相对 Origin 恒高 dev=+761 cnt(0.59% Origin,实测 CAPVD 128096→128856), 被 V4.20 双向保护(36321a1)"dev>0 永不更新"永久冻结 → Origin 卡 128095 → 再拿金属板 B 测试需下跌 ~809 cnt(正常 54 cnt)才触发 → 触发高度明显降低、不恢复。
- V4.20(双向保护前,278d470):dev>0 走正常窗口平均 → 数分钟缓慢恢复(现场"等一段时间能恢复")
- V4.22(含双向保护):dev>0 只冻结、永不更新 → 永久不恢复
根因
36321a1 为防"铁块靠近污染 Origin → 离开假进入锁死",把 dev>+4×dlt 高位的
"无车环境异常"一律永久冻结。但"铁块靠近(瞬态,秒级回摆)"与"永久环境变化
(基准被学低,如 A 拿走)"数值不可分,仅时间维度可分——永久冻结把后者也卡死。
修复(V4.24 两段式受控重校准)
| 阶段 | 条件 | 动作 |
|---|---|---|
| ① 冻结等待 | dev>+4×dlt 高位连续 60 s(ENV_RESYNC_WAIT=6000 tick)未回摆 | 保持双向保护冻结语义(<60 s 瞬态不污染) |
| ② 学习基线 B | 连续空闲窗(ENV_LEARN_WINDOW=200 tick)均值 + settle 判稳(连续 2 窗漂移 ≤0.1%) | 黄灯常亮指示学习过程 |
| ③ 原子替换 | B 可信且空闲 | Origin=B;清 freeze/ORG/entry 残留;slow snap(同 V4.04);黄灯恢复 |
- 学习期任何打断(CAPVD 回窗、dev<0 目标靠近、线圈断开重连)→ 重算重来
- 学习预算 ENV_LEARN_MAX_TICKS=3000(30 s)超时放弃,保留旧 Origin——宁可灵敏度低不冒险污染
- 替换瞬间 B≈当前空闲 CAPVD → dev≈0 无跳变,不会误触发继电器
- 黄灯优先级:断开快闪 > 学习常亮 > N 短闪(断开史)> 灭
验证
tests/test_env_resync.c(新增):5 场景 ALL PASS- 永久变化(常量高位)→ 6600 tick(~66 s)自动替换 Origin 128095→128856
- 瞬态高位 60 s 内回摆 → 不学习不替换
- 学习期打断 → abort 重算 → 最终恢复
- 学习期窗口不稳 → 30 s 预算放弃,Origin 不被污染
- 替换后 dev≈0 → 无重复学习不震荡
- gcc
-fsyntax-onlyTaskLoop.c 0 error
权衡(待现场验证)
- 铁块静止 60 s+ 也会被学入 → 靠等待时长 + 黄灯常亮提示(操作员看到黄灯别移走目标)
- 恢复总时长 ≈66 s(V4.20 分钟级),A 拿走场景现场复测确认手感
- ENV_RESYNC_WAIT / ENV_LEARN_MAX_TICKS 为编译期宏,现场可调
2026-09-02 — 红灯呼吸对齐 vd960Loop + 上电自检基准判稳(固件 V4.23)
固件版本:V4.23(cmcng.h:FIRMWARE_VER="4.23" + MAIN=4/SUB=23)。devlog 修订 V2.21。
现场反馈(用户测试 DLD154V4)
- 红灯呼吸太快 → 借鉴 vd960Loop 红灯呼吸效果
- 绿灯上电自检闪烁未体现完整自检逻辑 → 应等获得稳定基准值后才停止闪烁
修复 1:红灯呼吸节奏对齐 vd960Loop(main.c poll_red_pwm)
| 项 | 修复前 (V4.22) | 修复后 (V4.23) |
|---|---|---|
| PWM 满量程 | TMR14 ARR=665 | 不变 |
| 大步长 | +100 (≈15% 量程) | +39 (≈5.9%) |
| 近顶小步 | +20 (≈3%) | +10 (≈1.5%) |
| 分界点 | 500/600 (75%/90%) | 585 (88%) |
| 峰值保持 | 3 步 | 3 步 |
| 全周期 | ≈1.6s | ≈2.6s(与 vd960Loop 观感一致) |
- vd960Loop 参考参数:满量程 6800,升 <6000 大步 +400 / 近顶 +100,降 -400,60ms/步
- V4B 按
665/6800≈0.0978缩放取整:39/10/585/660 - 实测仿真:周期 42 步 × 60ms = 2520ms,峰值保持 ≥3 步,写值全程 ≤ ARR
修复 2:绿灯自检闪烁至基准值稳定(TaskLoop.c 稳定期判稳)
根因:原逻辑 _stable_cnt 达 128 样本(≈1.3s)即 g_loop_stable=1,与"基准值是否真稳定"无关;且 static 计数不清零 → 安全复位等二次稳定期 1 个样本即判稳(绿灯自检形同虚设)。
修复:
- 新增
g_stable_cnt(累计样本)/g_settle_cnt(连续窗口漂移达标计数),全局变量INIT_VD()清零、判稳退出时清零 - 每窗(100 样本≈1s)完成时比较窗口平均 Origin 漂移:≤ Origin×0.1% → settle+1,否则清零
- 判稳条件 = 最少样本 128 + 连续 2 窗漂移达标;硬兜底 500 样本(5s) 强制结束自检,防环境长期不稳绿灯无限闪
- 绿灯
poll_green_led()条件不变(INI_LOOP || !power_up || !g_loop_stable),自检闪烁自然持续到基准值稳定 - 安全复位二次稳定期从零开始(原 1 样本瞬间判稳 bug 消除)
验证
tests/test_power_on_stable.c:常量值判稳样本 200 / 首窗尖峰 300 / 持续漂移 500(兜底) / 二次稳定期 200 —— 4 项 PASStests/test_red_breath.c:周期 2520ms / 峰值保持 ≥3 步 / 写值 ≤ARR —— PASSgcc -fsyntax-only(借 vd960Loop AT32F421 库头):main.c / TaskLoop.c 语法通过
待现场验证:呼吸周期观感、上电绿灯自检时长(预计无车 2~3s、首窗尖峰 3s、异常漂移至 5s 兜底)
2026-09-02 — DEBUG 改编译器 -DDEBUG 控制 + 版本号 V4.22
固件版本:V4.22(cmcng.h:FIRMWARE_VER="4.22" + MAIN=4/SUB=22)。devlog 修订 V2.20。
- cmcng.h 删除
DEBUG_ENABLE宏块——DEBUG 改由编译器预处理器设置(Keil C/C++ 预定义符号加DEBUG) - 调试打印仍为
#ifdef DEBUG→ PRINT 生效;发布版编译不带 DEBUG 即自动关闭 - 附带 V4.20 修复:DBG 行 t 恒 0 bug(先取时间再归零)、freeze_ref 残留清零(FRZ 打印干净)
- 负 variation 锁死修复(双向对称基线保护)在 V4.20 已生效,现场日志已验证:三次铁块测试 Origin 稳定、0 次锁死
2026-09-02 — 负variation铁块场景修复:基线跟踪双向对称保护(固件 V4.20)
固件版本:V4.20。devlog 修订 V2.19。
现场现象(用户)
特殊形状铁块(磁导率主导)靠近线圈 → variation 为负(频率下降,CAPVD 高于 Origin):
- 靠近过程无输出(正常——检测只认正 variation,物理限制)
- 铁块慢慢离开时:有时一直无输出,有时一旦输出就释放不了(锁定)
根因(TaskLoop.c 基线跟踪单边保护)
// 修复前: 只挡 dev > +4×dlt —— 负variation(CAPVD>Origin) 时基线照常更新
if (dev < (int32_t)(loop1_dlt_ORG * 4)) {
update_moving_average(..., &loop1_Origin, loop1_CAPVD, ...); // Origin 被污染
}
污染链:铁块靠近 → CAPVD 升 Origin+500 → 基线跟踪"无车"照常更新(或 FREEZE_TIMEOUT=10s 后直接跳污染值)→ Origin 抬高 → 铁块离开 CAPVD 回落 → 跨过抬高的进入线 → 假进入 → Origin 冻结(有车)→ 释放线 = 污染 Origin - dlt(高)→ CAPVD 永远够不到 → 锁死不释放。
修复(双向对称保护)
- 偏差窗口对称:
-4×dlt ≤ dev ≤ +4×dlt才正常跟踪(负偏差也冻结) - 负偏差(dev>0, CAPVD>Origin)只冻结、永不超时更新 Origin——铁块停留多久都不污染
- 正偏差(dev<0, 疑似车)保留原 FREEZE_TIMEOUT 兜底(车辆长时间信号不丢)
- 权衡:长时间负温漂基线不跟随(安全方向,正车检测仍正常)
- 新增
EVT|neg_var_freeze事件打印:负偏差首中时输出 CAPVD/Origin/dev/dlt/频率
验证
tests/test_neg_variation.c回归单测 6 项全过:决策方向 / 负偏差超时不污染 / 正偏差兜底保留 / 完整场景仿真(铁块靠近→停留→离开:无假进入、无锁定)✓- 现有单测(方案A/B)不受影响
2026-09-02 — Debug 串口打印重组:频率/采样/基准全量输出(固件 V4.20)
固件版本:V4.20。devlog 修订 V2.18。 目的:现场有影响算法的异常情况待分析,扩充调试输出便于定位。
打印内容(TTL 调试口,波特率 230400)
① 周期状态行(每 2s,前缀 DBG|)——频率/采样/基准全量:
DBG|t=2000ms f=99kHz Xn=600 LPCNT=218 Value=131072 CAPVD=131072 slow=131072 Origin=131072 dlt=32 SENS=3 VD=0 FRZ=0/0 LIM=0 LOOP=1 STBL=1
| 字段 | 含义 |
|---|---|
| f | 线圈振荡频率 kHz(=240000×LPCNT/CAPVD,V4.27 修正:TMR3=120MHz 计数 + 通道 DIV_2) |
| Xn / LPCNT | 瞬时周期 / 自适应窗口 |
| Value / CAPVD / slow | 原始采样 / 主滤波 / 慢滤波(方案A) |
| Origin / dlt | 基准值 / 当前阈值(无车=进入线,有车=释放线) |
| SENS / VD | 灵敏度档 / 车辆状态 |
| FRZ | freeze_cnt / freeze_ref(基线冻结状态) |
| LIM | 斜率限幅截断计数(2s 内 EMI/干扰次数,周期清零) |
| LOOP / STBL | 线圈状态 / 稳定期标志 |
② 事件行(前缀 EVT|):
enter_try:进入线第一次命中(定位触发来源)leave_try:离开线第一次命中(定位释放来源)loop_disconnect/loop_reconnect:线圈断开/重连(带断开计数、断开瞬间 Xn/CAPVD/Origin/频率)- 原有
Car_In/Car_OFF/Loop stable/Baseline timeout/SENS changed保留
③ 调试开关(cmcng.h):
#define DEBUG_ENABLE 1 // 1=开启(现场分析) 0=关闭(发布)
辅助实现
calc_freq_khz(capvd, lp_cnt):f_kHz = 240000×LPCNT/CAPVD(V4.27 修正:TMR3 计数 120MHz × 通道捕获 DIV_2 → 等效 240MHz/周期;旧 60000 按 60MHz 假设漏算 4 倍)g_slope_limit_cnt:斜率限幅截断计数(IIR 输入被 5% 限幅截断时 +1,周期打印带出后清零)
待办
- 现场抓数:串口 230400 收
DBG|/EVT|行,异常复现时完整记录(至少覆盖异常前后 30s) - 分析:重点看 f 是否突变(线圈/干扰)、Origin 是否异常更新(freeze 误触发)、LIM 是否高频(EMI)
2026-09-01 — 方案B 调校定稿:发布版本号 V4.20
固件版本:V4.20(cmcng.h:FIRMWARE_VER="4.20" + MAIN=4/SUB=20)。devlog 修订 V2.17。 性质:发布定稿版——内容与 V4.07(方案B 调校)一致,版本号按产品线规划跳到 V4.20。
- 灵敏度表(方案B,USE_PLANB_TABLE=1):进入
{337,71,38,25}、释放{51,27,18,12} - 配置:
USE_SLOW_RELEASE=0(快滤波释放)+USE_PLANB_TABLE=1(调校表) - 单测:
test_planb_release.c(方案B)+test_release_slow_filter.c(方案A)均通过 - 历史版本对照:V4.03(方案A α18)→ V4.04(方案A α21+snap)→ V4.05(方案B 实验,加深表失败)→ V4.06(调校表)→ V4.07(SENS=0 回调)→ V4.20(发布)
2026-09-01 — 方案B 现场调校定稿:进入加深 + 释放调浅(固件 V4.06)
固件版本:V4.07(cmcng.h:FIRMWARE_VER="4.07" + MAIN=4/SUB=7)。devlog 修订 V2.16。 状态:方案B 定稿候选——SENS=3 现场实测接近 PD132T,等比推全档。 V4.07 微调:SENS=0 进入 357→337(等比值偏低档触发过深,现场回调折中)。最终表:进入
{337,71,38,25}、释放{51,27,18,12}。
现场调校过程(用户金属板测试)
- V4.05 加深表 {80,42,27,18}:释放比 PD132T 更早 → 加深方向失败
- V4.05 原始表 {60,32,21,14}:也早于 PD132T → 快滤波+原始表不够
- 用户改 SENS=3:进入 21→25、释放 14→12 → 接近 PD132T 最高灵敏手感 ✓
- 关键:进入加深(触发更严)+ 释放调浅(释放更晚) 组合有效
- 滞回 66%→47%(释放线更接近进入线,释放更严格)
V4.06 灵敏度表(等比 ×25/21 进入、×12/14 释放)
| SENS | 进入原表 | 进入新表 | 释放原表 | 释放新表 | 滞回 |
|---|---|---|---|---|---|
| 0 | 300 | 357 | 60 | 51 | 14% |
| 1 | 60 | 71 | 32 | 27 | 38% |
| 2 | 32 | 38 | 21 | 18 | 47% |
| 3 | 21 | 25 | 14 | 12 | 48% |
- 物理含义:进入加深(误触发更少)+ 释放调浅(释放更晚,等效 PD132T 手感)
- ⚠ 与 PD132T 表值不再一致(行为等效);SENS=0 进入 300→357 变化大,现场低档漏检可单独回调
- 代码:
USE_PLANB_TABLE=1时双表生效(TaskLoop.c),=0切回原始 PD132T 对齐表 - 废弃:V4.05 的
ReleaseTable_B独立表已删除(方向错误,并入 SensTable_1 调校)
单测
tests/test_planb_release.c更新:滞回正 ✓ / V4.06 表值 ✓ / 调浅释放≥原始(4档×4速)✓ / 释放时刻 ✓tests/test_release_slow_filter.c(方案A)仍通过
待现场
- 全档实测(尤其 SENS=0 进入 357 是否漏检大车)
- HR0/2 定住 1~2s:预期稳定(快滤波无悬停状态)
- 方案A(V4.04)对比数据补测
2026-09-01 — 方案B 实验:快滤波释放 + 调深释放阈值表(固件 V4.05)
固件版本:V4.05(cmcng.h:FIRMWARE_VER="4.05" + MAIN=4/SUB=5)。devlog 修订 V2.14。 状态:实验对比版——与 V4.04(方案A)现场 A/B 对比后定稿,二选一保留。
背景
V4.04(方案A:慢滤波释放 α21 + 进入 snap)已修两现象,但现场想对比另一条路线:不用慢滤波状态(消除任何滤波悬停风险),改由释放阈值表承担手感对齐。
方案B 配置(TaskLoop.h)
| 宏 | 值 | 含义 |
|---|---|---|
USE_SLOW_RELEASE |
0 | 释放走快滤波(α79@10ms, τ≈22ms),无慢滤波状态 |
USE_PLANB_TABLE |
1 | 释放判定用 ReleaseTable_B(调深表) |
ReleaseTable_B |
{80, 42, 27, 18} |
原始表 {60,32,21,14} 加深 ~30% |
各档滞回验证:ReleaseTable_B < SensTable(进入表)→ 滞回为正,无结构假释放。
⚠ 关键认知:加深方向的物理含义(仿真+单测双重确认)
释放方向是 CAPVD 从车辆深度向 Origin 恢复(从深往浅)。释放线 = Origin − dlt:
- dlt 增大(调深)→ 释放线降低 → CAPVD 恢复中更早碰到 → 释放更早(与"调深=更严格"的直觉相反)
- 单测
tests/test_planb_release.c:4 档 × 4 速度全部确认"加深表释放 ≤ 原始表"(如 SENS=3, 3s 抬:原始@2960ms → 加深@2930ms)
仿真预测(现场实测验证点)
| 板信号深度 | 加深表 vs PD132T | 结论 |
|---|---|---|
| ≥0.2%(200cnt+) | 加深表比 PD132T 早(差 3~6 counts) | 深信号下原始表 {60,32,21,14} 更接近 PD132T |
| ~0.1%(100cnt) | 加深表与 PD132T 差 ~1.3 counts | 浅信号下加深表更接近 |
现场验证:若实测"加深表释放比 V4.04 更早(板抬更低就释放)",说明方向如仿真;若与 PD132T 手感更近,则加深表定稿;否则 USE_PLANB_TABLE=0 一行切回原始表对比。
单测
tests/test_planb_release.c新增(gcc 编译通过):滞回为正 ✓ / 加深表释放不晚于原始表 ✓ / 释放时刻合理 ✓tests/test_release_slow_filter.c(方案A 单测)仍通过,两方案可回归
现场实测结果(2026-09-01 用户金属板测试)
| 配置 | 释放高度 vs PD132T | 结论 |
|---|---|---|
| V4.05 + USE_PLANB_TABLE=1(加深 {80,42,27,18}) | 更低于 PD132T(更早) | 加深方向被实测否定,与仿真预测一致 |
| V4.05 + USE_PLANB_TABLE=0(原始 {60,32,21,14}) | 低于 PD132T(更早) | 快滤波释放早于 PD132T(历史行为复现) |
实验结论:方案B 不可行。 根因:PD132T 的"晚释放"来自慢滤波滞后(速度相关),阈值表只能给"速度无关的固定偏移",快滤波(τ≈22ms)无论怎么调阈值(滞回为正前提下)释放都早于 PD132T(τ≈118ms)。仿真方向预测(加深→更早)被现场完全验证。
路线定稿:回到方案A(慢滤波释放)。 下一步现场测 v4.04-planA(α21 + 进入 snap,用户尚未测过该完整修正版)。
文档同步
- technical-spec §4.3.3 补方案B 实验说明
- analysis/docs/filter-coefficient-79-vs-64.md §4.5 方案B 段(待补)
2026-09-01 — 方案A 现场复核修正:RELEASE_ALFA 18→21 + 进入 snap(固件 V4.04)
固件版本:V4.04(cmcng.h:FIRMWARE_VER="4.04" + MAIN=4/SUB=4)。devlog 修订 V2.13。
背景(现场复核)
方案A(V4.03)落地后金属板复测,两个现象:
- 慢速抬板释放高度 V4B 仍比 PD132T 高一点,且跟手速有关(抬得越慢越接近)
- 定在 HR0/2(释放高度一半)保持 ~1s,V4B 释放继电器,PD132T 不释放
根因分析
| 现象 | 根因 | 证据 |
|---|---|---|
| 1 释放偏高 | τ 对齐用了近似口径:方案A α18 精确 τ≈137ms,PD132T α79@43.7ms 精确 τ≈118ms(α=79 时 T×256/α 近似公式高估 19.6%)+ V4B 释放 3 次确认 30ms |
仿真:2s 抬升 V4B +14mm、8s 抬升 +2mm,与现场"跟手速有关"吻合 |
| 2 HR0/2 假释放 | 双滤波结构(快进+慢出):进入由快滤波(τ≈22ms)30ms 确认,释放判定用慢滤波——进入确认瞬间慢滤波还悬在基线附近,残余信号落在窄带(SENS=3 时 0.032%~0.044%)时释放条件瞬时为真 → 3 次确认数满 → 假释放。PD132T 进出共用同一滤波,进入确认时滤波值已沉过离开线,结构性免疫 | 仿真:0.10% 板 HR0/2 放置 V4B 释放@0.18s,PD132T 不释放 |
修正(V4.04)
- RELEASE_ALFA 18 → 21:精确 τ = −T/ln(1−α) = −10/ln(1−21/256) ≈ 117ms,对齐 PD132T α79@43.7ms 精确 τ≈118ms。仿真释放高度差 3s 抬升 +9mm → +3mm(剩余为 3 次确认 30ms 固有延迟)
- 进入确认 snap:
loop1_CAPVD_slow = loop1_CAPVD(进入线档3 0.032% 恒深于离开线 0.021%,snap 后释放条件结构性为假)→ HR0/2 假释放窗口彻底消除
验证
tests/test_release_slow_filter.c更新 ALFA_SLOW=21:τ fast=30ms/slow=120ms(理论 22/117ms);释放时机差 200ms ✓- 仿真(Origin=100000, SENS=3):α21+snap 下 0.10% 板 HR0/2 放置,原版释放@0.18s → 未释放 ✓
- ⚠ 待板级:真机金属板复测确认释放高度对齐 + HR0/2 保持不再释放
文档同步
- technical-spec §4.3.3 补 V4.04 修正说明
- analysis/docs/filter-coefficient-79-vs-64.md §4.4 方案A 同步 α21 + snap
- release-notes 待发布时更新
2026-08-31 — 释放手感对齐 PD132T:释放慢滤波(方案 A,固件 V4.03)
固件版本:V4.03(cmcng.h:FIRMWARE_VER="4.03" + MAIN=4/SUB=3;⚠ 顺带修正字符串 "4.00" 与数字 4/2 不一致的历史问题)。devlog 修订 V2.12。
背景(现场测试)
PD132T 替换交付后金属板测试(从上往下接近触发、从下往上离开释放):触发高度两边一致,释放高度不一致——V4B 刚离开触发位置一点点就释放,PD132T 要离得更远才释放。
根因分析
| 项 | V4B | PD132T |
|---|---|---|
| 检测节拍 | 10ms | 43.7ms |
| IIR 系数 | ALFA_CAP1=79 | 79(SET_FLT=ON)/64(OFF) |
| τ | ≈32ms | ≈142~175ms |
| 释放确认 | 3×10ms | 单次 |
- 判定公式与阈值表完全一致(
(Origin-dlt_ORG) < CAPVD,表 {60,32,21,14} 已对齐) - 差异在 CAPVD 恢复速度:V4B 快 4.4~5.5× → 刚离开即恢复过浅阈值 → 早释放
- 释放阈值浅(进入的 20%)放大差异;触发阈值深 + 接近过程信号斜率大 → 触发高度差不明显
方案 A 实现(USE_SLOW_RELEASE)
- 新增独立慢滤波
loop1_CAPVD_slow(α=18/256 @10ms → τ≈142ms,复刻 PD132T 恢复速度),吃原始 Value(不经斜率限幅) - 离开判定改用慢滤波值,进入路径不变
- 开关
USE_SLOW_RELEASE(TaskLoop.h 默认 1,0=原快滤波释放,现场可对比回退) - 同步:INIT_VD 复位、稳定期直锁、线圈重连强制收敛
- ⚠ 若现场 PD132T SET_FLT=ON(α64 → τ≈175ms),调
RELEASE_ALFA15(τ≈170ms)更贴近
验证
tests/test_release_slow_filter.c(gcc 单测):τ fast=30ms/slow=140ms(理论 32/142ms);模拟金属板离开(信号每 10ms +80),释放时机 fast=150ms/slow=410ms,差 260ms ✓- 括号结构三版本(原始/改动/回退)计数一致,无结构影响
- ⚠ 待板级:真机金属板测试确认释放高度对齐;MRS 编译
文档同步
- technical-spec §4.3.3 模式 1 补 V4.03 慢滤波说明
- release-notes 待发布时更新
2026-08-28 — 灵敏度进入/离开对齐 PD132T(V2.11)
背景
客户现场在用 PD132T(8051),替换 DLD154V4B(同款芯片平台 AT32F421 的单路产品)。交付要求:平滑——灵敏度表现一致、触发/释放手感无感。
对照 PD132T 源码(SensTable {300,60,32,21} / SensTable1 {60,32,21,14},阈值 Origin×表>>16;离开阈值受 SET_ASB 拨码控制,出厂默认 OFF → 恒 14):
进入表对比:
| 档 | PD132T Δf/f | V4B 原 Δf/f | 差异 |
|---|---|---|---|
| 0 | 0.458% | 0.330% | V4B 灵敏 1.39× |
| 1 | 0.092% | 0.165% | V4B 钝 1.79× |
| 2 | 0.049% | 0.055% | 几乎一致 |
| 3 | 0.032% | 0.031% | 几乎一致 |
离开表对比(PD132T SENUP 标贴 OFF → 电平1 → SET_ASB=1 → 分档 {60,32,21,14} = 出厂默认态):
| 档 | PD132T 离开 | V4B 原离开 | 差异 |
|---|---|---|---|
| 0 | 0.092%(60) | 0.165%(108) | V4B 钝 1.8×,释放偏慢 ⚠ |
| 1 | 0.049%(32) | 0.110%(72) | V4B 钝 2.25× ⚠ |
| 2 | 0.032%(21) | 0.027%(18) | V4B 灵敏 1.16× |
| 3 | 0.021%(14) | 0.021%(14) | 一致 |
决定
// TaskLoop.c
const uint16_t SensTable[4] = {300, 60, 32, 21}; // V2.11(全档与 PD132T 完全一致)
const uint16_t SensTable_1[4] = { 60, 32, 21, 14}; // V2.11(与 PD132T 完全一致)
- 进入表全档与 PD132T 完全一致(216/108/36/20 → 300/60/32/21,Δf/f 0.33%/0.16%/0.055%/0.031% → 0.458%/0.092%/0.049%/0.032%)
- 离开表 {108,72,18,14} → {60,32,21,14}(对齐 PD132T SENUP 标贴 OFF=SET_ASB=1 的分档释放,出厂默认态;拨码低有效,若现场 SENUP 标贴 ON 需改恒 14 表)
- 等效手感修正:V4B IIR τ=32ms vs 142ms、节拍 10ms vs 43.7ms → 同档位下 V4B 检测更快;3 次进入确认 → 调表后仍比 PD132T 抗瞬态误触
- 增强滤波 FLT 不纳入对齐:现场少用(2026-08-28 决策),V4B 恒 79 + 斜率限幅组合更优
相关交付文档
- 完整交付对齐分析:
vd-analysis/docs/pd132t-to-v4b-delivery-alignment.md - 决策记录:脉冲模式不比较(现场少用);有限存在搁置待确认 V4B 是否启用
2026-08-28 — 新增 IWDT 硬件看门狗(V2.10)
背景
V4B 是全产品线唯一无看门狗的型号(对比:M1H 有 WDT_CONTR、PD132 系有 IWDG/WWDG、154Pro V3.03 有 WWDG 558ms)。现场若主循环卡死/FreeRTOS 调度异常,表现为"假活"——指示灯正常但检测逻辑已死,只能断电恢复。
实现(对齐 154Pro V3.03 双保险模式)
// main(): wdt_init() — IWDT 分频16 + 重装载4095, 使能后立即喂一次
// TMR15 ISR: g_wdg_counter++ (5ms)
// 主循环: poll_wdg() — 计数达 100 (500ms) 才 wdt_counter_reload()
- 超时 ≈ 1.64s(LSI≈40kHz:16×4096/40k),喂狗周期 500ms,余量 >3×
- 双保险语义:ISR 死 → 计数不涨 → 永不喂狗;主循环死 → poll_wdg 不执行 → 超时复位
- FreeRTOS 调度失败/任务创建失败 → 无人喂狗 → 复位(避免"假活")
涉及文件
| 文件 | 变更 |
|---|---|
src/main.c |
Timr6_Init() 后调 wdt_init() |
src/TaskLoop.c |
+g_wdg_counter + wdt_init() + poll_wdg();TMR15 ISR 计数;主循环喂狗 |
inc/TaskLoop.h |
+WDT 宏 + extern + 函数声明 |
验证
- 隔离测试(host gcc mock wdt_* 驱动)5 项断言全过:init 配置、10s 喂狗 20 次(500ms 精确)、ISR 死不喂狗、边界 99/100 tick
- 待现场验证:实际复位时间(LSI 实际频率),用
RST_REASON类机制确认复位源
⚠ 现场发现并修复:WDT_DIV 传值 bug(V2.10.1)
现象:现场实测 WDT_COUNTER_LIMIT=100(500ms 喂狗)不断复位重启,改为 50(250ms)才正常。
根因:wdt_divider_set() 参数是枚举值不是分频数值——WDT_CLK_DIV_16 = 0x02,寄存器只取低 3 位。宏误写 WDT_DIV=16(0b10000)→ 寄存器写入 0 = WDT_CLK_DIV_4 → 实际分频 4,实际超时 410ms < 喂狗周期 500ms → 每次喂狗前已超时,不断复位。
修复:#define WDT_DIV 2(枚举值)+ 调用处显式 (wdt_division_type) 转换;隔离测试升级 mock 为"寄存器 3bit 截断 + 反推实际分频",复现 bug 机制并断言修复后超时 1638ms > 500ms。
对照教训:vd960Loop 原实现用 wdt_divider_set(WDT_CLK_DIV_64) 枚举写法 ✓ 无此问题——AT32 WDT 分频参数一律用枚举常量,勿传数值。
2026-08-28 — 平坦性离开判定默认关闭(现场实测不理想)
背景
同一现场(广告杆/道闸)与 V2.8 SENS=3 调档同源。广告杆落杆误触发排查中发现,平坦性三条件离开判定(CN200910309382,V1.4 移植)在真实场景响应不理想:
- 平坦性依赖"第一上升坡面"动态计算 Δ2/Δ3,车辆离开缓慢/多次驻留时,坡面特征不稳定,Δ2/Δ3 失真
- 三条件(|f-fb|<dlt && |f'|<Δ2 && |f''|<Δ3)对离开过程平坦度要求苛刻,现场车辆(半挂、缓慢通过)离开确认滞后/不触发
- 与简单 cnt_release 防抖对比实测,平坦性未体现出大车防误触优势,反而引入离开延迟
决定
// TaskLoop.h
#define USE_FLATNESS_EXIT 0 // V2.9 默认: 简单 cnt_release 防抖
- 离开判定切回滞回 + 连续 3 次确认(
(Origin-dlt) < CAPVD且cnt_release>=3),与 DLD154Pro 当前行为一致 - 平坦性代码完整保留在
#if USE_FLATNESS_EXIT内,可一行开启做现场对比 - 全部平坦性状态变量/初始化/进入重置均带
#if包裹,改 0 直接编译剔除,无残留引用
同步文档
technical-spec.md§4.3.3:模式 1 标为默认(V2.9 起),模式 2 标"默认禁用(#if 0,代码保留)";修正模式 1 伪代码方向错误(CAPVD < Origin + dlt→(Origin - dlt) < CAPVD)product-manual.md/release-notes.md/roadmap.md:离开判定口径统一为"滞回 + 连续确认(平坦性可选)"- 版本历史补 V2.7/V2.8(此前 release-notes/product-manual 缺行),本次记 V2.9
2026-06-23 — 跳出框框:去掉 >>6 精度浪费
背景
DLD154V4B 的检测算法继承自 M1H(STC12C5202, 2008)和 TLD-110(P87LPC762, 2003),但有几个关键硬件差异:
| 特性 | M1H / TLD-110 | DLD154V4B |
|---|---|---|
| 主频 | ~12MHz (8051) | 120MHz (Cortex-M4) |
| 分频芯片 | CD4060 (Pin5, ÷32) | 无,直连 PA7 |
| MCU 内分频 | 无 | TIM3 DIV_4 → DIV_2 |
| 有效分频比 | ÷32 | ÷2 |
| 捕获方式 | PCA 周期捕获 / 门控计数 | TIM3_CH2 硬件输入捕获 |
问题:<<6 和 >>6 的精度浪费
原始代码的数据流存在一个"膨胀再压缩"的精度陷阱:
TMR3 ISR:
Xn = 周期差值 (4800 ticks @ DIV_4)
LPCNT = (32768 << 6) / Xn = 437 ← 窗口开大 64×,降噪
Value = Σ 437次 Xn ≈ 2,097,600 ← 437 样本精密累加
vd1_task:
tmp = Value >> 6 = 32,775 ← 6bit 精度全部丢弃!
CAPVD = IIR(tmp...) ← IIR 只看到 ~6 样本有效信息
<<6 和 >>6 在数学上互相抵消——437 个样本累加,然后右移 6 位,等效仅用 ~7 个样本(437/64 ≈ 6.8)。窗口开大降噪了,但精度被自己扔掉了。
方案:去掉 <<6/>>6,用 MEASUREMENT_BASE
TMR3 ISR:
LPCNT = 131072 / Xn = 27~54 ← 自适应窗口,不丢精度
Value = Σ Xn ≈ 131072 ← 直接作为检测输入
vd1_task:
CAPVD = IIR(Value) ← 全精度参与滤波
| 参数 | 旧方案 | 新方案 |
|---|---|---|
| LPCNT (100kHz, DIV_2) | — | 54 |
| 测量窗口 | 17.5ms (DIV_4) | ~1ms |
| 有效精度/窗口 | ~6 样本 (>>6 后) | 54 样本 (全保留) |
| Origin 范围 | ~32K | ~131K |
| 灵敏度阈值 | 百分比公式,自动按比例缩放 ✓ | 同 ✓ |
| 进入响应 | ~50ms | ~3ms |
同步改进
| # | 改动 | 原因 |
|---|---|---|
| 1 | TIM3 分频 DIV_4 → DIV_2 | 提高采样率,中断率 2× 仍安全 (CPU<3%) |
| 2 | MEASUREMENT_BASE = 131072 (2^17) | 平衡精度和 Origin 范围 |
| 3 | 去除所有 >>6 | 保留全采样精度 |
| 4 | 离开增加 cnt_release >= 3 防抖 |
防瞬间噪声导致误落杆 |
| 5 | 基线冻结 + 100 窗口慢跟踪 | 仿 TLD-110,有车不更新基线 |
为什么不需要 CD4060 外部分频
AT32F421 的 TIM3 有内置输入分频器,配合 120MHz 主频:
| 线圈频率 | DIV_2 中断率 | CPU 占用 (50周期/ISR) |
|---|---|---|
| 100 kHz | 50k/s | 2.1% |
| 150 kHz | 75k/s | 3.1% |
| 200 kHz | 100k/s | 4.2% |
均在安全范围内,无需外部分频芯片。
对比 M1H/TLD-110
| 指标 | M1H (CD4060÷32) | DLD154V4B (新) |
|---|---|---|
| 测量间隔 | ~50ms (固定) | ~1ms (自适应) |
| 进入防抖 | 500ms IN_DELAY | 500ms IN_DELAY |
| 离开防抖 | 1.9s OUT_DELAY | 3次连续确认 + 1.9s OUT_DELAY |
| 基线跟踪 | 100次 (有车也跟) | 100次 (有车冻结) |
2026-06-23 — 精简重构,对齐参考实现
- 删除二阶差分滤波(计算但从未参与判决)
- 删除 FltHistoryManager 死代码(20+ 未用字段)
- 删除 StageRangeConfig(区间约束未引用)
- 删除动态窗口切换(LOOP_WINDOW_SIZE_LOW→FAST)
- 时序状态机简化:去掉 PLUSE_IN_F/PLUSE_IN 中间层
- 拨码去抖 10→5(对齐 M1H)
- 代码量:1177→706 行(-40%)
2026-06-22 — 参考分析
见 reference_analysis.md:M1H + TLD-110 完整算法分析。
2026-06-23 — 指示灯行为规范化
LED 硬件对应
| 硬件 | 引脚 | 宏 | 行为 |
|---|---|---|---|
| 红灯 | PB1 | (无宏, TMR14 PWM) | 始终呼吸,不干预 |
| 绿灯 (LEDA) | PA9 | LEDA_ON/LEDA_OFF |
自检慢闪 / 有车亮 / 无车灭 |
| 黄灯 (LEDC) | PA10 | LED_YELLOW_ON/OFF |
故障快闪 / 断开次数编码 |
注:
LEDA宏在 BSP 遗留代码中指向 PB1(红灯),已修正为 PA9(绿灯)。LEDB宏无实际 IO,已删除。
绿灯行为
| 状态 | 绿灯 |
|---|---|
| 上电自检 (Origin 未确立) | 慢闪 200ms |
| 数值稳定期 (128 样本 ≈ 128ms) | 慢闪 200ms |
| 正常工作,无车 | 灭 |
| 正常工作,有车 | 亮 |
| 线圈断开中 | 灭(黄灯快闪负责故障指示) |
黄灯行为
| 条件 | 黄灯 |
|---|---|
| 上电后从未接线圈 | 快闪 200ms |
| 线圈当前断开中 | 快闪 200ms |
| 重连后,断开过 1 次 | 1 短闪 (80ms 亮) + 1.2s 间隔 |
| 重连后,断开过 2 次 | 2 短闪 + 1.2s 间隔 |
| 重连后,断开过 3+ 次 | 3 短闪 + 1.2s 间隔 |
| 正常,无断开记录 | 灭 |
"不接线圈上电,上电后再接线圈"不计入断开次数。
2026-06-23 — 上电稳定期 & 线圈重连
上电稳定期
Origin 首次确立后,线圈振荡需要时间稳定。新增 g_loop_stable 标志:
INIT_VD()→g_loop_stable = 0vd1_task(): 稳定期内只做 IIR + 基线跟踪,跳过进入检测- 128 样本 (~128ms) 后
g_loop_stable = 1,正式启用检测 - 安全复位时重置
g_loop_stable = 0
线圈重连状态保持
断开时不丢 VD_FLAG,重连后快速收敛 IIR:
断开: 保留 loop1_VD_FLAG,仅关断继电器
重连: loop1_CAPVD = 0 → 首个样本直锁 Value → IIR 后续正常跟踪
| 断开前 | 断开期间 | 重连后 | 检测结果 |
|---|---|---|---|
| 有车 | 车还在,绿灯灭 | 车还在 | CAPVD < Origin-dlt → VD_FLAG=1 → 绿灯亮 |
| 有车 | 车离开 | 车离开 | CAPVD ≈ Origin → cnt_release→3 → VD_FLAG=0 |
| 无车 | 车进入 | 车进入 | CAPVD < Origin-dlt → VD_FLAG=1 → 绿灯亮 |
2026-06-23 — 移植平坦性离开判定(CN200910309382)
来源
专利 CN200910309382(中山大学,张辉/黄永强/陈古典)提出平坦性三条件判定法, 解决大车通行时频率曲线的负波峰和近零波谷导致单一阈值法多次误触发的问题。
算法
车辆到达 → 单一阈值法 f(i) - f_b > Δ1 (沿用 SensTable)
车辆离开 → 平坦性三条件 同时满足:
① |f - f_b| < Δ1 频率回归基频 (SensTable_1)
② |f'| < Δ2 一阶导数近零
③ |f''| < Δ3 二阶导数近零
Phase 1 (g_exit_state=0): 车辆进入线圈后,追踪第一上升坡面,
记录最大 |f'| 和 |f''|。当斜率连续 3 次降到 SLOPE_FLAT_THRESH 以下,
计算动态阈值:
Δ2 = max_slope / K1 (K1=8)
Δ3 = max_slope_rate / K2 (K2=8)
Phase 2 (g_exit_state=1): 每帧检查三条件。连续 3 次全部满足 → 车辆离开。
与传统方法对比
| 方法 | 离开判据 | 大车防误检 |
|---|---|---|
| M1H/TLD-110 | 单一滞回阈值 | ❌ 多峰可能多次触发 |
| 原 cnt_release | 连续 3 次超阈值 | ⚠️ 固定阈值,大车波谷可能误判 |
| 平坦性判定 | f-f_b |
参数说明
| 常量 | 值 | 含义 |
|---|---|---|
| K1, K2 | 8 | 动态阈值除数(专利推荐值) |
| SLOPE_FLAT_THRESH | 100 | 斜率趋零判断阈值 |
| MIN_DELTA2 | 5 | Δ2 下限(防除数过小) |
| MIN_DELTA3 | 2 | Δ3 下限 |
| FLAT_CONFIRM_CNT | 3 | 平坦连续确认次数 |
整数化适配
专利原实现使用 float(Hz 频率值),DLD154V4B 用 uint32 定点(Origin≈131K)。 导数计算同样用 int32 整数差分,阈值 /K1、/K2 做整数除法,精度足够。
2026-06-23 — Origin 污染保护 & 宏开关
USE_FLATNESS_EXIT 宏
新增编译开关,一行切换离开判据:
#define USE_FLATNESS_EXIT 1 // 1=平坦性, 0=cnt_release防抖
所有平坦性状态变量和逻辑用 #if USE_FLATNESS_EXIT 包裹。
Origin 基线污染保护
问题:实测发现车辆驶入时 Xn 偶尔先增大再减小。无车状态下 Origin 跟踪上升,
被污染到虚高值。进入检测虽触发,但离开时 Origin 冻在虚高处,
|f-f_b| 远超 SensTable_1 阈值 → 绿灯常亮、永远不释放。
根因:CAPVD 异常上升期间,moving average 持续将虚高值写入 Origin。
修复:在基线跟踪前增加保护条件:
dev = CAPVD - Origin;
if (dev < dlt_ORG × 4)
update_moving_average(...); // 安全跟踪
else
freeze; // 冻结 + 重置累计
冻结阈值 = 进入阈值的 4 倍,随灵敏度自动缩放。
| 场景 | CAPVD | Origin | dev | 阈值(×4) | 结果 |
|---|---|---|---|---|---|
| 正常无车 | 127081 | 127080 | +1 | 276 | 跟踪 ✓ |
| 异常上升 | 127884 | 127085 | +799 | 276 | 冻结 ✓ |
2026-06-24 — 时序参数修正 & 接口更正
时序参数修正
OUT_DELAY 和 PULSE_DELAY 之前沿用 M1H 的值(1.9s / 950ms),现修正为 500ms:
| 参数 | M1H 旧值 | DLD154V4B 新值 |
|---|---|---|
| OUT_DELAY | 1.9s (38 tick) | 500ms (10 tick),SW_4 控制开关 |
| PULSE_DELAY | 950ms (19 tick) | 500ms (10 tick),固定 |
SW_4 语义:0 = 无离开延时(立即脉冲),1 = 离开延时 500ms。删除 OUT_DELAY_FAST / PULSE_DELAY_FAST 宏,因只有一组值。
// TaskLoop.h
#define OUT_DELAY 10 // 离开防抖 500ms(仅 SW_4=ON 时生效)
#define PULSE_DELAY 10 // 脉冲宽度 500ms
// TaskLoop.c
if (SET_DLY) {
loop1_OUTCNT++;
if (loop1_OUTCNT > OUT_DELAY) { ... } // 500ms 延时
} else {
// 无离开延时:立即 FLAG_PLUSE
}
接口修正
- 去除所有 RS485 相关描述:本产品只有 TTL 电平 UART Tx 调试口
- 产品手册端子定义:RS485-A/B → Tx TTL 调试输出
- 技术规格书 §9:整节从 RS485 协议改为 TTL Tx 调试接口说明
2026-06-26 — M4 核心优化:双路 IIR + 进入确认 + 斜率限幅
背景
DLD154V4B 的 8051 时代设计在 M4 上可以做得更好。8051 的 50ms tick 是 CPU 限制,不是最优选择。
三项改进
1. 10ms tick + 双路 IIR
| 滤波器 | α | τ | 用途 |
|---|---|---|---|
| CAPVD (慢速) | 18/256 ≈ 0.07 | 135ms | 基线跟踪,等效原 50ms 的 79/256 |
| CAPVD_fast (快速) | 128/256 = 0.5 | 28ms | 进入/离开检测判定 |
tick 提升到 10ms,但通过调整 α 保持与 50ms 设计相同的滤波强度。快速 IIR 用于检测,慢速 IIR 用于基线,两路各司其职。
2. 斜率限幅
EMI/闪电等瞬态干扰会造成 CAPVD 瞬间跳变。物理车辆不可能让线圈频率瞬间改变 >5%:
max_step = CAPVD × 5 / 100; // 5% 限幅
if (|delta| > max_step) delta = clamp(delta, -max_step, max_step);
尖峰被截断,真实车辆信号(缓慢的频率漂移)不受影响。
3. 进入确认
原设计:单次 CAPVD < Origin-dlt → 立即 VD_FLAG=1(同 8051)
新设计:CAPVD_fast 连续 3 次低于阈值 → 才判定有车
if (CAPVD_fast < Origin - dlt)
entry_cnt++;
if (entry_cnt >= 3) { VD_FLAG = 1; ... }
else
entry_cnt = 0; // 一旦恢复就重置
对真实车辆:CAPVD_fast τ=28ms,3 次确认 = 30ms,加上 IN_DELAY 500ms = 总响应 ~530ms,比原来的 550ms 还快。
对瞬态干扰:单个尖峰无法连续 3 次 → 被过滤。
对比
| 指标 | 8051 原设计 | M4 优化 |
|---|---|---|
| tick 周期 | 50ms | 10ms |
| IIR τ (检测) | 135ms | 28ms (5× 快) |
| IIR τ (基线) | 135ms | 135ms (相同) |
| 进入判定 | 单次阈值 | 3 次连续确认 |
| 瞬态抑制 | 无 | 斜率限幅 + 确认 |
| 进入响应 | ~550ms | ~530ms |
| 误触发风险 | 中 | 低 |
兼容性
- 离开检测路径不变(cnt_release 平坦性均已带确认)
- 灵敏度表、IN_DELAY、OUT_DELAY 等参数不变
- 可通过
ENTRY_CONFIRM宏调整确认次数,MAX_SLOPE_RATE调整限幅强度
2026-06-26 — CAPVD_fast 初始化修复
问题
M4 V2.0 引入双路 IIR 后,进入检测使用 CAPVD_fast(快速 IIR,α=0.5)。但 CAPVD_fast 始终为 0,导致首次进入判定就触发有车。
根因
// 原代码(错误):
if (loop1_CAPVD_fast != 0) {
loop1_CAPVD_fast = (loop1_CAPVD_fast + loop1_CAPVD) / 2;
}
TMR3 ISR 首次捕获时直接设置 loop1_CAPVD(不为 0),INIT_VD 将 CAPVD_fast 初始化为 0。vd1_task 进入时 CAPVD != 0 → if (CAPVD_fast != 0) 永远为 false → CAPVD_fast 保持 0 不更新。
修复
条件反转:== 0 时首次锁定当前 CAPVD 值,之后正常执行快速 IIR。
// 修复后:
if (loop1_CAPVD_fast == 0) {
loop1_CAPVD_fast = loop1_CAPVD; // 首次直接锁定
} else {
loop1_CAPVD_fast = (loop1_CAPVD_fast + loop1_CAPVD) / 2;
}
2026-06-26 — 稳定期绕过 IIR 和斜率限幅
问题
上电后很快输出有车状态。日志显示:
First_capSum:177406, Origin:177406 ← 首测为瞬态高值
Loop stable, Origin:149755 ← 稳定期后 Origin 仍偏高
Car_In, Value:128654, Origin:149755 ← Origin - Value = 21067 >> dlt=82
根因
V2.0 引入的 5% 斜率限幅 在稳定期内仍然生效。首测 CAPVD=177406 是瞬态高值(~38% 偏高),斜率限幅让 CAPVD 在 128 个采样周期内只能缓慢下降到 149755 — 无法在稳定期内充分收敛。100 窗口滑动平均被前半段的高值污染,导致 Origin 停在 149755,远高于真实值 ~128688。
修复
稳定期内不走 IIR 和斜率限幅——直接用 raw Value 建立基线:
if (!g_loop_stable) {
/* 稳定期内不做斜率限幅和 IIR — 直接用 Value 快速收敛到真实基线 */
loop1_CAPVD = loop1_Value;
loop1_CAPVD_fast = loop1_Value;
// ... 滑动平均跟踪 ...
return;
}
稳定期结束后恢复正常 IIR + 斜率限幅用于检测。
| 场景 | 修复前 | 修复后 |
|---|---|---|
| 首测瞬态 | 177406 被限幅缓慢下降 | 直接被 128688 覆盖 |
| Origin 收敛 | 149755 (偏离 +16%) | ~128688 (正确) |
| 稳定期结束 | Origin 偏离 → 误判有车 | Origin 准确 → 正常检测 |
2026-06-29 — 基线冻结超时自动恢复
问题
V1.5 引入的 Origin 污染保护机制在 CAPVD 异常偏高时永久冻结基线。如果线圈因环境变化(温度漂移、器件老化、更换线圈)稳定在新的频率值,Origin 永远不会更新 → 绿灯常亮、永久误判有车。
方案
在冻结路径上增加超时自动恢复 + 稳定性验证:
#define FREEZE_TIMEOUT 3000 // ~30s @ 10ms/tick
#define FREEZE_STABILITY_RATE 2 // 稳定性窗口: 参考值的 ±2%
if (dev >= dlt_ORG × 4) {
if (freeze_cnt == 0)
freeze_ref = CAPVD; // 记录冻结起始值
else if (|CAPVD - freeze_ref| > freeze_ref × 2%)
reset(freeze_cnt, freeze_ref); // 波动过大 → 重新计时
freeze_cnt++;
if (freeze_cnt >= 3000) {
Origin = CAPVD; // 连续30s稳定在±2%窗口内 → 接受
}
}
行为表格
| 场景 | CAPVD 行为 | 稳定性检查 | 结果 |
|---|---|---|---|
| 车辆驶入(Xn 先增) | 偏高 2~3s 后下降 | 中途恢复 → freeze_cnt 清零 |
正常冻结保护 ✓ |
| 温度漂移 | 缓慢爬升到新值并稳定 | 爬升阶段频繁重置;稳定后连续 10s | Origin 更新 ✓ |
| 更换线圈 | 瞬间跳到新频率 | 稳定后连续 10s | Origin 更新 ✓ |
| 车辆缓慢驶入(CAPVD 持续爬升) | 持续偏高且不断上升 | 每超出 ±2% 就重置 → 永远到不了 10s | 不触发更新 ✓ |
最后一行是关键:如果没有稳定性检查,车辆缓慢驶入时 CAPVD 持续偏高 10s 也会触发 Origin 更新——这是错误的。
2026-06-29 — 架构简化:单路 IIR ALFA_CAP1=79 + WINDOW_ORIGIN=500
背景
双路 IIR(慢速 α=18/256 + 快速 α=0.5)在 ALFA_CAP1=18 时斜率限幅参考 CAPVD 拖累了快速通路, 多次修补后发现:ALFA_CAP1=79 @10ms 本身就 τ≈32ms,已经足够快,无需双路复杂度。
改动
| 项目 | 改前 | 改后 |
|---|---|---|
| ALFA_CAP1 | 18 (@10ms, τ=135ms) | 79 (@10ms, τ=32ms) |
| IIR 路数 | 双路(慢+快) | 单路 |
| WINDOW_ORIGIN | 100 (1s) | 500 (5s) |
| 稳定期窗口 | 500 | 100 |
update_moving_average window |
uint8_t | uint16_t |
| 快速 IIR 输入 | CAPVD(慢速输出,滞后) | 已删除 |
| 斜率限幅 | 快/慢双参考(CAPVD + CAPVD_fast) | 单参考 CAPVD |
保留的 V2 保护机制
- 斜率限幅 (MAX_SLOPE_RATE=5%)
- 进入确认 (ENTRY_CONFIRM=3)
- 基线冻结超时 (10s + ±2% 稳定性检查)
- 稳定期绕过 IIR/限幅 (V2.2)
两阶段基线策略
稳定期: 100 样本 × 10ms = 1s → 快速收敛,开机即用
正常: 500 样本 × 10ms = 5s → 强噪声抑制,稳定跟踪
2026-06-30 — 项目文档补全
- 验收标准 V1.0: 环路车辆检测器验收标准文档,涵盖电气特性、检测精度、响应时间、环境适应性
- 发展路线图 V1.0: M1H→V4B 演进回顾 + V3.0 目标规划
2026-08-27 — 灵敏度最高档调整:SENS=3 阈值 10→20(防误触发)
改动
| 文件 | 内容 |
|---|---|
src/TaskLoop.c |
SensTable[3] 10→20(Δf/f 0.015%→0.031%,ΔL/L 0.031%→0.061%);SensTable_1[3] 9→14(滞回 90%→70%) |
src/main.c |
注释掉重复定义 g_input_div = 1(TaskLoop.c:23 已有定义,清理 ODR 重复) |
原因(现场)
现场广告杆/道闸落杆时最高灵敏度档(10/9)易误触发——落杆机械动作 + 电机电磁扰动使 CAPVD 波动越过 0.015% Δf/f 阈值,误判有车(落杆瞬间继电器误动作)。提高至 20(0.031% Δf/f)并加大滞回(离开 14/进入 20 = 70%),落杆扰动不再越线,正常车辆信号(轿车典型 ΔL/L 1~5%)不受影响。
文档同步
docs/technical-spec.md§4.3.1 灵敏度表 + 表格(含 ΔL/L 口径说明)docs/reference_analysis.md§5.6 灵敏度表
修订记录
| 版本 | 时间 | 说明 |
|---|---|---|
| V2.58 | 2026-09-04 | V4.36.22 最低电感量 20→25µH: 频率上限 153kHz; L<25µH 断开级快闪; test 153/154 |
| V2.57 | 2026-09-04 | V4.36.21 电感量判定防抖 1s→5s (COIL_FAULT_HOLD_TICKS=500): 越界/恢复均 5s, 防瞬态误检 |
| V2.56 | 2026-09-04 | V4.36.20 最低工作电感量 COIL_L_MIN_UH=20µH (43nF): L<20µH(f>171k)→断开级快闪; 一长一短仅 L 偏大; test 171/172 |
| V2.55 | 2026-09-04 | 故障补偿触发幅度量化说明 (dev>+4×dlt; SENS=3≈电感+0.31%) |
| V2.54 | 2026-09-04 | V4.36.19 低Q 释放抗抖: τ50ms 平滑判释放+带回×1.5 (REL_ALFA/REL_BAND_LO_MULT), 高/中Q 零影响 |
| V2.53 | 2026-09-04 | V4.36.18 频率窗下界 20→18kHz (18~125kHz) |
| V2.52 | 2026-09-04 | 安全复位观感勘误(无代码): 绿灯镜像继电器后复位指示变化; manual 4.5/spec 对齐实际行为 |
| V2.51 | 2026-09-04 | V4.36.17 修复上电无线圈黄灯不闪: 黄灯模式1 改 !LOOP_OK(5ms 实时) |
| V2.50 | 2026-09-04 | V4.36.16 上电自检与重连灯语义分离: 黄灯去!power_up, 判稳门控限运行中(stable=1) |
| V2.49 | 2026-09-04 | V4.36.15 重连判稳门控: 值稳定(600ms无漂移)+回带才放行, Origin 自动对齐, 强车8×dlt例外, 5s兜底 |
| V2.48 | 2026-09-04 | V4.36.14 重连确认窗漏网路径修复: 主循环拍级上升沿检测替代 ISR LOOP_OK0 |
| V2.47 | 2026-09-04 | V4.36.13 一长一短 灭 100→300ms (dur 180/60/20/140, 周期2.0s) |
| V2.46 | 2026-09-04 | V4.36.12 一长一短长亮 300→900ms (dur 180/20/20/140, 周期1.8s) |
| V2.45 | 2026-09-04 | V4.36.11 低Q 重连抑制窗 400→1500ms (分档 200/300/1500ms) |
| V2.44 | 2026-09-04 | V4.36.10 绿灯镜像 RLY1→RLY2 默认继电器(PA5); RLY1 为拨码3可选脉冲继电器 |
| V2.43 | 2026-09-04 | V4.36.9 频率窗上限 115→125kHz (20~125kHz, 43nF≈38µH起) |
| V2.42 | 2026-09-04 | V4.36.8 进入/释放确认按Q档(高3/中4/低5样本), dlt已比例化无需分档 |
| V2.41 | 2026-09-04 | V4.36.7 参数: RELAY_HOLD 1s; Q抑制 高200/中300/低400ms |
| V2.40 | 2026-09-04 | V4.36.6 高Q 抑制窗 0→100ms(短兜底), 分档终值 100/200/400ms |
| V2.39 | 2026-09-04 | V4.36.5 重连起振抑制按Q分档(f>100k低Q 400ms/80~100k中Q 200ms/≤80k高Q 0ms), 进入确认挂起 |
| V2.38 | 2026-09-04 | V4.36.4 绿灯=RLY1 继电器实际输出状态(吸合亮/释放灭), 删断开强制灭分支; 自检期慢闪不变 |
| V2.37 | 2026-09-04 | V4.36.3 有车断开继电器保持 RELAY_HOLD_MS=500ms(ISR计时/宏可调); 无车断开立即释放不变 |
| V2.36 | 2026-09-04 | V4.36.2 线圈重连确认窗 100ms(防抖动重复计数/首样本毛刺); 断开判定不加防抖 |
| V2.35 | 2026-09-04 | 版本体系增加修订号: 4.36.1 (MAIN/SUB 产品定, 小改只增 REV); 启动打印 fw 行 |
| V2.34 | 2026-09-04 | V4.36 频率窗上限: 108→115kHz(43nF板≈44µH, 放行~48µH小线圈) |
| V2.33 | 2026-09-04 | V4.35 频率窗上限复核: 92→108kHz(43nF板口径≈50µH, 92@43nF≈70µH过严) |
| V2.32 | 2026-09-04 | V4.34 产品基准回到三极管库存板: COIL_CAL_C_NF 68→43; 0Ω改动仅机理验证 |
| V2.31 | 2026-09-04 | V4.33 线圈频率窗上限 COIL_F_OK_MAX_KHZ 120→92kHz |
| V2.30 | 2026-09-04 | V4.32 黄灯一长一短: 200/100/100/800ms → 300/100/100/700ms |
| V2.29 | 2026-09-04 | V4.31 故障补偿时序再调: 预判2s(200)/补偿7s(700)/恢复2s, 总 ~15s |
| V2.28 | 2026-09-04 | V4.30 故障补偿时序: 预判3s(300)/补偿8s(800)/恢复2s(200), 总 ~16s |
| V2.27 | 2026-09-04 | V4.29 硬件修复(拨码三极管5.1K→0Ω)后 C_eff=68.1~68.9nF≈名义66, COIL_CAL_C_NF 43→68 (旧43为5.1K带病特性作废) |
| V2.26 | 2026-09-04 | V4.28 电感量估算引入标定 COIL_CAL_C_NF=43(名义 66nF vs 实测 C_eff≈43,5 组反推 41.3~45.5nF);残差 ±6% |
| V2.25 | 2026-09-04 | V4.27 频率测量 4 倍偏差修正(calc 60000→240000:120MHz×DIV_2);coil_l_uH 随 f 修正;旧 f/L 日志需 ×4 |
| V2.24 | 2026-09-04 | V4.26 线圈电感量告警(频率窗 20~120kHz 一长一短)+ 故障补偿 60s→10s;行尾规范化 CRLF |
| V2.23 | 2026-09-02 | V4.25 环境异常黄灯预判(锁存):dev>+4dlt 高位连续 5s 触发 g_env_warn 锁存常亮;回摆/目标靠近保持,环境空闲稳定 5s(ENV_RECOVER_WAIT)才解除;60s 才真正学习 |
| V2.20 | 2026-09-02 | V4.22 DEBUG 改编译器 -DDEBUG 控制(cmcng.h DEBUG_ENABLE 删除) |
| V2.19 | 2026-09-02 | V4.20 负variation铁块锁死修复:基线跟踪双向对称保护(±4×dlt 对称窗口) |
| V2.18 | 2026-09-02 | V4.20 Debug 串口打印重组:频率/采样/基准全量输出(DBG/EVT 前缀) |
| V2.17 | 2026-09-01 | V4.20 方案B 调校定稿发布版本号(内容同 V4.07) |
| V2.16 | 2026-09-01 | V4.06→V4.07 方案B 现场调校定稿:进入加深 + 释放调浅;SENS=0 回调 337 |
| V2.14 | 2026-09-01 | V4.05 方案B 实验:快滤波 + 调深释放阈值表(A/B 现场对比) |
| V2.13 | 2026-09-01 | V4.04 方案A 修正:RELEASE_ALFA 18→21(精确τ117ms)+ 进入 snap 消除假释放 |
| V2.12 | 2026-08-31 | V4.03 释放手感对齐方案A:释放慢滤波 USE_SLOW_RELEASE(α18) |
| V2.11 | 2026-08-28 | 灵敏度 0/1 档对齐 PD132T(216/108→300/60,Δf/f 0.33%/0.16%→0.46%/0.09%),客户现场替换平滑交付 |
| V2.10 | 2026-08-28 | 新增 IWDT 硬件看门狗(超时≈1.64s,双保险喂狗);修复 WDT_DIV 分频枚举传值 bug(勿传 16,用 WDT_CLK_DIV_16) |
| V2.9 | 2026-08-28 | 平坦性离开判定默认关闭(现场实测不理想),切回简单 cnt_release 防抖 |
| V2.8 | 2026-08-27 | 灵敏度最高档 SENS=3 阈值 10→20、离开 9→14(防误触发);清理 g_input_div 重复定义 |
| V2.7 | 2026-06-30 | 验收标准 + 发展路线图文档 |
| V2.6 | 2026-06-29 | 架构简化: 单路 IIR ALFA_CAP1=79, WINDOW_ORIGIN=500, 稳定期100 |
| V2.5 | 2026-06-29 | 冻结超时 30s→10s,加快环境变化响应 |
| V2.4 | 2026-06-29 | 冻结超时增加稳定性检查: ±2% 窗口内连续稳定 |
| V2.3 | 2026-06-29 | 基线冻结超时: 持续偏高后强制更新 Origin,防止死锁 |
| ------ | ------ | ------ |
| V2.2 | 2026-06-26 | 稳定期绕过 IIR/斜率限幅,用 Value 直接收敛基线 |
| V2.1 | 2026-06-26 | CAPVD_fast 初始化修复(条件反转为 ==0 首次锁定) |
| V2.0 | 2026-06-26 | M4 优化: 双路 IIR + 斜率限幅 + 进入确认;tick 10ms |
| V1.7 | 2026-06-26 | vTaskDelay 10→50ms 修正(对齐原始 TMR15 5ms×10 设计);基线更新 1s→5s |
| V1.6 | 2026-06-24 | 时序修正:OUT_DELAY/PULSE_DELAY→500ms;RS485→TTL Tx |
| V1.5 | 2026-06-23 | Origin 污染保护、USE_FLATNESS_EXIT 开关 |
| V1.4 | 2026-06-23 | 移植 CN200910309382 平坦性离开判定 |
| V1.3 | 2026-06-23 | 指示灯行为、稳定期、重连状态保持 |
| V1.2 | 2026-06-23 | <<6/>>6 精度浪费分析与改进 |
| V1.1 | 2026-06-23 | 精简重构,对齐 M1H/TLD-110 |
| V1.0 | 2026-06-22 | 参考分析文档 |