xiaozhi-esp32 玩转 ES8311 音频编解码器:5 步搭出能全双工说话的语音助手
xiaozhi-esp32 玩转 ES8311 音频编解码器:5 步搭出能全双工说话的语音助手
半夜想问桌上一块小音箱"明天天气怎么样",它边说边听,你插一句嘴它还能立刻接住——这种体验背后,在 xiaozhi-esp32 里负责"听得清、说得出"的,就是一颗叫 ES8311 的音频编解码芯片。xiaozhi-esp32 是基于 MCP 协议的开源 ESP32 语音聊天机器人项目,你只需要给它接上麦克风、喇叭和这颗芯片,剩下的采样、编码、回声消除、唤醒它都已经做好了。
核心价值速览:ES8311 在小智里干了什么
🎙️ 把 ES8311 理解成"ESP32 和人耳之间的翻译官":它内部同时有 ADC(模数转换)和 DAC(数模转换)。麦克风进来的模拟声音,由它转成数字 PCM 交给 ESP32;AI 说出的数字音频流,再由它还原成声音推给喇叭。一片芯片把"收"和"发"都包了,不需要再额外配 DAC、ADC 两颗料。
在 xiaozhi-esp32 的数据链路里,codec 的位置很关键:麦克风 → ES8311 → 音频输入任务 → Opus 编码 → 网络发往云端,反向再走一遍(流程详见 main/audio/README.md)。它配置的是双工模式,收发通道同时工作,配合项目里的 AEC 回声消除,才能实现"AI 说话时你打断它"的全双工对话。实现代码在 main/audio/codecs/es8311_audio_codec.cc,不长,值得读一遍。
对电池供电的小设备来说,它的账算得很划算:播放功耗约 14mW、录音约 12mW,工作电压 2.5V–3.6V,直接吃 ESP32 的 3.3V 供电,不用额外做电源转换;DAC 信噪比 95dB、ADC 91dB,语音识别的"底噪"足够低。
选型对比:ES8311 是否适合你的项目
| 关键指标 | ES8311 | 同类方案(普通 I2S DAC 芯片 / 分立方案) | 实际价值 |
|---|---|---|---|
| 控制接口 | I2S + I2C | 多为纯 I2S,需 GPIO 拨码 | I2C 配寄存器,控制逻辑简单,代码可复用 |
| 信噪比 | 95dB(DAC) / 91dB(ADC) | 85dB–90dB | 语音更干净,唤醒和 ASR 准确率更高 |
| 功耗 | 约14mW播放 / 12mW录音 | 20mW–30mW | 电池设备续航更长 |
| 工作电压 | 2.5V–3.6V | 3.3V–5V 居多 | 与 ESP32 3.3V 系统直连 |
| 封装 | QFN24 (4×4mm) | SSOP28 (6.4×10.1mm) | PCB 面积省一半,适合小型化 |
一句话选型:只做 TTS 播放、不需要拾音,用便宜的 I2S DAC 就够;要做双向语音交互,ES8311 是性价比最均衡的选择;要远场麦克风阵列,那应该看 ES7210(xiaozhi-esp32 同样支持,见 main/boards/ 下各板卡实现)。
上手路径:5 步从零到第一次对话
第 1 步:备料。 ESP32-S3 开发板、ES8311 模块、8Ω 小喇叭、驻极体麦克风,加上面包板。接三类线:电源(VCC 接 3.3V、GND 共地)、I2C(SDA/SCL)、I2S(BCLK、WS、DIN、DOUT)。
第 2 步:拿到代码。
git clone https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32
第 3 步:定义引脚。 在你板子的 config.h 里把 I2S 引脚和 I2C 地址写死,采样率统一 24kHz:
#define AUDIO_INPUT_SAMPLE_RATE 24000
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_8
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_7
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_5
第 4 步:实例化 codec。 在板级初始化里构造 Es8311AudioCodec,构造函数会替你完成 I2S 双工通道创建、编解码器复位(写 0x00 寄存器 0x1F)、增益与音量配置:
Es8311AudioCodec codec(
i2c_bus, I2C_NUM_0, 24000, 24000,
mclk, bclk, ws, dout, din,
pa_pin, 0x18); // 0x18 = ES8311 I2C 默认地址
如果用的是项目已适配的 138 个板卡之一,这一步可以跳过,直接选对应固件变体即可,自定义板卡完整流程见 docs/custom-board_zh.md。
第 5 步:编译烧录,开口说话。 idf.py set-target esp32s3 后 idf.py build flash monitor,看到日志里 "Es8311AudioCodec initialized" 就成功了一半,喊出唤醒词,听到它回答你,第一次闭环就跑通了。🔊
避坑清单:4 个最常见的翻车现场
-
现象:喇叭完全没声音。 原因:I2C 地址对不上(模块上地址跳线不是 0x18),或 PA 功放使能引脚没拉起。解法:先用 I2C 扫描确认能读到 0x18;确认 PA 引脚方向,部分板卡需要传
pa_inverted = true(构造函数已支持)。 -
现象:声音像快进或磁带变速。 原因:I2S 侧和 ES8311 侧采样率不一致。注意构造函数里有硬性断言——输入输出采样率必须相等,且要和 I2S 时钟配置一致,全项目统一用 24000 最省心。
-
现象:麦克风要么太小声、要么全是环境底噪。 原因:输入增益设置不当,代码默认 30dB,偏高会放大环境噪声。解法:按实测环境微调
input_gain_,另外给 ES8311 电源引脚加 10µF + 0.1µF 滤波电容,音频电路对电源纹波很敏感。 -
现象:AI 说话时听不见人声,没法打断。 原因:没启用设备端回声消除。解法:在板卡
config.json的sdkconfig_append里加"CONFIG_USE_DEVICE_AEC=y",S3/P4 平台会自动走带 AEC 的 AFE 引擎。
进阶调优:3 条立竿见影的建议
- 保持 24kHz + Opus 流式传输。 24kHz 是识别准确率与系统资源的平衡点;Opus 编码让收发只传压缩流,带宽占用远小于裸 PCM,这也是小智支持 Realtime 端到端语音模型的基础。
- 让电源管理"该关就关"。
UpdateDeviceState()会随EnableInput/EnableOutput自动开关 codec 通道并拉低 PA 使能脚,闲置时芯片功耗直接归零。电池产品不用自己额外写开关机逻辑,保持这个策略即可。 - 动 DMA 缓冲前先懂它。 I2S 侧默认 6 个 DMA 描述符、每个 240 帧(见 main/audio/audio_codec.h),这个组合对延迟和稳定性做了折中;只有在出现特定平台的爆音时才考虑调整,盲目改反而引入新抖动。
写在最后
ES8311 就是 xiaozhi-esp32 里那颗"让设备开口又开耳"的芯片:I2C 配置简单、双工 + AEC 支撑全双工对话、功耗低到可以塞进口袋。建议你先照着第 1、5 步在面包板上跑通一次完整对话,再回来啃板级代码——动手一轮,比读十遍文档都值。
更多推荐





所有评论(0)