小智 AI 聊天机器人 xiaozhi-esp32 固件教程:让 ESP32-S3 机器人听懂话、会走路、能看路的完整指南
【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32
xiaozhi-esp32(小智 AI 聊天机器人)是一套跑在 ESP32 系列芯片上的语音助手固件:你说话,它用大模型回答,并通过 MCP 协议直接控制设备本身——音量、灯光、电机、摄像头翻转,全都能用一句"往前走"解决。它适合三类人:手里有一块 ESP32-S3 开发板想接大模型的玩家、想理解"语音 + 大模型 + 硬件控制"这条链路怎么打通的开发者,以及基于 ESP-SparkBot 这类带底盘、摄像头、屏幕的机器人硬件想快速落地的新手。全文以 ESP-SparkBot 为主例讲清从零上手到二次开发的路径。
5 分钟跑起来:ESP-SparkBot 固件构建与烧录最短路径
第一次上手不建议直接搭开发环境,官方提供了免开发环境的预编译固件(默认接入 xiaozhi.me 服务器,个人注册账号可免费使用实时语音模型)。想自己编译,最短路径如下:
- 安装 ESP-IDF。注意版本:项目当前要求ESP-IDF v6.0.1 及以上,推荐 v6.1,不再支持 5.x。Linux 上编译更快也更省心。
- 克隆源码:
git clone https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32 cd xiaozhi-esp32- 确认工具链并列出所有可编译的板卡(共 138 个板卡目录、171 个固件变体):
source /path/to/esp-idf/export.sh python3 scripts/build.py --list-boards- 编译 ESP-SparkBot 固件,脚本会帮你选对芯片目标、分区表和资产:
python3 scripts/build.py espressif/esp-sparkbot --name esp-sparkbot- 烧录并打开串口日志:
idf.py -p /dev/ttyUSB0 flash monitor看到设备连上 Wi-Fi、注册成功,说声唤醒词,机器人开始对话,这一步就算通了。项目采用 Google C++ 代码风格,后面要改代码的话先养成格式化习惯。
一次讲清核心机制:MCP 协议是怎么让大模型"遥控"机器人的
先解释名词:MCP(Model Context Protocol)可以理解为"给大模型发的遥控器说明书"——设备把自己的功能包装成一个个"工具"(Tool)上报给后台,大模型在对话中决定调用哪个工具,设备端执行。
整条链路是这样的:
你说话 → 离线唤醒 → Opus 编码 → WebSocket/MQTT 上传 → 后台 LLM 决策 → MCP tools/call 下发 → 设备执行(前进/开灯/翻转摄像头)→ 语音反馈关键在两点:
- 设备端注册工具。以 esp_sparkbot_board.cc 为例,底盘控制就是一段
AddTool注册:
mcp_server.AddTool("self.chassis.go_forward", "前进", PropertyList(), this -> ReturnValue { SendUartMessage("x0.0 y1.0"); // 通过 UART 发给底盘 return true; });- 调用走标准 JSON-RPC 2.0。后台发来的"前进"指令长这样,设备收到后在回调里执行真实硬件动作:
{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.chassis.go_forward", "arguments": {} }, "id": 2 }音频链路同样清晰:麦克风采集 16 kHz PCM → 离线唤醒词检测(基于 ESP-SR 的 WakeNet,支持自定义唤醒词)→ Opus 编码上传 → 云端 TTS 的 Opus 流解码回放进喇叭。有 AEC(回声消除,即设备"说话时也能听见你")的硬件还能做到实时全双工对话。更多细节可看 MCP 协议交互流程文档、MCP 用法说明、音频架构说明。
硬件构成:ESP-SparkBot 由哪些模块组成
ESP-SparkBot 由乐鑫官方推出,主体是 ESP32-S3,外设通过 I2C、SPI、I2S、UART、DVP 五类总线挂接。各模块与规格如下(引脚定义见 config.h):
| 模块 | 规格 | 总线与关键配置 |
|---|---|---|
| 主控 | ESP32-S3 | 双核 240MHz,配 PSRAM |
| 音频 | ES8311 编解码 + 喇叭 | I2S:MCLK 45 / BCLK 39 / WS 41 / DIN 40 / DOUT 42,16kHz 采样 |
| 显示 | 240×240 ST7789 SPI 屏 | CS 44 / DC 43 / SCK 21 / MOSI 47,背光 PWM 46 |
| 摄像头 | OV2640,240×240@25fps | DVP 8bit,XCLK 15 / PCLK 13,构建时启用CONFIG_CAMERA_OV2640 |
| 底盘 | 双电机,UART 协议控制 | UART1 @115200,TX 38 / RX 48 |
| 按键 | BOOT 键 | GPIO0,单击切换对话、启动时长按进配网 |
音频引脚片段示意:
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_45 #define AUDIO_I2S_GPIO_BCLK GPIO_NUM_39 #define AUDIO_I2S_GPIO_DIN GPIO_NUM_40 // ... 完整 5 脚映射见 config.h注意一个硬件细节:功放(PA)引脚和屏幕 IO 复用了,所以代码里EnableOutput(false)时是有意为空的,改引脚前先看 esp_sparkbot_board.cc 里的注释。
典型玩法:三个能直接照抄的场景
1. 语音遥控机器人。唤醒后直接说"往前走""转个圈""跳支舞"。对应工具self.chassis.go_forward、turn_left、dance等,"跳舞"还会同步把灯光切到演示模式:
mcp_server.AddTool("self.chassis.dance", "跳舞", PropertyList(), this -> ReturnValue { SendUartMessage("d1"); light_mode_ = LIGHT_MODE_MAX; return true; });2. 灯光表达情绪。设备内置 9 种灯光模式(充电呼吸、低电量告警、常亮、闪烁、快/慢呼吸、流光、演示、睡眠),大模型可通过self.chassis.switch_light_mode带参数调用:
mcp_server.AddTool("self.chassis.switch_light_mode", "打开灯光效果", PropertyList({Property("light_mode", kPropertyTypeInteger, 1, 6)}), this -> ToolResult { /* 拼 "wN" 命令发 UART */ });3. 摄像头当眼睛。说"把摄像头镜像翻转一下"即可切换画面方向(self.camera.set_camera_flipped),设置会写入 NVS 掉电保存;配合后台的视觉能力(MCPinitialize时上报 vision 地址),还能让模型直接"看"摄像头图像。
二次开发:给自己的机器人加一个 MCP 工具
加功能的最小路径就三步:在板卡代码里注册工具 → 写执行逻辑 → 重新烧录。以"带参数的 RGB 灯"为例(摘自 MCP 用法说明):
mcp_server.AddTool("self.light.set_rgb", "设置RGB颜色", PropertyList({ Property("r", kPropertyTypeInteger, 0, 255), Property("g", kPropertyTypeInteger, 0, 255), Property("b", kPropertyTypeInteger, 0, 255) }), this -> ReturnValue { SetLedColor(p["r"].value<int>(), p["g"].value<int>(), p["b"].value<int>()); return true; });工具命名建议用"模块.功能"风格(如self.dog.forward),description 写人话,大模型靠它做决策。如果你要适配的是全新硬件,需要按 自定义开发板指南 走完整链条:config.json→scripts/build.py→Kconfig.projbuild→CMakeLists.txt→ 板卡源码(必须恰好一个DECLARE_BOARD),且不要动现有板卡的引脚来迁就新硬件——板卡身份影响 OTA 兼容性,宁可新加一个变体。
踩坑实录:现象、原因与排查
现象:编译报版本不兼容 / 组件拉不下来。原因:项目已放弃 ESP-IDF 5.x,最低 v6.0.1。 排查:idf.py --version确认版本;旧 5.x 环境彻底换掉。
现象:切换板卡后编译失败或行为异常。原因:构建脚本会改写本地sdkconfig和构建状态,build 目录残留上一个目标。 排查:换一个板卡前先idf.py fullclean,再用python3 scripts/build.py <board> --name <variant>重新生成。
现象:说唤醒词没反应。排查顺序:先确认唤醒词音频资源存在(本地化缺失会回退英文,见 main/assets/locales/);再看 音频架构中的输入链路——AudioInputTask是否出数据、AFE 引擎是否初始化;最后检查麦克风 I2S 引脚是否与 config.h 一致。
现象:屏幕不亮或显示花屏。排查:检查 SPI 屏 4 根信号线 + 背光是否接对;确认bits_per_pixel = 16与invert_color配置和实际屏体一致(本板 ST7789 需要颜色反转)。
现象:摄像头画面左右/上下颠倒。原因:部分复刻版摄像头是固定安装的。 排查:说"翻转摄像头"即可切换,该设置已持久化;也可以改camera-flipped默认值。
现象:编译通过但烧录后没反应。排查:确认烧录分区表与固件匹配(partitions/ 下按容量分档);串口 monitor 无输出时优先查 TX/RX 是否反接、波特率是否为 115200。
性能调优:几个有实际收益的旋钮
| 优化项 | 做法 | 预期收益 |
|---|---|---|
| 唤醒词录音上传 | 项目已把最近 2 秒 PCM 放进 64KB PSRAM 环形缓冲,Opus 逐帧读取,不再临时拼接 | 避免内部 SRAM 抖动,减少丢帧 |
| 队列内存 | 音频队列用编译期固定容量存储,不再动态扩容 deque | 消除音频路径上的堆分配尖峰 |
| 摄像头帧缓冲 | 帧缓存走外部 PSRAM(CONFIG_CAMERA_OV2640_DVP_YUV422_240X240_25FPS) | 240×240@25fps 下省出大量内部 RAM |
| 音频功耗 | AudioPowerSaveTimer按活动启停 codec ADC/DAC 通道 | 空闲电流明显下降 |
| 睡眠策略 | 结合 sleep_timer.cc 与背光调节进入浅睡 | 桌面常驻场景续航更好 |
| 显示 | SPI 屏 PCLK 40MHz + 10 级传输队列 | 刷新不占满主循环 |
改音频路径时的通用纪律(来自 AGENTS.md):不在主事件循环和音频任务里阻塞、不养无界队列、回调里改状态要走Application::Schedule()。
参与贡献与学习路线
贡献方向按门槛从低到高:给冷门板卡补文档和图片;新增一块板卡(照 custom-board_zh.md 走五步链条);音频引擎和 AEC 调参(看 main/audio/);协议层改造(改动 main/protocols/ 时要同时验证 WebSocket 和 MQTT/UDP 两条通路)。社区入口是仓库 Issues 和官方 QQ 群(群号见 README_zh.md)。学习路线建议:先烧通预编译固件 → 读懂一块最简板卡(如 xmini c3)→ 再啃 ESP-SparkBot 的 I2C/SPI/UART 三总线初始化 → 最后按 音频架构文档 走一遍数据流。
项目以 MIT 许可证发布,固件默认接入官方服务器,也可自行部署第三方开源服务器对接同一套协议。小智把大模型从屏幕里拽到了桌面上,剩下的——你的机器人长什么样、会什么技能——由你定义。
【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考