注意

这是最新开发分支配套的文档,可能包含已发布版本中尚未提供的功能。如果您要查看特定版本的文档,请使用左侧的下拉菜单并选择所需要的版本。

小智语音助手例程讲解#

概述#

本例程在 CanMV K230 上实现「小智」语音助手客户端,通过 WebSocket 与云端小智服务通信,完成语音采集、上传、TTS 播放、界面状态显示,并支持人脸检测/注册唤醒与 MCP / IoT 设备控制能力。

例程路径:/sdcard/examples/26-xiaozhi/(源码对应仓库中的 resources/examples/26-xiaozhi)。

环境准备#

运行本例程前,请确认:

  • 硬件:CanMV K230 开发板、摄像头模组、板载麦克风与扬声器/耳机;默认对话按键为 GPIO21(低电平有效),状态灯为 GPIO52。可在 run.py 顶部修改 KEY_PIN / LED_PIN

  • 网络:开发板已通过 LAN 或 WLAN 接入互联网,可访问小智 OTA / WebSocket 服务(默认 api.tenclass.net)。

  • 存储:SD 卡中已包含本例程目录及相关资源(字体、表情图等)。

  • 配置:首次运行会生成 /data/xiaozhi.cfg(UUID、MAC、OTA/WS 地址等);也可按需修改其中的服务器地址。

运行方式#

首次激活#

第一次启动时需要先完成设备激活,否则无法正常连接小智服务。

  • 在浏览器打开小智官网:https://xiaozhi.me/,按页面指引完成设备绑定/激活。

  • 激活码会在第一次启动时打印在串口 log 中,请注意查看,例如:

    收到激活码: xxxxxx
    设备需要激活,激活码: xxxxxx
    
  • 将 log 中的激活码填入官网对应位置完成激活。激活成功后,再次运行例程即可正常建连;后续启动一般无需重复激活。

启动#

在 CanMV IDE 中打开并运行:

/sdcard/examples/26-xiaozhi/run.py

若硬件按键 / LED 接线与默认不一致,请先修改 run.py 顶部参数后再运行:

KEY_PIN = 21   # 对话按键 GPIO(低电平有效)
LED_PIN = 52   # 状态指示灯 GPIO

也可在调用时传入:main(key_pin=21, led_pin=52)

程序会依次完成:UI / 摄像头初始化 → 设备初始化 → OTA 激活 → 连接小智 WebSocket 服务。

启动成功后,串口与界面状态会提示类似:

小智语音助手已启动,按Ctrl+C退出

界面状态最终会进入 「等待按键唤醒」

重要提醒:先等「等待按键唤醒」,再按键对话#

请务必先等到界面/状态显示「等待按键唤醒」之后,再按下按键开始对话。 若在网络连接、设备激活或会话建立完成前就按键,可能出现「网络连接中,请稍后」等提示,此时需等待连接完成后再试。

推荐交互流程:

  • 等待状态变为 「等待按键唤醒」

  • 按下并按住 板载对话按键(GPIO21):开始录音,状态变为「等待您的指令」,LED(GPIO52)点亮。

  • 对着麦克风说话

  • 松开按键:结束录音并上传,等待云端回复;TTS 播放时状态为「说话中」。

  • 播放结束后再次回到 「等待按键唤醒」,可进行下一轮对话。

补充说明:

  • 本例程默认使用 手动按键 交互模式(按住说话、松开结束)。

  • 若已注册人脸,识别到已注册用户时,也可触发人脸唤醒(发送唤醒文本),无需按键。

  • 在 IDE 中停止脚本或 Ctrl+C 可退出;退出时会先停人脸检测与 WebSocket / 音频线程。

代码架构#

例程按职责拆分为多层,入口为 run.py

run.py                 # 启动入口:UI + Client 组装、主循环、退出清理
├── xiaozhiclient.py   # 业务中枢:激活、会话、按键/人脸唤醒、消息分发
├── websocket_client.py# WebSocket 收发(含 Opus 音频帧)
├── http_client.py     # OTA / 激活 HTTP 请求
├── audio_manager.py   # 录音 / Opus 编解码 / TTS 播放队列
├── config.py          # 配置加载、UUID/MAC、WS 地址与 hello
├── state.py           # 协议消息类型、会话状态、消息构建/解析
├── lvgl_ai.py         # LVGL UI + 摄像头 + 人脸检测线程
├── face_reg_rec.py    # 人脸识别 / 注册
└── iot/               # MCP / IoT 设备抽象
    ├── thing.py
    ├── thing_manager.py
    └── things/speaker.py   # 示例设备:扬声器音量控制

