You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-NOW树状拓扑节点检测FSM状态切换异常问题求助

解决ESP-NOW FSM状态切换后不立即执行逻辑的问题

核心问题定位

你的FSM逻辑大概率是仅绑定在ESP-NOW数据接收回调函数中执行,导致状态切换后,若无新数据触发回调,主程序不会主动检查当前状态并执行对应逻辑。

具体修复方案

1. 重构FSM执行逻辑,移到主循环轮询

把状态判断和业务逻辑从回调中抽离,放在主循环里持续轮询。回调仅负责数据解析和状态切换触发,不处理核心业务:

// 全局状态枚举与变量
typedef enum {
    STATE_1,
    STATE_2
} fsm_state_t;
fsm_state_t current_state = STATE_1;

// ESP-NOW接收回调
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
    // 仅处理数据解析与状态切换条件判断
    if (/* 满足切换到STATE_2的条件 */) {
        current_state = STATE_2;
    }
    // 其他必要的数据预处理逻辑
}

// 主循环
void loop() {
    // 持续轮询当前状态并执行对应逻辑
    switch(current_state) {
        case STATE_1:
            // STATE_1的业务逻辑代码
            break;
        case STATE_2:
            // STATE_2的业务逻辑代码(状态切换后会立即执行)
            break;
        default:
            break;
    }
    // 可选:添加短延迟避免CPU占用过高
    vTaskDelay(pdMS_TO_TICKS(10));
}

2. 状态切换时主动触发目标状态逻辑

如果不想完全重构代码,可以在状态切换的代码块里,主动调用一次目标状态的逻辑函数:

// 状态切换触发处
if (/* 切换条件满足 */) {
    current_state = STATE_2;
    // 主动执行STATE_2的逻辑
    run_state_2_logic();
}

// 独立封装状态逻辑函数
void run_state_1_logic() {
    // STATE_1的业务逻辑
}

void run_state_2_logic() {
    // STATE_2的业务逻辑
}

3. 移除状态逻辑中的阻塞操作

检查你的状态逻辑是否包含阻塞式代码(比如长时间delay()、死循环),如果有,改用非阻塞实现(比如用millis()或vTaskDelay()实现定时),确保主循环能持续轮询状态。

额外注意事项

  • 确保current_state是全局变量或通过指针传递,保证回调和主循环访问的是同一个状态值
  • 若使用FreeRTOS,建议将FSM轮询放在独立任务中,避免与其他任务抢占资源

内容的提问来源于stack exchange,提问作者Varaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:30:00