Files
vd_960/vd960Loop/docs/devlog.md

132 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# vd960Loop 开发日志
> MCU: AT32F421 (Cortex-M4, 120MHz) | 线圈通道: 4路 | 调试口: TTL Tx (3.3V 9600 8N1)
---
## 2026-06-26 — 多项可配置化改造
### 1. 上报频率从 raw CAPVD 改为实际线圈频率
`uart_report_packet_loop_acs``CMD_DBN_GET_MCJQ_PARAM` 中,频率字段原来直接上报 `loop_CAPVD`IIR 累加值),现改为经过公式转换的实际频率:
```c
freq = (sclk_freq × input_div × LPCNT) / CAPVD
```
使用 `uint64_t` 先乘后除避免整数截断,`LPCNT>0 && CAPVD>0` 防除零。
### 2. 有限存在时长可配置 (hold_time)
- `Loop154_Unit` 新增 `uint16_t hold_time` 字段
- `storage.c``exist_mode` 计算: `hold_time = exist_mode × 20 × 5`tick 数,每 tick 50ms
- `vd1_task_per_channel` 判定有车时: 若 `hold_time > 0``loop_VD_HOLD = 1`,启用有限存在计时
- `TMR15_GLOBAL_IRQHandler`: `Hold_CNT > unit->hold_time` 替代固定 `HOLD_TIME`
- 超时后执行通道完整重启(`LC_Reset=1, loop_INI_LOOP=1`),相当于线圈重启重建基线,避免继电器释放后立即重新吸合
- `exist_mode=0` 时不启用有限存在,兼容无限制存在场景
### 3. 离开延时可配置 (relay_delay)
- `Loop154_Unit` 新增 `uint16_t relay_delay` 字段
- `storage.c``delay_time` 计算: `relay_delay = delay_time × 2`tick 数)
- `TMR15_GLOBAL_IRQHandler`: `OUTCNT > unit->relay_delay` 替代固定 `OUT_DELAY`
### 4. vTaskDelay 修正: 10ms → 50ms
`loop_task_function` 的主循环 `vTaskDelay``10ms` 改为 `50ms`,对齐 DLD154V4B 原始设计TMR15 5ms×10
**影响:**
- 基线更新周期: 100×10ms=1s → 100×50ms=5s对齐原始设计Origin 更稳定)
- CPU 占用: 主循环轮询频率降低 5×节省 CPU
**原因:** TMR3 ISR ~1ms 产出一个 CAP_OK 样本50ms 内有 ~50 个样本。`vd1_task_per_channel` 每个 tick 只取最新一个做 IIR10ms 轮询时 CAP_OK 总是 ready改为 50ms 不影响有效测量速率——采集由 TMR3 ISR 硬件驱动,基线更新速率受 `vd1_task` tick 限制。
---
## 2026-06-29 — DLD154V4B V2.0~V2.5 M4 优化移植
> 参考: DLD154V4B 单路 M4 优化版算法,移植到 vd960Loop 四路并联
### 1. 时序加速: vTaskDelay 50ms → 10ms
主循环 tick 从 50ms 提升到 **10ms**(加速 5×。TMR15 ISR 保持 5msTM1cnt 10 分频得到 50ms 中断,`Hold_CNT/OUTCNT/INCNT` 仍以 50ms 为单位。
**影响:**
- 检测响应更快:进入确认 3×10ms=30ms 即可判定
- 冻结超时 1000×10ms=10s
- WINDOW_ORIGIN=500 → 基线跟踪窗口 500×10ms=5s等效原 100×50ms
### 2. 斜率限幅 (Slope Limiter)
```c
MAX_SLOPE_RATE = 5% // 单次 IIR 输入变化不超过 CAPVD 的 5%
```
IIR 之前先对 `loop_Value` 做斜率限幅:与当前 `loop_CAPVD` 比较,变化幅度限制在 ±5% 以内(下限 100防止突发电磁干扰污染 IIR 状态。
### 3. 进入确认 (Entry Confirm)
```c
ENTRY_CONFIRM = 3 // 连续 3 次低于阈值才判定有车
```
替代原来的单次触发:`loop_CAPVD < (Origin - dlt_ORG)` 计数 `loop_entry_cnt++`,达到 3 次才置 `loop_VD_FLAG=1`。中途高于阈值则清零,消除偶发毛刺导致的误触发。
### 4. 基线冻结超时 (Freeze Timeout)
```c
FREEZE_TIMEOUT = 1000 // 10s @10ms/tick
FREEZE_STABILITY_RATE = 2 // 稳定性窗口 ±2%
```
有车期间基线被冻结(`ORG_CNT/ORG_SUM` 清零不更新),但新增超时机制:
- 冻结时记录参考值 `loop_freeze_ref`
- 若 CAPVD 波动超过 ±2%,重新计时(车还在动)
- 若 CAPVD 在 ±2% 内稳定超过 10s强制 `Origin = CAPVD`(视为长时间停车,基线应更新)
- 解决长时间停车导致基线永久偏离的问题
### 5. IIR 简化: 双路 → 单路
初始移植了双路 IIR慢速 α=18/256 + 快速 α=0.5),经测试发现快速 IIR 引入额外噪声,最终**去掉快速 IIR**,仅保留慢速:
```c
ALFA_CAP1 = 79 // α = 79/256 ≈ 0.31, @10ms → τ ≈ 32ms
```
斜率限幅直接对慢速 IIR 输入做限制,简化逻辑且效果一致。
### 6. 稳定期快速收敛
稳定期 `!loop_stable` 绕过 IIR + 斜率限幅:
- 直接用 `loop_CAPVD = loop_Value`raw value
- `update_moving_average` 窗口改为 **100**(小窗口快速收敛)
- 128 样本约 1.28s 完成初始化
稳定后切换回正常 IIR + WINDOW_ORIGIN=500 慢跟踪。
### 7. 参数修正
| 参数 | 旧值 | 新值 | 说明 |
|------|------|------|------|
| `WINDOW_ORIGIN` | 100 | 500 | 基线窗口 5s @10ms |
| `update_moving_average` window | `uint8_t` | `uint16_t` | 修复 500→256 溢出 |
| `loop_entry_cnt` | — | `uint8_t` | 新增: 进入确认计数器 |
| `loop_freeze_cnt` | — | `uint16_t` | 新增: 冻结持续计数 |
| `loop_freeze_ref` | — | `uint32_t` | 新增: 冻结参考值 |
---
## 修订记录
| 版本 | 时间 | 说明 |
|------|------|------|
| V2.5 | 2026-06-29 | 稳定期窗口 100 快速收敛 |
| V2.4 | 2026-06-29 | 去掉快速 IIRALFA_CAP1=79 @10ms |
| V2.3 | 2026-06-29 | 基线冻结超时 + 稳定性检查 |
| V2.2 | 2026-06-29 | 进入确认 ENTRY_CONFIRM=3 |
| V2.1 | 2026-06-29 | 斜率限幅 MAX_SLOPE_RATE=5% |
| V2.0 | 2026-06-29 | vTaskDelay 50→10ms, 双路 IIR 移植 |
| V1.3 | 2026-06-26 | vTaskDelay 10→50ms 对齐原始设计 |
| V1.2 | 2026-06-26 | hold_time/relay_delay 可配置,有限存在完整重启 |
| V1.1 | 2026-06-26 | 频率上报 CAPVD→实际频率转换 |