模块说明#

模块

作用

run.py

创建 XiaoZhi_UIXiaoZhiClient,注册回调,主循环中刷新 LVGL 与 UI 更新队列

xiaozhiclient.py

设备生命周期、按键录音、人脸唤醒、处理 hello / STT / TTS / LLM / IoT / MCP 消息

websocket_client.py

维护 WSS 连接、心跳、文本/二进制帧收发

audio_manager.py

AI/AO 采集播放,Opus 编码上传与解码播放(播放侧使用预缓冲队列减轻卡顿)

lvgl_ai.py

界面状态、表情、字幕;人脸检测叠加;跨线程 UI 更新通过队列在主循环 flush

iot/

将板端能力抽象为 Thing,上报 descriptors / states,执行云端下发的控制命令

数据流(简图)#

按键按下
  → AudioManager 录音 → Opus 编码
  → WebSocket 二进制上传
  → 云端 ASR / LLM / TTS
  → WebSocket 下发 Opus + 文本消息
  → AudioManager 播放 + UI 更新状态/字幕/表情

云端 IoT / MCP 控制
  → ThingManager.invoke(...)
  → 如 Speaker.setvolume 调节音量
  → 回传 states

启动流程(核心逻辑)#

xiaozhi_client = XiaoZhiClient.get_instance()
xiaozhi_gui = XiaoZhi_UI()
xiaozhi_gui.user_gui_init()

xiaozhi_client.init_device(audio_download_callback, tts_state_callback, ws_state_callback)
xiaozhi_client.active_device()
xiaozhi_client.connect_to_server()
xiaozhi_client.register_update_callback(text_callback, llm_callback, status_callback)
xiaozhi_client.start_key_trigle_thread()
xiaozhi_client.start_face_wakeup_thread()

while True:
    xiaozhi_gui.flush_ui_updates()
    time.sleep_ms(lv.task_handler())
    # ... 人脸结果同步、按需重连等

MCP 与 IoT 功能#

本例程在连接握手的 hello 消息中声明支持 MCP:

"features": {
    "mcp": True
}

对应实现要点:

  • 能力声明state.MessageBuilder.build_hello_message() 中设置 features.mcp = True,告知云端客户端支持 MCP 相关能力。

  • IoT 设备模型:通过 ThingManager 注册板端设备(当前示例为 Speaker),会话建立后上报 descriptors(设备与方法描述,如音量属性、setvolume 方法)以及 states(当前设备状态)。

  • 命令执行:收到 type: "iot" 消息后,由 ThingManager.invoke() 分发执行,例如:

    {
      "type": "iot",
      "commands": [
        {
          "name": "Speaker",
          "method": "setvolume",
          "parameters": { "volume": 50 }
        }
      ],
      "session_id": "..."
    }
    

    执行后若状态变化,会再次上报 states

  • MCP 消息通道:协议侧已支持 type: "mcp" 的解析与分发入口(_hanle_mcp_message),可在此基础上扩展 MCP 工具调用;当前示例以 IoT Thing(如扬声器音量)演示端侧可控能力。

扩展新设备时,可参考 iot/things/speaker.py

  • 继承 Thing,定义属性与方法;

  • ThingManager.initialize_iot_devices()add_thing(...) 注册。

界面与状态提示#

常见界面/状态文案含义如下:

状态文案

含义

网络连接中,请稍后。。。。

WebSocket 尚未就绪,请稍候再按键

等待按键唤醒

已就绪,可按住按键开始说话

等待您的指令

正在录音,请说话

获取指令结束

已松键,结束本轮录音

说话中 / 说话结束

TTS 播放开始 / 结束

网络已连接 / 网络连接中断

WebSocket 连接状态变化

注意事项#

  • 先等「等待按键唤醒」,再按键对话,避免在激活或建连过程中误触发录音。

  • 首次启动请先完成官网激活https://xiaozhi.me/),激活码见串口 log。

  • 需要稳定网络;首次激活依赖 OTA 接口,请确认防火墙/代理不会拦截 HTTPS / WSS。

  • 人脸检测与 TTS 播放会同时占用算力与内存,长时间运行请保证散热与电源稳定。

  • 从 IDE 停止脚本时可能出现 soft reboot 相关日志(如 Display unbind、ISP stop),属资源回收过程,一般不影响再次运行。

具体多媒体、网络相关接口可参考文档:audiodisplaysensorlvglnetworksocket

评论列表
条评论
登录