Wi-Fi 与小智语音深挖
Wi-Fi 与小智语音深挖
为巽1. 责任边界
esp_xiaozhi 组件不负责扫描、配网或 Wi-Fi 重连。main/app_net/app_wifi.c 负责 Remote STA、扫描、连接、超时、重试和 profile NVS;main/ai_voice/app_ai_voice.c 负责 HTTP 获取配置、MCP、WebSocket、OPUS 音频;app_xiaozhi_controller.c 负责双击按键、页面确认和跨模块通知。
2. 手动联网流程
开机不启动 Wi-Fi。实体电源键 500 ms 窗口内双击,控制器保存返回页面并切到 Xiaozhi 页面;用户确认后才 app_wifi_request_scan()。扫描结果去重、按 RSSI 降序、最多 10 个,支持开放/WPA2/WPA3 混合认证。连接单次 20 s,最多 3 次,退避 2 s/4 s;认证失败直接失败。
只有 IP_EVENT_STA_GOT_IP 后才把 profile 写入 app_wifi NVS,最多保存 5 个最近网络。Wi-Fi event handler 不做网络操作,只投递 SCAN_DONE/GOT_IP/DISCONNECTED 命令给 app_wifi task。
3. Xiaozhi 状态机
1 | OFF -> WAITING_WIFI -> CONNECTING -> READY |
控制器在启动时只创建空闲 Wi-Fi/AI task。确认连接后,Wi-Fi 进入 CONNECTED,控制器调用 app_ai_voice_notify_wifi_ready() 和 app_ai_voice_set_enabled(true)。断 Wi-Fi 清除 audio/listening bits、停止 I2S/MAX98357A,并保留会话意图等待下一次 ready。
4. 为什么分段启动
GOT_IP 后不立即同时发 HTTPS、TLS、WebSocket 和音频。ai_voice 先等 1 s,调用 esp_xiaozhi_chat_get_info();再等 1 s 启动 chat;WebSocket connected 后再等 0.5 s 打开音频。每个窗口都检查 Wi-Fi 是否仍 ready,降低 ESP-Hosted SDIO 在瞬时 burst 下进入 unrecoverable state 的概率。
5. 组件调用链
1 | esp_xiaozhi_chat_get_info() |
当前没有离线唤醒词、ESP-SR 或 BLE Wi-Fi 配网命令。服务器若没有 WebSocket 配置,状态进入 ERROR,不猜测 MQTT 回退。
6. 断线恢复
收到 ESP_XIAOZHI_CHAT_EVENT_DISCONNECTED 后,应用层不等待 websocket 内部 5 s 自动重连,而是设置 restart bit。ai_voice task 调用 esp_xiaozhi_chat_deinit()、esp_mcp_destroy(),释放 transport,延迟 3 s 后从 info/chat 重新启动。停止时还要清空 OPUS 队列、停麦克风、拉低 MAX98357A SDMODE、释放 I2S0 TX channel。
7. Wi-Fi NVS 和安全
profile store 版本=1,结构包含 count、SSID、password、authmode,最多 5 条。连接成功才 commit,扫描和高频状态不写 Flash。Wi-Fi driver storage 设为 RAM,避免 SDK 自动持久化密码。当前 Xiaozhi credentials 由组件写入其 NVS namespace,工程没有把密码写入 UI 或 BLE payload。
8. 面试追问
为什么不在 Wi-Fi 回调里启动 Xiaozhi? 回调线程不应执行 HTTP/TLS/MCP,也无法处理重试和停止;事件只入队,业务 task 负责完整生命周期。
为什么手动联网而不是开机自动联网? 骑行 UI 的启动时延和 ESP-Hosted/SDIO 内部 DMA 余量更可控,同时避免用户未授权时扫描网络。
Wi-Fi 断了运动会停止吗? 不会。Wi-Fi/Xiaozhi 是可选业务;运动模型、BLE/GNSS 和 UI 继续运行,只有语音链路进入等待或错误。
1 |



