diff --git a/docs/devlog.md b/docs/devlog.md index 45e0bb5..1f06897 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -4,6 +4,45 @@ --- +## 2026-09-03 — 重连判稳门控(固件 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)→ 判稳门控: +1. **值稳定检测**:200ms 步进 |ΔCAPVD| ≤ dlt/2 → 连续 3 步(600ms) 无漂移 +2. **回带确认**:|CAPVD-Origin| ≤ dlt(空场语义;浅车/蠕变尾 dev 超带不完成) +3. 通过 → **Origin 对齐当前空场** + CAPVD_slow 同步 + dlt 重算 → 放行 + (消除"新空场≠旧 Origin"基线差——根治窗末假车) +4. 不稳期间:进入判定挂起 + **黄灯快闪保持**(用户要求) +5. **强车例外**:CAPVD < Origin-8×dlt(真车深压)→ 不等判稳立即放行 +6. **5s 兜底**:超时强制放行(dev 深由正常进入判定接管,避免永久无输出) + +有车断开重连(VD_FLAG=1,保持路径输出中)不判稳:重连后走离开判定。 + +### 验证 + +- 语法 0 error;4 组单测全 PASS +- 宏:STABILIZE_STEP_TICKS 20 / STABILIZE_STEPS_OK 3 / STABILIZE_MAX_MS 5000 + +### 待板级验证 + +1. 21µH/46µH 无车拔插多次:不再出现窗末/窗后 Car_In 跳变; + 串口应见 `stab gate on` → (蠕变中可多次 `stab wait`)→ `stab done Origin->xxx` +2. 判稳期黄灯快闪、判稳完成后黄灯灭 +3. 判稳期真车压上:`stab bypass strong_car` → 立即 Car_In +4. 有车断开重连行为不变(保持输出→离开释放) +5. 136µH 高Q 正常重连:判稳快通过(~1s 内),无感 + ## 2026-09-03 — 重连确认窗漏网路径修复(固件 V4.36.14) > **固件版本:V4.36.14**(cmcng.h:FIRMWARE_VER="4.36.14",REV=14)。devlog 修订 V2.48。 @@ -1784,6 +1823,7 @@ if (dev >= dlt_ORG × 4) { | 版本 | 时间 | 说明 | |------|------|------| +| V2.49 | 2026-09-03 | V4.36.15 重连判稳门控: 值稳定(600ms无漂移)+回带才放行, Origin 自动对齐, 强车8×dlt例外, 5s兜底 | | V2.48 | 2026-09-03 | V4.36.14 重连确认窗漏网路径修复: 主循环拍级上升沿检测替代 ISR LOOP_OK0 | | V2.47 | 2026-09-03 | V4.36.13 一长一短 灭 100→300ms (dur 180/60/20/140, 周期2.0s) | | V2.46 | 2026-09-03 | V4.36.12 一长一短长亮 300→900ms (dur 180/20/20/140, 周期1.8s) | diff --git a/docs/product-manual.md b/docs/product-manual.md index 1425325..68d6205 100644 --- a/docs/product-manual.md +++ b/docs/product-manual.md @@ -178,7 +178,7 @@ DLD154V4B 是一款基于 ARM Cortex-M4 微控制器的**单通道环形线圈 | 故障类型 | 红灯 | 绿灯 | 黄灯 | 说明 | |---------|------|------|------|------| -| 线圈断开(当前) | 呼吸 | 灭 | **快闪** (200ms) | 检查线圈连接。**断开前有车:继电器保持 RELAY_HOLD_MS=500ms 后仍断才释放**(防瞬时断开误释放,宏可调) | +| 线圈断开(当前) | 呼吸 | 灭 | **快闪** (200ms) | 检查线圈连接。**断开前有车:继电器保持 RELAY_HOLD_MS=1000ms 后仍断才释放**(防瞬时断开误释放,宏可调)。**重连后无车判稳门控**:值稳定(600ms 无漂移)且回带内才放行检测,判稳期黄灯保持快闪,Origin 自动对齐新空场 | | 线圈电感量不合理(V4.26/V4.36.13) | 呼吸 | 灭(无车) | **一长一短** (900ms亮/300ms灭/100ms亮/700ms灭 循环) | 空场频率出 20~125kHz(默认低频档):L偏大(f<20k)/L偏小(f>125k),检查线圈匝数/尺寸 | | 线圈重连,断开 1 次 | 呼吸 | 正常 | **1 短闪** + 1.2s 灭 | 发生过 1 次断开,已恢复 | | 线圈重连,断开 2 次 | 呼吸 | 正常 | **2 短闪** + 1.2s 灭 | 发生过 2 次断开,已恢复 | diff --git a/docs/technical-spec.md b/docs/technical-spec.md index fabe3e6..a13b552 100644 --- a/docs/technical-spec.md +++ b/docs/technical-spec.md @@ -1,6 +1,6 @@ # DLD154V4B 技术规格书 -> 单路线圈车辆检测器 | 固件版本: V4.36.14 | 文档版本: V2.30 +> 单路线圈车辆检测器 | 固件版本: V4.36.15 | 文档版本: V2.31 > 本文档面向工程开发、系统集成及故障深度分析 --- @@ -796,3 +796,4 @@ DLD154V4B V1.4 起实现该专利的整数化版本,用于大车通行时的 | V2.28 | 2026-09-03 | **V4.36.12 黄灯一长一短 长亮 300→900ms**:dur {60,20,20,140}→{180,20,20,140}(总周期 1.8s),灭100/短亮100/灭700 不变 | | V2.29 | 2026-09-03 | **V4.36.13 一长一短 灭 100→300ms**:dur {180,20,20,140}→{180,60,20,140}=900/300/100/700ms(总周期 2.0s) | | V2.30 | 2026-09-03 | **V4.36.14 重连确认窗漏网路径修复**:主循环拍级自身上升沿检测(g_prev_ok)替代 ISR LOOP_OK0——插头抖动致 LOOP_OK0 卡 1 时恢复不再漏触发确认窗(现场 21µH 无窗直接 Car_In 复现);LO 抑制窗仍 1500ms(用户临时 3000 未入库) | +| V2.31 | 2026-09-03 | **V4.36.15 重连判稳门控**:无车断开重连后值稳定才放行动作——200ms 步进漂移≤dlt/2 连续 600ms + dev 回带(≤dlt) → Origin 对齐当前空场(消新旧基线差);不稳黄灯续闪;强车 8×dlt 例外即时放行;5s 兜底。低Q 窗末假车(21µH 蠕变 ~2.2s > 固定窗)根治 | diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index d5102d6..eaf3d82 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -43,6 +43,11 @@ // 历史: V4.05 曾用 ReleaseTable_B 加深释放表(实验失败, 方向反) // V4.06 改为 SENS=3 进入21→25+释放14→12, 等比推全档 #define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰) +/* V4.36.15: 重连判稳门控 (无车断开重连: 值稳定才放行, 不稳黄灯续闪) */ +#define STABILIZE_STEP_TICKS 20 // 判稳步进: 20 样本≈200ms +#define STABILIZE_STEPS_OK 3 // 连续 3 步(600ms)漂移≤dlt/2 → 无漂移 +#define STABILIZE_MAX_MS 5000 // 判稳兜底: 超时强制放行(避免永久无输出) + /* V4.36.8: 进入/释放确认样本数 — 按线圈 Q 档 (Q∝1/f 代理, 低Q抖动大需更多样本防误判) */ #define ENTRY_CONFIRM 3 // 进入确认基准(高Q): 连续 N 次低于阈值才判定有车 #define ENTRY_CONFIRM_HI 3 // 高Q(f<=80k) 进入确认样本 diff --git a/utilities/at32f421_freertos_demo/inc/cmcng.h b/utilities/at32f421_freertos_demo/inc/cmcng.h index aefd025..bdd0920 100644 --- a/utilities/at32f421_freertos_demo/inc/cmcng.h +++ b/utilities/at32f421_freertos_demo/inc/cmcng.h @@ -14,11 +14,11 @@ #define __CMCNG_H__ #define PRODUCT_MODEL "DLD154" -#define FIRMWARE_VER "4.36.14" // ..޶ (2026-09-03 : СĶֻ REV; MAIN/SUB ɲƷ) +#define FIRMWARE_VER "4.36.15" // ..޶ (2026-09-03 : СĶֻ REV; MAIN/SUB ɲƷ) #define HARDWARE_VER "3.00" #define FIRMWARE_VER_MAIN 4 #define FIRMWARE_VER_SUB 36 -#define FIRMWARE_VER_REV 14 +#define FIRMWARE_VER_REV 15 #define HARDWARE_VER_MAIN 3 #define HARDWARE_VER_SUB 0 diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index 1f5f6ef..0841709 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -162,6 +162,11 @@ uint8_t g_relay_hold_done = 0; // V4.36.3: 本次有车断开已兜底 uint16_t g_reconn_blank_ms = 0; // V4.36.5: 重连起振抑制倒计时(ms, 按Q分档, vd1_task 每样本-10) uint8_t g_entry_need = 3; // V4.36.8: 进入确认样本数 (按Q档, 高3/中4/低5) uint8_t g_prev_ok = 0; // V4.36.14: loop_task 主循环拍级上一拍 LOOP_OK (自身上升沿检测) +uint8_t g_reconn_stab = 0; // V4.36.15: 重连判稳门控(无车重连: 值稳定才放行) +uint16_t g_stab_ms = 0; // V4.36.15: 判稳已耗时(兜底 5s) +uint8_t g_stab_step_tick = 0; // V4.36.15: 200ms 步进计数 +uint8_t g_stab_ok_cnt = 0; // V4.36.15: 连续无漂移步数 +uint32_t g_stab_base = 0; // V4.36.15: 步进比较基准 CAPVD uint8_t g_release_need = 3; // V4.36.8: 释放确认样本数 (按Q档, 高3/中4/低5) uint8_t g_fault_phase = 0; uint16_t g_fault_tick = 0; @@ -353,7 +358,7 @@ void poll_yellow_led(void) g_fault_tick++; /*--- 模式1: 快闪 — 当前断开中 或 从无线圈上电 ---*/ - if (g_disconnect_active || !g_loop_power_up_state) { + if (g_disconnect_active || g_reconn_stab || !g_loop_power_up_state) { if (g_fault_tick >= FLT_FAST_HALF) { g_fault_tick = 0; LED_YELLOW_GPIO->odt ^= LED_YELLOW_PIN; // toggle @@ -466,6 +471,11 @@ void INIT_VD(void) loop1_RF_FLAG = 0; loop1_LOOP_OK = 1; loop1_LOOP_OK0 = 0; + g_reconn_stab = 0; /* V4.36.15: 判稳门控清零 */ + g_stab_ms = 0; + g_stab_step_tick = 0; + g_stab_ok_cnt = 0; + g_stab_base = 0; loop1_CAP_OK = 0; loop1_CAPVD = 0; loop1_CAPVD_slow = 0; // 方案A: 释放慢滤波复位 @@ -986,6 +996,64 @@ void vd1_task(void) /* V4.36.8: 进入/释放确认样本数按 Q 档更新 (每样本; Origin=0 时归高Q 3) */ update_q_confirm_need(); + /*--- V4.36.15: 重连判稳门控 (无车重连: 值稳定且回带才放行) --- + * blank 固定窗只挡"最脏起振期"; 低Q 起振蠕变(21µH 实测 ~2.2s)由本门控自适应接管: + * 200ms 步进检查 CAPVD 漂移 ≤ dlt/2 → 连续 3 步(600ms)无漂移, + * 且 |CAPVD-Origin| ≤ dlt(回带内=空场确认) → 判稳完成 → Origin 对齐当前空场 + * (消除"新空场≠旧 Origin"基线差, 根治窗末假车; 浅车/蠕变尾 dev 超带时不完成) + * 强车例外: CAPVD < Origin-8×dlt(真车深压) → 不等判稳立即放行 + * 兜底 5s: 超时强制放行(避免永久无输出; dev 深则进入判定正常接管) */ + if (g_reconn_stab) { + uint32_t _dlt = loop1_dlt_ORG; + if (_dlt < 8) _dlt = 8; + + if (g_stab_base == 0) + g_stab_base = loop1_CAPVD; + + if (loop1_CAPVD < (loop1_Origin - 8 * _dlt)) { + /* 强车例外: 真车深压不等判稳 */ + g_reconn_stab = 0; + PRINT("EVT|stab bypass strong_car dev:%d\n", + (int32_t)loop1_CAPVD - (int32_t)loop1_Origin); + } else { + g_stab_ms += 10; + g_stab_step_tick++; + if (g_stab_step_tick >= STABILIZE_STEP_TICKS) { + g_stab_step_tick = 0; + int32_t _drift = (int32_t)loop1_CAPVD - (int32_t)g_stab_base; + if (_drift < 0) _drift = -_drift; + if (_drift <= (int32_t)(_dlt / 2)) + g_stab_ok_cnt++; + else + g_stab_ok_cnt = 0; + g_stab_base = loop1_CAPVD; + + if (g_stab_ok_cnt >= STABILIZE_STEPS_OK) { + int32_t _d = (int32_t)loop1_CAPVD - (int32_t)loop1_Origin; + if (_d < 0) _d = -_d; + if (_d <= (int32_t)_dlt) { + /* 回带内=空场确认 → Origin 对齐当前空场(消基线差) */ + loop1_Origin = loop1_CAPVD; + loop1_CAPVD_slow = loop1_CAPVD; + loop1_dlt_ORG = ((uint32_t)loop1_Origin * + SensTable[loop1_SensLevel]) >> 16; + PRINT("EVT|stab done Origin->%d dev:%d\n", + loop1_Origin, _d); + } else { + /* dev 仍超带(浅车/蠕变尾): 继续抑制等回带 */ + PRINT("EVT|stab wait dev:%d drift:%d\n", _d, _drift); + g_stab_ok_cnt = 0; + } + } + } + /* 兜底 5s: 强制放行 (dev 深则进入判定正常接管) */ + if (g_stab_ms >= STABILIZE_MAX_MS) { + g_reconn_stab = 0; + PRINT("EVT|stab timeout %dms\n", g_stab_ms); + } + } + } + /*--- 2. 稳定期:绕过 IIR 和斜率限幅,小窗口快速收敛; * 基准值稳定(连续窗口 Origin 漂移达标)后才结束自检 ---*/ if (!g_loop_stable) { @@ -1170,7 +1238,7 @@ void vd1_task(void) coil_monitor(); /*--- 进入确认 — 连续 ENTRY_CONFIRM 次低于阈值才判有车 ---*/ - if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG) && g_reconn_blank_ms == 0) { + if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG) && g_reconn_blank_ms == 0 && !g_reconn_stab) { if (loop1_entry_cnt == 0) { /* 过渡事件: 第一次命中进入线 (定位"为什么开始进入") */ PRINT("EVT|enter_try Value:%d CAPVD:%d Origin:%d dlt:%d f:%dkHz LPCNT:%d Xn:%d\n", @@ -1385,6 +1453,18 @@ void loop_task_function(void *pvParameters) g_relay_hold_cnt = 0; // V4.36.3: 保持计时复位 g_relay_hold_done = 0; g_reconn_blank_ms = 0; // V4.36.5: 抑制倒计时(首样本直锁时按 Q 定档) + /* V4.36.15: 无车断开重连 → 判稳门控(值稳定才放行动作); + * 有车断开重连(VD_FLAG=1, 保持路径输出中)不判稳: 重连后走离开判定 */ + if (loop1_VD_FLAG == 0) { + g_reconn_stab = 1; + g_stab_ms = 0; + g_stab_step_tick = 0; + g_stab_ok_cnt = 0; + g_stab_base = 0; // 首样本直锁后置当前 CAPVD + PRINT("EVT|stab gate on (no-car reconnect)\n"); + } else { + g_reconn_stab = 0; + } env_resync_abort(); PRINT("EVT|loop_reconnect confirmed %dms\n", RECONNECT_CONFIRM_TICKS * 10);