Files
story/firmware/echoear-platform-agent/README.md
T

212 lines
11 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.
<h1 align="center"><img src="https://iam.volccdn.com/obj/volcengine-public/pic/volcengine-icon.png"></h1>
<h1 align="center">ConversationalAI Embedded Kit 2.0 </h1>
## EchoEar 平台版固件
本目录是在火山官方 Embedded Kit 2.0 基础上适配的 ESP32-S3 EchoEar 固件。它使用低负载 WebSocket 方案,并将设备身份、动态注册和会话配置统一接入自有 SaaS。
安全边界:
- 固件和设备端都不包含火山 `Product Secret`;
- SaaS 使用平台设备身份为 EchoEar 动态申请火山 `Device Secret`;
- EchoEar 只保存自己的平台设备凭据和火山单设备凭据;
- 每次对话前由 SaaS 下发 Bot、人设、绑定用户的非密钥 Viking 查询范围和会话配置;
- 字幕和最终轮次回传 SaaS,供会话记录与长期记忆处理。
当前测试硬件:ESP32-S3 EchoEar,16 MB Flash、16 MB PSRAM,硬件标识由 STA MAC 生成(当前板为 `echoear-b43a451634a8`)。
每次申请对话前,先通过 `/device/v2/bootstrap` 上报实际固件版本并检查 `firmware_compatible`,再获取配置和创建会话。固件版本为 `1.2.1-echoear-companion.2`;本工程基于 Embedded Kit 2.0,硬件智能体 SDK 版本独立上报为 `2.0.0`。会话能力中的 `sdk_version` 不能用固件版本代替。动态 `session.update` 同时配置端到端语音、混合编排 LLM、长者自然陪聊约束,以及按当前绑定用户隔离的 Viking `MemoryConfig`;端到端语音凭据和 Viking API Key 均不进入固件。会话尚未创建时保持唤醒采集,不重复拆建音频管线。SPI 屏幕仅在 `on_color_trans_done` 后释放 GFX 帧缓冲,避免异步传输期间提前复用缓冲区。运行状态用眼睛动画表示,避免 80 MHz 下中文逐像素渲染长期占用 CPU:快速眨眼表示聆听,转圈表示思考,正常眼睛表示待机或回答。
本板构建使用 16 MB Flash,Flash 与八线 PSRAM 均为 80 MHz。通用默认配置、ESP32-S3 默认配置和当前 `sdkconfig` 必须一致;不要恢复上游的 32 MB Flash 或实验性 120 MHz PSRAM 参数。
唤醒词为“嗨,乐鑫”,启用 `CONFIG_SR_WN_WN9_HILEXIN`,使用 `DET_MODE_95` 高灵敏度检测,并将 AFE 线性增益设为 2.0。生成的 `build/srmodels/srmodels.bin` 必须包含 `wn9_hilexin` 模型(约291 KB),并烧录到 `model` 分区 `0x510000`;不能使用未选择任何模型时生成的4字节空文件。
EchoEar V1.2 的 ES7210 使用 TDM:I2S 按两路32位接收,AFE 按四路16位解释,布局为 `RMNM`(ch1/ch3 麦克风、ch0 回声参考、ch2 忽略)。不可改成两路16位 `MR`。诊断日志 `MIC_LEVEL` 仅记录各路幅度统计,不保存录音。PCM输出每帧60 ms、16 kHz、单声道16位,读取缓冲区为1920字节,避免截断半帧。唤醒事件在会话服务就绪后直接发布,不依赖已移除的 `CONFIG_LANGUAGE_WAKEUP_MODE`。
低负载 WebSocket 任务使用 12 KiB 栈;4 KiB 会在收到 `session.created` 后发生栈溢出并重启。握手期间暂停上传麦克风帧,待引擎进入 STARTED 后再发送。低负载接口返回的 PCM 按 24 kHz 单声道16位解码,再由播放管线转换到板载 16 kHz I2S。`session.created` 的 `job_id` 用作平台启动确认,确保后续字幕和结束事件在 ACTIVE 会话上提交。
联网、平台 HTTPS 激活和音频初始化在独立的 24 KiB 启动任务中执行,避免默认 4 KiB `main` 栈溢出导致循环重启;任务退出时释放栈,并记录启动阶段最小栈余量。平台激活成功后才启动音频采集。激活失败时保留设备配置、显示绑定或配置提示,并仅记录平台错误码,不输出响应正文或凭据。
STA 连接使用全信道扫描并按信号强度选择同名 AP,实时语音期间关闭 Wi-Fi 省电,避免多 AP 环境中误连弱信号节点造成 WebSocket 写入失败。
### Windows 编译与烧录
使用 ESP-IDF v5.5.1:
```powershell
. 'E:\Codex\toolchains\esp-idf-v5.5.1\export.ps1'
idf.py build
idf.py -p COM6 flash
idf.py -p COM6 monitor
```
首次烧录前建议完整备份 Flash。当前板原厂备份位于 `backups/b43a451634a8/factory-2026-09-03-16mb.bin`,恢复命令:
```powershell
esptool.py --chip esp32s3 --port COM6 write_flash 0x0 backups/b43a451634a8/factory-2026-09-03-16mb.bin
```
### 首次激活
首次启动、缺少平台设备凭据、保存的 Wi-Fi 连接失败或超时,以及手动请求重新配网时,都会进入配置热点,无需清空 NVS:
1. 连接 `VolcConvAI-XXXXXX`,热点密码与热点名相同;
2. 打开 `http://192.168.4.1`;
3. 填写 2.4 GHz Wi-Fi、平台 Device ID 和平台 Device Secret;
4. 重启后,设备通过 SaaS 完成火山动态注册并获取单设备运行凭据。
正常运行时短触圆屏任意位置可直接开始对话,作为唤醒词的可靠备用入口。屏幕底部区域持续按住3秒后设备重启并开启配置热点。该操作保留原来的 Wi-Fi 和设备身份,只记录重新配网请求;成功提交配网页后退出配网模式。触摸任务在联网和平台激活之前创建,因此激活失败时也可以请求重新配网。
如果尚未配置平台设备身份,固件不会尝试用 Product Secret 直接访问火山。
重新配网回归检查(需要烧录后实机验证):
- 已保存可用 Wi-Fi、但缺少平台凭据:启动后直接出现热点和配网地址。
- Wi-Fi 密码错误或 DHCP 超时:连接等待结束后进入热点,不能重启循环。
- 正常运行时:短触屏幕启动对话;按住屏幕底部区域3秒进入配置热点。
- 配网页提交错误 Wi-Fi 后可重试;只有取得 IP 地址后才保存配置并重启。
- 配网页成功提交后正常启动,手动配网请求清除,原平台身份不会因进入配网而被删除。
本地 `idf.py build` 仅验证编译、链接和分区大小,不代替热点可见性、触摸坐标及长按时长的实机验证。
配网页提交使用 JSON 与后台连接任务,`POST /submit` 受理后立即返回 202,页面通过 `GET /setup-status` 查询连接、保存成功或失败状态。连接失败可以重试;保存成功后等待15秒重启,再由启动流程执行平台激活。Wi-Fi 扫描改为手动触发,连接期间不扫描。更新固件后请刷新配网页,避免继续使用已经打开的旧表单。
配网页交互回归:`node --test tests/setup-portal.test.cjs`(模拟设备响应,覆盖失败重试、响应丢失、断联、成功提示和输入校验)。
## 快速开始
具体操作,请参考 [官网文档](https://www.volcengine.com/docs/6348/1806625)。
## 运行设备端(乐鑫)
以下操作以 macOS 操作系统为例。
### 环境与硬件要求
- 乐鑫 ESP32-S3-Korvo-2
- USB 数据线:两条 A 转 Micro-B 数据线,一条作为电源线,一条作为串口线。
- PC 设备:编译和烧录。支持 Windows、Linux 或者 macOS 操作系统。(本文操作以 macOS 为例)
### 配置乐鑫环境
详见[开发环境配置文档](https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/get-started/index.html)。
1. 安装 CMake 和 Ninja 编译工具。
```bash
brew install cmake ninja dfu-util
```
2. 将乐鑫 ADF 框架克隆到本地,并同步各子仓(submodule)代码。
> **注意**:Demo 中使用的 ADF 版本为 `eca11f20e56f9b5321b714da4305e123672d92a9`,对应 IDF 版本为 `v5.4`,请确保 ADF 版本与 IDF 版本匹配。
>
```bash
# 1. clone 乐鑫 ADF 框架
git clone https://github.com/espressif/esp-adf.git
# 2. 进入esp-adf目录
cd esp-adf
# 3. 切换到乐鑫 ADF 指定版本
git reset --hard eca11f20e56f9b5321b714da4305e123672d92a9
# 4. 同步各子仓代码
git submodule update --init --recursive
```
3. 安装乐鑫 esp32s3 开发环境相关依赖。
```bash
./install.sh esp32s3
```
成功安装所有依赖后,命令行会出现如下提示:
```bash
All done! You can now run:
. ./export.sh
```
> 如在上述任何步骤中遇到以下错误:
> `<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:xxx)`
> 可前往**访达->应用程序->Python** 文件夹,点击 `Install Certificates.command` 安装证书。更多信息,请参考 [安装 ESP-IDF 工具时出现的下载错误](https://github.com/espressif/esp-idf/issues/4775)。
>
4. 设置环境变量。
> **每次打开命令行窗口均需要运行该命令进行设置。**
>
```bash
. ./export.sh
```
### 下载并配置工程
1. 将实时对话式 AI 硬件示例工程克隆到 乐鑫 ADF examples 目录下。
1. 进入 esp-adf/examples 目录。
```bash
cd $ADF_PATH/examples
```
2. 克隆实时对话式 AI 硬件示例工程。
```bash
git clone https://github.com/volcengine/ConversationalAI-Embedded-Kit-2.0.git
```
2. 修复乐鑫按键问题
1. 进入 esp-adf 目录。
```bash
cd $ADF_PATH
```
2. 修复乐鑫按键问题。
```bash
git apply $ADF_PATH/examples/ConversationalAI-Embedded-Kit-2.0/low_load_first/espressif/0002-fix-esp-button.patch
```
### 编译固件
进入 `esp-adf/examples/ConversationalAI-Embedded-Kit-2.0/low_load_first/espressif` 目录下编译固件。
1. 进入 espressif 目录。
```bash
cd $ADF_PATH/examples/ConversationalAI-Embedded-Kit-2.0/low_load_first/espressif
```
2. 设置编译目标平台。
```bash
idf.py set-target esp32s3
```
3. 设置 实例ID、产品ID、产品秘钥、设备ID等参数。
```bash
idf.py menuconfig
```
进入 `Example Configuration` 菜单,在 `volcano instance id` 中填入你的实例ID,在 `volcano product key` 中填入你的产品Key,在 `volcano product secret` 中填入你的产品秘钥,在 `device name` 中填入你的设备ID, 在 `bot id` 中填入你的智能体ID,并保存。
4. 编译固件。
```bash
idf.py build
```
### 烧录并运行示例 Demo
1. 打开乐鑫开发板电源开关。
2. 烧录固件。
```bash
idf.py flash
```
3. 运行示例 Demo 并查看串口日志输出。
```bash
idf.py monitor
```
4. Wi-Fi 配网。
1. 手机找到名如 VolcConvAI-XXXXXX” 的 Wi-Fi 热点,密码同Wi-Fi名,连接上 Wi-Fi。
2. 打开浏览器,在地址栏输入 `http://192.168.4.1`,进入 Wi-Fi 配网页面。
3. 输入 Wi-Fi 名称和密码,点击提交。
> **注意**:如果需更换 Wi-Fi,请重启设备。如果设备重启后无法连接到之前保存的 Wi-Fi(例如超出了范围或旧网络已关闭),请等待 30s 进入配网模式,再重新执行上面 Wi-Fi 配网的 3 个步骤。
>