feat(V4B): V4.36.5 — 重连起振抑制按 Q 分档

现象: 30/46/47/50µH 无车拔插重连继电器跳一下 (136/210µH 无)
根因: 低L→高f→低Q→起振慢幅度弱→前几窗 Xn 偏差→假有车
(100ms 确认窗只保载波存在, 不保幅度稳定)
改动: 首样本直锁时按空场频率 f 分档设抑制窗
  f>100k 低Q 400ms / 80~100k 中Q 200ms / ≤80k 高Q 0ms
  抑制期仅挂起进入确认累计(entry_cnt), 真车不丢, 其余逻辑照常
语法0 error, 4测试全绿; spec V2.21 / devlog V2.39
This commit is contained in:
wangfq
2026-09-04 10:06:51 +08:00
parent 55ac432c69
commit ca6b40cd2d
4 changed files with 89 additions and 4 deletions
+50
View File
@@ -4,6 +4,55 @@
--- ---
## 2026-09-03 — 重连起振抑制窗 按 Q 分档(固件 V4.36.5)
> **固件版本:V4.36.5**cmcng.hFIRMWARE_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.2210µ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 + 进入确认延时),道闸场景可接受
- 高 Q136/210µH)行为零变化
### 验证
- 语法 0 error4 组单测全 PASS(抑制在 vd1_task 进入判定,无单测耦合;待板级验证)
### 待板级验证
1. 30/46/47/50µH 无车拔插重连:继电器不再跳(EVT|reconn_blank 400ms 打印确认档位)
2. 136/210µH 拔插:无 reconn_blank 打印、无跳(高Q 0ms
3. 中档 60~90µH(如手头有):应打 reconn_blank 200ms
4. 抑制期真车压上:抑制结束正常判车(仅延迟 ~400ms)
## 2026-09-03 — 绿灯=继电器状态指示(固件 V4.36.4) ## 2026-09-03 — 绿灯=继电器状态指示(固件 V4.36.4)
> **固件版本:V4.36.4**cmcng.hFIRMWARE_VER="4.36.4"REV=4)。devlog 修订 V2.38。 > **固件版本:V4.36.4**cmcng.hFIRMWARE_VER="4.36.4"REV=4)。devlog 修订 V2.38。
@@ -1590,6 +1639,7 @@ if (dev >= dlt_ORG × 4) {
| 版本 | 时间 | 说明 | | 版本 | 时间 | 说明 |
|------|------|------| |------|------|------|
| V2.39 | 2026-09-03 | V4.36.5 重连起振抑制按Q分档(f>100k低Q 400ms/80~100k中Q 200ms/≤80k高Q 0ms), 进入确认挂起 |
| V2.38 | 2026-09-03 | V4.36.4 绿灯=RLY1 继电器实际输出状态(吸合亮/释放灭), 删断开强制灭分支; 自检期慢闪不变 | | V2.38 | 2026-09-03 | V4.36.4 绿灯=RLY1 继电器实际输出状态(吸合亮/释放灭), 删断开强制灭分支; 自检期慢闪不变 |
| V2.37 | 2026-09-03 | V4.36.3 有车断开继电器保持 RELAY_HOLD_MS=500ms(ISR计时/宏可调); 无车断开立即释放不变 | | V2.37 | 2026-09-03 | V4.36.3 有车断开继电器保持 RELAY_HOLD_MS=500ms(ISR计时/宏可调); 无车断开立即释放不变 |
| V2.36 | 2026-09-03 | V4.36.2 线圈重连确认窗 100ms(防抖动重复计数/首样本毛刺); 断开判定不加防抖 | | V2.36 | 2026-09-03 | V4.36.2 线圈重连确认窗 100ms(防抖动重复计数/首样本毛刺); 断开判定不加防抖 |
+2 -1
View File
@@ -1,6 +1,6 @@
# DLD154V4B 技术规格书 # DLD154V4B 技术规格书
> 单路线圈车辆检测器 | 固件版本: V4.36.4 | 文档版本: V2.20 > 单路线圈车辆检测器 | 固件版本: V4.36.5 | 文档版本: V2.21
> 本文档面向工程开发、系统集成及故障深度分析 > 本文档面向工程开发、系统集成及故障深度分析
--- ---
@@ -786,3 +786,4 @@ DLD154V4B V1.4 起实现该专利的整数化版本,用于大车通行时的
| V2.18 | 2026-09-03 | **V4.36.2 重连确认窗**:载波连续恢复 ~100ms 才确认重连重置(防接触抖动重复计数/首样本毛刺);断开判定不加防抖(释放速度安全刚需) | | V2.18 | 2026-09-03 | **V4.36.2 重连确认窗**:载波连续恢复 ~100ms 才确认重连重置(防接触抖动重复计数/首样本毛刺);断开判定不加防抖(释放速度安全刚需) |
| V2.19 | 2026-09-03 | **V4.36.3 有车断开继电器保持 RELAY_HOLD_MS=500ms**:断开前 VD_FLAG=1 → RLY 保持不释放;500ms 内重连+有车 → 无缝续持;重连+无车 → vd1_task 判离释放;超时仍断 → 强制释放(宏可调) | | V2.19 | 2026-09-03 | **V4.36.3 有车断开继电器保持 RELAY_HOLD_MS=500ms**:断开前 VD_FLAG=1 → RLY 保持不释放;500ms 内重连+有车 → 无缝续持;重连+无车 → vd1_task 判离释放;超时仍断 → 强制释放(宏可调) |
| V2.20 | 2026-09-03 | **V4.36.4 绿灯=继电器状态指示**:稳定后绿灯镜像 RLY1(PA6) 实际输出——吸合亮/释放灭;删除断开时绿灯强制灭分支(与保持逻辑一致,消除"拔线绿灯灭=误判继电器释放");自检/判稳期仍 200ms 慢闪 | | V2.20 | 2026-09-03 | **V4.36.4 绿灯=继电器状态指示**:稳定后绿灯镜像 RLY1(PA6) 实际输出——吸合亮/释放灭;删除断开时绿灯强制灭分支(与保持逻辑一致,消除"拔线绿灯灭=误判继电器释放");自检/判稳期仍 200ms 慢闪 |
| V2.21 | 2026-09-03 | **V4.36.5 重连起振抑制按 Q 分档**:低Q(高频小L 46~50µH)起振慢前几窗偏差大→假有车跳输出;按空场频率 f 分档抑制——f>100k 低Q 400ms / 80~100k 中Q 200ms / ≤80k 高Q 0ms136/210µH 实测无需);抑制期仅挂起进入确认累计 |
+2 -2
View File
@@ -14,11 +14,11 @@
#define __CMCNG_H__ #define __CMCNG_H__
#define PRODUCT_MODEL "DLD154" #define PRODUCT_MODEL "DLD154"
#define FIRMWARE_VER "4.36.4" // 主.子.修订 (2026-09-03 起: 小改动只增 REV; MAIN/SUB 由产品定) #define FIRMWARE_VER "4.36.5" // 主.子.修订 (2026-09-03 起: 小改动只增 REV; MAIN/SUB 由产品定)
#define HARDWARE_VER "3.00" #define HARDWARE_VER "3.00"
#define FIRMWARE_VER_MAIN 4 #define FIRMWARE_VER_MAIN 4
#define FIRMWARE_VER_SUB 36 #define FIRMWARE_VER_SUB 36
#define FIRMWARE_VER_REV 4 #define FIRMWARE_VER_REV 5
#define HARDWARE_VER_MAIN 3 #define HARDWARE_VER_MAIN 3
#define HARDWARE_VER_SUB 0 #define HARDWARE_VER_SUB 0
@@ -62,6 +62,16 @@ uint32_t loop1_freeze_ref;
* 超时仍断开才释放(防瞬时断开误释放/防砸); * 超时仍断开才释放(防瞬时断开误释放/防砸);
* 保持期内重连且有车 → 输出无缝续持 */ * 保持期内重连且有车 → 输出无缝续持 */
/* V4.36.5: 重连起振抑制窗 — 按线圈 Q 分档 (Q∝1/f, 用空场频率代理)
* 低Q(高频小L): 起振慢/幅度弱 → 前几窗测量偏差大 → 假"有车"跳输出
* 高Q(低频大L): 起振快样本干净 → 无需抑制 (136/210µH 实测无问题)
* 分界(实测): 46~50µH→109~113k 必跳 → >100k 归低Q; 80~100k 中Q; <=80k 高Q */
#define RECONNECT_Q_HI_F_KHZ 80 /* f <= 80kHz (L≳92µH@43nF) → 高Q */
#define RECONNECT_Q_MID_F_KHZ 100 /* 80< f <=100kHz → 中Q */
#define RECONNECT_BLANK_Q_HI_MS 0 /* 高Q: 起振快, 不抑制 */
#define RECONNECT_BLANK_Q_MID_MS 200 /* 中Q: 短抑制 */
#define RECONNECT_BLANK_Q_LO_MS 400 /* 低Q(f>100k, L<~59µH): 长抑制 */
/*=========================================================================== /*===========================================================================
* 全局状态变量 — 标志位 * 全局状态变量 — 标志位
*===========================================================================*/ *===========================================================================*/
@@ -149,6 +159,7 @@ uint8_t g_reconn_candidate = 0; // V4.36.2: 重连确认窗候选(载波
uint16_t g_reconn_cnt = 0; // V4.36.2: 载波连续恢复计数 (确认窗 ~100ms) uint16_t g_reconn_cnt = 0; // V4.36.2: 载波连续恢复计数 (确认窗 ~100ms)
uint16_t g_relay_hold_cnt = 0; // V4.36.3: 有车断开继电器保持计时(ms, ISR 5ms 累加) uint16_t g_relay_hold_cnt = 0; // V4.36.3: 有车断开继电器保持计时(ms, ISR 5ms 累加)
uint8_t g_relay_hold_done = 0; // V4.36.3: 本次有车断开已兜底释放(防重复OFF) uint8_t g_relay_hold_done = 0; // V4.36.3: 本次有车断开已兜底释放(防重复OFF)
uint16_t g_reconn_blank_ms = 0; // V4.36.5: 重连起振抑制倒计时(ms, 按Q分档, vd1_task 每样本-10)
uint8_t g_fault_phase = 0; uint8_t g_fault_phase = 0;
uint16_t g_fault_tick = 0; uint16_t g_fault_tick = 0;
uint8_t g_coil_fault = 0; // V4.26: 线圈电感量异常 0=正常 1=L偏大(f<20kHz) 2=L偏小(f>120kHz) uint8_t g_coil_fault = 0; // V4.26: 线圈电感量异常 0=正常 1=L偏大(f<20kHz) 2=L偏小(f>120kHz)
@@ -922,6 +933,22 @@ void vd1_task(void)
*================================================================*/ *================================================================*/
if (loop1_CAPVD == 0) { if (loop1_CAPVD == 0) {
loop1_CAPVD = loop1_Value; loop1_CAPVD = loop1_Value;
/* V4.36.5: 首样本直锁(重连重置后) → 按线圈 Q(空场频率)分档设定抑制窗
* Origin 为断开前空场基线(同线圈同环境) → f 即 Q 档;
* 上电(Origin=0)时 f=0 → 归高Q档 0ms, 不影响正常判稳流程 */
g_reconn_blank_ms = 0;
{
uint32_t _f = calc_freq_khz(loop1_Origin, loop1_LPCNT);
if (_f > RECONNECT_Q_MID_F_KHZ)
g_reconn_blank_ms = RECONNECT_BLANK_Q_LO_MS; /* 低Q(高频) 长抑制 */
else if (_f > RECONNECT_Q_HI_F_KHZ)
g_reconn_blank_ms = RECONNECT_BLANK_Q_MID_MS; /* 中Q 短抑制 */
/* 高Q(低频) → 0ms 不抑制 */
if (g_reconn_blank_ms)
PRINT("EVT|reconn_blank %dms f:%d kHz\n",
g_reconn_blank_ms, _f);
}
} else { } else {
int32_t raw_delta = (int32_t)loop1_Value - (int32_t)loop1_CAPVD; int32_t raw_delta = (int32_t)loop1_Value - (int32_t)loop1_CAPVD;
int32_t max_step = (int32_t)(loop1_CAPVD * MAX_SLOPE_RATE / 100); int32_t max_step = (int32_t)(loop1_CAPVD * MAX_SLOPE_RATE / 100);
@@ -941,6 +968,12 @@ void vd1_task(void)
} }
#endif #endif
/* V4.36.5: 重连起振抑制倒计时 (每样本 ~10ms) */
if (g_reconn_blank_ms) {
if (g_reconn_blank_ms > 10) g_reconn_blank_ms -= 10;
else g_reconn_blank_ms = 0;
}
/*--- 2. 稳定期:绕过 IIR 和斜率限幅,小窗口快速收敛; /*--- 2. 稳定期:绕过 IIR 和斜率限幅,小窗口快速收敛;
* 基准值稳定(连续窗口 Origin 漂移达标)后才结束自检 ---*/ * 基准值稳定(连续窗口 Origin 漂移达标)后才结束自检 ---*/
if (!g_loop_stable) { if (!g_loop_stable) {
@@ -1125,7 +1158,7 @@ void vd1_task(void)
coil_monitor(); coil_monitor();
/*--- 进入确认 — 连续 ENTRY_CONFIRM 次低于阈值才判有车 ---*/ /*--- 进入确认 — 连续 ENTRY_CONFIRM 次低于阈值才判有车 ---*/
if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG)) { if (loop1_CAPVD < (loop1_Origin - loop1_dlt_ORG) && g_reconn_blank_ms == 0) {
if (loop1_entry_cnt == 0) { if (loop1_entry_cnt == 0) {
/* 过渡事件: 第一次命中进入线 (定位"为什么开始进入") */ /* 过渡事件: 第一次命中进入线 (定位"为什么开始进入") */
PRINT("EVT|enter_try Value:%d CAPVD:%d Origin:%d dlt:%d f:%dkHz LPCNT:%d Xn:%d\n", PRINT("EVT|enter_try Value:%d CAPVD:%d Origin:%d dlt:%d f:%dkHz LPCNT:%d Xn:%d\n",
@@ -1313,6 +1346,7 @@ void loop_task_function(void *pvParameters)
g_env_wait_cnt = 0; // V4.24: 断开重连后环境学习状态复位 g_env_wait_cnt = 0; // V4.24: 断开重连后环境学习状态复位
g_relay_hold_cnt = 0; // V4.36.3: 保持计时复位 g_relay_hold_cnt = 0; // V4.36.3: 保持计时复位
g_relay_hold_done = 0; g_relay_hold_done = 0;
g_reconn_blank_ms = 0; // V4.36.5: 抑制倒计时(首样本直锁时按 Q 定档)
env_resync_abort(); env_resync_abort();
PRINT("EVT|loop_reconnect confirmed %dms\n", PRINT("EVT|loop_reconnect confirmed %dms\n",
RECONNECT_CONFIRM_TICKS * 10); RECONNECT_CONFIRM_TICKS * 10);