开源 AI 语音助手 + 大模型与真实硬件的连接器:基于 ESP32 系列芯片,语音唤醒 → 全双工对话,通过 MCP 协议把大模型能力接到真实硬件(灯光/舵机/智能家居)。MIT 开源,138 个板卡目录、171 个固件变体,硬件门槛低到面包板手搓。
┌─ 硬件层 ──────────────────────────────┐
│ ESP32-S3 为主(C3/C5/C6/P4 也可) │
│ 音频 codec:ES8311/8374/8388/8389 │
│ 外设:LVGL 屏(10+驱动)、LED、摄像头、 │
│ BMI270、BQ27220 电量计、旋钮、USB │
├─ 系统层 ──────────────────────────────┤
│ Application 事件主循环 │
│ → DeviceStateMachine 状态机(12态) │
│ → protocols:WebSocket / MQTT+UDP │
│ → audio_service:采集/编解码/播放3任务 │
│ → 60+ managed 组件(esp-sr/lvgl...) │
├─ 云侧 ────────────────────────────────┤
│ xiaozhi.me 官方 or 自建服务器 │
│ ASR → LLM(Qwen免费) → TTS 实时流 │
└───────────────────────────────────────┘
12 个状态:Unknown → Starting → WifiConfiguring → Activating → Idle ⇄ Connecting → Listening ⇄ Speaking,另有 Notifying / Upgrading / AudioTesting / FatalError,所有迁移有严格校验表(防死锁)。
Device-Id(MAC) + Client-Id(UUID) 鉴权,自动查 OTA打断:播放中说唤醒词 → abort(wake_word_detected) → 清空队列 → 立即回听,全双工无感知切换。
🎤 MEMS麦克风 → PCM 48k → 重采样 16k → VAD/降噪
→ Opus编码(60ms/帧=960样本) → [v2头12B / v3头4B]+payload
→ WebSocket 二进制帧(或 MQTT信令 + UDP音频 AES-128-CTR 加密)
→ 云端 ASR → LLM → TTS
→ 下行 Opus(24k) → 解码 → 重采样 → DAC → 🔊 喇叭
| 消息类型 | 方向 | 用途 |
|---|---|---|
| hello / listen / abort | 上行 | 握手 / 开始停止监听 / 打断 |
| stt / llm / tts | 下行 | 识别文本 / 情绪表情 / 语音流+字幕 |
| mcp | 双向 | JSON-RPC 2.0 工具调用(控制硬件) |
| system / alert / notify | 下行 | 远程重启 / 告警 / 被动通知播报 |
可靠性:WS 靠 TCP keepalive;MQTT keepalive 240s + 120s 无数据判死 + 60s 自动重连;MQTT 音频通道 AES-128-CTR + 序列号防重放。
{"type":"llm","emotion":"happy"} → 设备 SetEmotion 立刻换表情,对话中显示思考中/说话中/开心等动态表情闭环:收音 → 屏显"正在听" → LLM 情绪 → 表情切换 → TTS 说话+字幕+LED 呼吸,全程可视化。
设备端运行 MCP Server,大模型通过对话直接调用:
| 工具 | 作用 |
|---|---|
| self.audio_speaker.set_volume | 调音量 |
| self.screen.set_brightness / set_theme | 屏幕亮度 / 主题 |
| self.camera.take_photo | 拍照 |
| self.screen.snapshot / preview_image | 截屏上传 / 屏显图片 |
| self.get_device_status / get_system_info | 查设备状态 / 系统信息 |
| self.reboot | 远程重启 |
| self.upgrade_firmware | 对话里直接命令设备升级固件 |
| self.assets.set_download_url | 更换资源包(表情/字体) |
| 板卡自定义工具 | 各家板子注册自己的(灯带 RGB、舵机、GPIO…) |
这就是"动口控制万物"的实现:AI 说"把灯调暗点",工具调用直接落硬件。
idf.py set-target esp32s3 && idf.py build(xiaozhi.bin 2.6M 实测编译通过 ✅)idf.py -p /dev/ttyUSB0 flash(16MB flash,80MHz)