feat(iot_mqtt): loop_data 上报调度升级三档 — car_state 沿立即上报
原双速率下进/出车沿最坏等 300ms 门控。改为三档: - 立即档: 任一通道 car_state 翻转沿 → 直通间隔门控立即发布 - 快速档: |variation|>阈值 → 300ms (不变) - 空闲档: 配置 interval, 默认 60s (不变) 要点: - car_edge 优先级最高; 快照仍在门控后刷新, 同沿只触发一次立即档 - 防洪泛天然有界: Loop 事件帧最快 150ms/帧 且 car_state 为防抖后状态 - 协议 §5.2 补上报节奏说明; tests/test_report_cadence.c 8 组全过
This commit is contained in:
@@ -572,11 +572,14 @@ static void iot_process_recv(void) {
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
* 传感器数据上报 (双速率: 空闲态按 interval 上报, 变化态 300ms 快速上报)
|
||||
* 传感器数据上报 (三档调度)
|
||||
* 立即档: car_state 翻转沿 → 直通门控立即上报 (进/出车不等间隔)
|
||||
* 快速档: |variation| > 阈值 → 300ms
|
||||
* 空闲档: 按配置 interval (默认 60s, 最小 1s)
|
||||
*
|
||||
* Step 1 — 消费 Loop MCU 新帧 → 更新缓存
|
||||
* Step 2 — 对所有通道检测 variation, 决定上报间隔
|
||||
* Step 3 — 间隔门控: 时间到了才从缓存发布
|
||||
* Step 1 — 消费 Loop MCU 新帧 → 事件沿检测 + 更新缓存
|
||||
* Step 2 — 判定上报档位 (car_edge / fast_mode / idle)
|
||||
* Step 3 — 间隔门控 (car_edge 直通)
|
||||
*===========================================================================*/
|
||||
void iot_mqtt_publish_sensor(void) {
|
||||
static uint8_t _last_car_state[4] = {0};
|
||||
@@ -611,31 +614,33 @@ void iot_mqtt_publish_sensor(void) {
|
||||
/* 尚无缓存数据 → 不发 */
|
||||
if (!_cached_sr_valid) return;
|
||||
|
||||
/*--- Step 2: 判断是否进入变化态 (任一通道 |variation|>=阈值, 或 car_state 翻转沿) ---*/
|
||||
/*--- Step 2: 判定上报档位 (三档) ---
|
||||
car_edge : 任一通道 car_state 翻转沿 → 【立即上报】直通间隔门控
|
||||
fast_mode : 任一通道 |variation|>阈值 → 300ms 快速档
|
||||
否则 : 空闲档, 按配置 interval (默认 60s, 最小 1s) */
|
||||
uint32_t interval_ms;
|
||||
uint8_t fast_mode = 0;
|
||||
uint8_t car_edge = 0;
|
||||
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < _cached_sr.coil_count; i++) {
|
||||
/* car_state 翻转沿(进车/出车)优先级最高, 命中即定档 */
|
||||
if (_last_car_state[i] != _cached_sr.coils[i].car_state) {
|
||||
car_edge = 1;
|
||||
break;
|
||||
}
|
||||
// variation 为有符号(V1.05): 正=车/裕量, 负=反向漂移, 两向显著变化都加速
|
||||
int32_t v = _cached_sr.coils[i].variation;
|
||||
int32_t av = (v >= 0) ? v : -v;
|
||||
if (av > IOT_MQTT_VARIATION_THRESHOLD) {
|
||||
fast_mode = 1;
|
||||
break;
|
||||
}
|
||||
/* car_state 翻转沿(进车/出车) 同样触发快速上报
|
||||
注: 能走到这里 fast_mode 必为 0 (置 1 即 break), 无需再判 */
|
||||
if (_last_car_state[i] != _cached_sr.coils[i].car_state) {
|
||||
fast_mode = 1;
|
||||
break;
|
||||
fast_mode = 1; /* 记录但不 break: 后续通道可能有沿(优先级更高) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fast_mode) {
|
||||
interval_ms = IOT_MQTT_FAST_INTERVAL_MS; // 300ms
|
||||
if (fast_mode || car_edge) {
|
||||
interval_ms = IOT_MQTT_FAST_INTERVAL_MS; // 300ms (car_edge 时门控被直通, 仅作记录)
|
||||
} else {
|
||||
/* 空闲态: 使用配置的 interval (秒→毫秒), 最小 1s */
|
||||
uint32_t cfg_ms = (uint32_t)g_report_cfg.interval * 1000;
|
||||
@@ -643,12 +648,15 @@ void iot_mqtt_publish_sensor(void) {
|
||||
? cfg_ms : IOT_MQTT_IDLE_INTERVAL_MIN_MS;
|
||||
}
|
||||
|
||||
/*--- Step 3: 间隔门控 ---*/
|
||||
/*--- Step 3: 间隔门控 (car_edge 直通: 进/出车立即上报, 不等间隔) ---
|
||||
防洪泛天然有界: Loop MCU 事件帧最快 150ms 一帧, 且发布后快照即同步,
|
||||
同一个沿不会重复触发立即档 */
|
||||
{
|
||||
uint32_t now = mstick();
|
||||
if (_last_publish_ms != 0
|
||||
if (!car_edge
|
||||
&& _last_publish_ms != 0
|
||||
&& (now - _last_publish_ms) < interval_ms) {
|
||||
return; // 未到间隔; _last_car_state 不刷新, 翻转沿保持"待发", 持续顶住 fast_mode
|
||||
return; // 未到间隔; _last_car_state 不刷新, 翻转沿保持"待发"
|
||||
}
|
||||
_last_publish_ms = now;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user