immortalbob/303ESP32S3-AI-ESPHome
GitHub: immortalbob/303ESP32S3-AI-ESPHome
这是一个为无文档Xiaozhi AI语音板提供ESPHome配置的项目,使其能集成到Home Assistant作为本地语音助手卫星。
Stars: 0 | Forks: 0
# 303ESP32S3-AI v2.3 ESPHome 配置文件
## 无文档的 Xiaozhi AI 语音板 —— 逆向工程
本仓库包含 **303ESP32S3-AI v2.3** 开发板的完整可运行的 ESPHome 配置文件。
该板在 eBay 和 AliExpress 上以 "Xiaozhi AI Voice Chat" 模块名义销售。此板无任何官方
英文文档、无原理图,也无 ESPHome 官方支持——所以我们自行制作了配置文件。

## 开发板识别
如果你拥有此板,你将在 PCB 上看到以下标记:
- `esp32s3-ai_v2.3`
- `303esp32ai2`
- `5437314r_p759_251206`
- FCC ID: `2bb77-esps3-32`
其他识别信息:
- 开发板尺寸:39x45.5mm
- 耀眼的绿色和蓝色 LED
- 原始固件 SKU:`bread-compact-wifi` (Xiaozhi AI v2.0.3, ESP-IDF v5.5)
该板出厂时运行中文版 Xiaozhi AI 固件。如果你的板在上电时会说中文,那你找对板子了。
## 硬件规格
| 组件 | 详情 |
|---|---|
| MCU | ESP32-S3-WROOM-1 N16R8 |
| 闪存 | 16MB |
| PSRAM | 8MB Octal (OPI) |
| 麦克风 | INMP441 I2S MEMS |
| 功放 | MAX98357A I2S Class-D |
| USB | CH340X(一键刷机,无需手动复位) |
| 电池 | TP5410 管理芯片,PH2.0 接口 |
| 扬声器 | PH2.0 接口(套件附带) |
| 按钮 | 5个(音量增,音量减,WiFi,BOOT,EN) |
| LED | 4个蓝色(TP5410 电池指示),2个红色,1个绿色 |
| PIR | 针脚已引出(GND, OUT, VCC)—— 兼容 HC-SR501 |
## 已确认的 GPIO 引脚分配
此引脚分配是通过以下方法组合确定的:
- 出厂 Xiaozhi 固件的启动日志分析
- 固件二进制提取和十六进制分析
- 对所有可用 GPIO 引脚进行 ADC 扫描
- 对所有可用 GPIO 引脚进行数字输入扫描
- 物理 PCB 走线检查
## | 功能 | GPIO | 备注 |
|---|---|---|
| INMP441 WS (麦克风时钟) | GPIO4 | I2S |
| INMP441 SCK (麦克风位时钟) | GPIO5 | I2S |
| INMP441 SD (麦克风数据) | GPIO6 | I2S |
| MAX98357A DIN (扬声器数据) | GPIO7 | I2S |
| MAX98357A BCLK (扬声器位时钟) | GPIO15 | I2S |
| MAX98357A LRC (扬声器字选择) | GPIO16 | I2S |
| PIR 传感器 OUT | GPIO8 | 兼容 HC-SR501,输入 |
| 音量减按钮 | GPIO39 | INPUT_PULLUP,反相 |
| 音量增按钮 | GPIO40 | INPUT_PULLUP,反相 |
| WiFi 按钮 | GPIO1 | INPUT_PULLUP,反相,可重新定义用途 |
| BOOT | 硬件引脚 | 刷机模式,非 GPIO 可控 |
| EN | 硬件引脚 | 复位引脚,非 GPIO 可控 |
| 2个红色 LED | 未知 | 经过彻底 GPIO 扫描后未找到 |
| 1个绿色 LED | 未知 | 经过彻底 GPIO 扫描后未找到 |
| 4个蓝色 LED | 不适用 | 由 TP5410 硬件控制,非 ESP32 控制 |
| 状态 LED (WS2812) | GPIO48 | 从源码确认——此变体上 **未焊接** |
| 触摸按钮 | GPIO47 | 从源码确认——此变体上 **未焊接** |
## 硬件说明
### 按钮
- **音量增 / 音量减** —— 在 HA 中作为二进制传感器暴露,可连接自动化程序用于音量控制或其他任何用途。
- **WiFi 按钮** —— 在原厂 Xiaozhi 固件中,此按钮用于触发 WiFi 配网。在 ESPHome 中,它完全可以通过 HA 自动化重新定义用途——你可以用它做任何事:静音、切换场景、切换在场状态等。
- **BOOT** —— 硬件刷机按钮,将 GPIO0 拉低进入刷机模式。固件中不可控。
- **EN** —— 硬件复位按钮。固件中不可控。
### PIR 传感器
PIR 针脚(GND, OUT, VCC)兼容 HC-SR501 及类似的 3.3V PIR 传感器。
OUT 引脚已确认在 **GPIO8** 上。HC-SR501 有两个调节电位器:
- **灵敏度** —— 如果可能,请在焊接前调节
- **延时** —— 最小约 3 秒,按需设置
启动后请等待 30-60 秒,让 HC-SR501 预热,之后才能可靠检测。
### 电池
TP5410 通过 PH2.0 接口支持外接 **3.7V 锂聚合物单节电池**。
常见的兼容电池包括带 PH2.0 导线的 18650 电芯,或容量在 500mAh-2000mAh 范围的扁平锂聚合物电池包。
**重要提示:** 连接前请务必注意极性——PCB 上已标记正负极。接反极性会损坏开发板。
TP5410 提供以下功能:
- 在连接电池时可通过 USB-C 充电
- USB 和电池供电之间自动切换
- 通过 4 个蓝色 LED 指示电池电量(每个 LED 代表 25%)
- 过充和过放保护
即使不连接电池,仅使用 USB 供电,开发板也能正常工作。
### LED (发光二极管)
**4 个蓝色 LED** 由 TP5410 电池管理 IC 直接驱动,指示充电水平。无法通过软件控制。唯一让它们安静的方法是物理方式(贴胶带、涂指甲油或拆焊)。
在对所有可用 ESP32-S3 GPIO 引脚作为输入和输出进行彻底扫描后,未找到控制 **2 个红色 LED 和 1 个绿色 LED** 的引脚。据信它们直接硬连接到电源轨,而非由 ESP32 控制。绿色 LED 似乎是一个简单的电源指示灯(USB 连接时始终亮起)。如果你找到了这些引脚,请提交 PR!
### 此变体不具备的硬件
- **无 OLED 显示屏** —— Xiaozhi 固件尝试初始化 SSD1306 显示屏但失败。存在带有显示屏的同系列 SKU。你的板子是不带显示屏的 "紧凑型" 变体。
- **无摄像头** —— 固件中存在摄像头支持,但此变体上无接口。
- **无状态 LED** —— 源码中 GPIO48 被定义为 `BUILTIN_LED_GPIO`(作为 WS2812 NeoPixel),但此变体上物理未安装。
- **无触摸按钮** —— 源码中 GPIO47 被定义为 `TOUCH_BUTTON_GPIO`,但此变体上物理未安装。
### PSRAM (伪静态随机存取存储器)
此板使用 **八线 PSRAM** (N16R8)。`psram: mode: octal` 设置是强制性的。使用错误模式将导致启动失败或不稳定。
### 刷机模式
在 `sdkconfig_options` 中需要设置 `CONFIG_ESPTOOLPY_FLASHMODE_QIO: "y"`。缺少此设置,开发板在长时间运行后可能出现细微的不稳定或启动问题。
## 前置条件
在刷写此配置之前,你需要一个已配置以下组件的正常运行的 Home Assistant 安装:
### 必需
- **Home Assistant OS** —— 在 Core 2026.5.2, OS 17.3, Frontend 20260429.4 上测试通过。
- **ESPHome Device Builder** —— 在 2026.5.0b1 (beta) 上测试通过。标准版本可能可用,但未使用此配置验证。
- **Faster-Whisper** —— 本地语音转文字引擎。通过 HA 附加组件商店安装。推荐模型:`large-v3-turbo` 以在基于 CPU 的服务器上获得最佳准确率。
- **openWakeWord** —— 仅当使用服务端唤醒词而非本地 `micro_wake_word` 时需要。通过 HA 附加组件商店安装。
- **一个已配置的语音助手管线** —— 设置 → 语音助手 → 添加助手。将 STT 设为 Faster-Whisper,TTS 设为喜欢的引擎。
### 文字转语音选项
任何兼容 HA 的 TTS 引擎均可使用。热门选择:
- **Piper** —— 完全本地,快速,质量尚可。通过 HA 附加组件商店安装。
- **Home Assistant Cloud (Nabu Casa)** —— 订阅制,最高质量的语音。
- **Edge TTS** —— 免费,Microsoft Azure 语音,需要互联网连接。
### 硬件
- 303ESP32S3-AI v2.3 开发板
- USB-C 线(需支持数据传输,非纯充电线)
- 5V USB 电源(质量很重要——廉价电源可能导致不稳定)
- 可选:用于运动检测的 HC-SR501 PIR 传感器
- 可选:用于无线操作的 3.7V 锂聚合物电池
## ESPHome 设置
### 首次刷机
由于此板使用 CH340X USB 芯片,刷机过程很简单:
1. 通过 USB-C 连接
2. 根据刷机方法,可能需要按住 BOOT 键
3. 使用 ESPHome 仪表板或 CLI 刷机
### 唤醒词配置
此配置使用 `micro_wake_word` 进行 **本地设备端唤醒词处理**。这意味着唤醒词检测完全在 ESP32-S3 自身完成,无需与 Home Assistant 往返通信。好处包括:
- 更低的延迟响应
- 使用多个卫星节点时无重复唤醒词冲突
- 即使 HA 短暂不可用也能工作
默认唤醒词是 **“Hey Jarvis”**。要更改它,请修改模型行:
```
micro_wake_word:
models:
- model: hey_jarvis # default
```
其他可用模型包括:
| 唤醒词 | 模型字符串 |
|---|---|
| Hey Jarvis | `hey_jarvis` |
| Okay Nabu | `okay_nabu` |
| Hey Mycroft | `hey_mycroft` |
| Alexa | `alexa` |
只需将 `hey_jarvis` 替换为你偏好的模型字符串并重新刷机即可。
### 云端/服务端唤醒词(替代方案)
如果你更喜欢使用运行在 Home Assistant 服务器上的 openWakeWord 而非本地处理,请替换 `micro_wake_word` 块并按如下方式更新 `voice_assistant`:
```
voice_assistant:
id: va
microphone: va_mic
speaker: va_speaker
noise_suppression_level: 0
auto_gain: 31dBFS
volume_multiplier: 4.0
use_wake_word: true
on_wake_word_detected:
- voice_assistant.start:
on_end:
- delay: 1s
- voice_assistant.start_continuous:
on_error:
- lambda: |-
if (code.size()) {
ESP_LOGD("va", "VA error: %s", code.c_str());
} else {
ESP_LOGD("va", "VA error: ");
}
- delay: 10s
- voice_assistant.start_continuous:
```
并完全移除 `micro_wake_word:` 块。
**注意:** 当使用服务端唤醒词并部署多个卫星节点时,如果所有设备同时听到相同的唤醒词,你可能会遇到 `duplicate_wake_up_detected` 错误。为每个房间使用不同的唤醒词或切换到本地处理可以解决此问题。
### 多房间部署
要部署到多个板子,只需为每个设备更改以下值:
- `name:`
- `friendly_name:`
- `api encryption key:` —— 为每个设备生成一个新的
其他所有内容,包括 GPIO 分配,在所有此型号的板子上都是相同的。
### 所需密钥
将这些添加到你的 ESPHome `secrets.yaml`:
```
wifi_ssid: "Your WiFi SSID"
wifi_password: "Your WiFi Password"
api_key: "Generate with ESPHome dashboard"
ap_password: "Your fallback AP password"
```
### 音量按钮自动化
音量增和音量减按钮在 HA 中作为二进制传感器暴露。
自动化示例:
```
automation:
- alias: "Voice Satellite Volume Up"
trigger:
- platform: state
entity_id: binary_sensor.master_bedroom_volume_up
to: "on"
action:
- service: number.set_value
target:
entity_id: number.master_bedroom_volume
data:
value: "{{ [states('number.master_bedroom_volume') | float + 10, 100] | min }}"
```
### WiFi 按钮自动化
WiFi 按钮完全可以重新定义用途。示例 —— 用它来切换场景:
```
automation:
- alias: "WiFi Button Toggle Scene"
trigger:
- platform: state
entity_id: binary_sensor.master_bedroom_wifi_button
to: "on"
action:
- service: scene.turn_on
target:
entity_id: scene.bedroom_night
```
### PIR 运动检测自动化
PIR 传感器在 HA 中作为运动二进制传感器暴露。示例 —— 检测到运动时开灯:
```
automation:
- alias: "PIR Motion Lights"
trigger:
- platform: state
entity_id: binary_sensor.master_bedroom_motion
to: "on"
action:
- service: light.turn_on
target:
entity_id: light.bedroom_lights
```
## 故障排除
### 开发板无法刷机
- 确保你的 USB-C 线支持数据传输(非纯充电线)
- CH340X 会自动处理刷机
- 如果仍然失败,尝试在刷机前按住 BOOT 键,然后在刷机开始后松开
### 开发板启动但无法连接到 HA
- 检查你的 `api encryption key` 是否与 HA 期望的一致
- 验证 `secrets.yaml` 中的 WiFi 凭据
- 查看 ESPHome 日志——连接问题会明确报告
### `stt-no-text-recognized` 错误
- 在唤醒词之后立即说出命令,不要停顿
- 尝试将 `volume_multiplier` 增加到 `6.0` 或更高
- 检查 HA 中的 Faster-Whisper 是否正在运行且健康
- 如果尚未使用 Faster-Whisper,请将 STT 引擎切换到它
- 在 Faster-Whisper 设置中,尝试将 beam size 设为 1 以获得更快的响应
### 唤醒词不触发
- 启动后等待 5-10 秒再说话
- 在 设置 → 设备与服务 → Wyoming → openWakeWord 中检查 openWakeWord 阈值
- 将阈值从 0.5 降低到 0.3 以提高灵敏度
- 如果麦克风拾音效果差,增加 `volume_multiplier`
### 长时间使用后开发板无响应
- 这是 ESPHome/HA 语音管线中的一个已知问题——此配置中的 `on_error` 重启逻辑可缓解此问题
- 检查 HA 日志中的 aioesphomeapi 错误
- 确保 HA 已更新到 2026.5.2 或更高版本,其中包含了 aioesphomeapi 修复
- 验证电源质量——`Power On` 复位原因表明电源不稳定
### 编译器内存不足/编译过程中崩溃
- micro_wake_word 模型会显著增加编译开销
- 在编译期间关闭 HA 主机上的其他应用程序
- 如果使用低内存系统,尝试先在不包含 `micro_wake_word` 的情况下编译,然后再添加
- 有时第二次编译尝试会在第一次失败后成功
### PSRAM 启动挂起
- 确保设置了 `psram: mode: octal` —— 这对 N16R8 是强制性的
- 确保 `CONFIG_ESPTOOLPY_FLASHMODE_QIO: "y"` 已包含在 sdkconfig_options 中
- 当使用 `psram:` 块时,**不要** 向 sdkconfig_options 添加 `CONFIG_SPIRAM_MODE_OCT`
—— 两者都设置会导致启动挂起
### 检测到重复唤醒词错误
- 当多个卫星节点同时听到相同的唤醒词时发生
- 解决方案:使用本地 `micro_wake_word`(此配置中的默认设置)而非服务端唤醒词——每个设备独立处理,消除冲突
## 我们是如何搞清楚的
这块板子完全没有英文文档。以下是 GPIO 引脚分配的逆向工程方法:
### 1. 开发板识别
通过上电并捕获串行启动日志来识别开发板,其中包含:
```I (232) Board: UUID=ee2f52e2-c6cf-4633-b1e0-a9fb258aea01 SKU=bread-compact-wifi```
此 SKU 与 Xiaozhi AI 开源固件仓库匹配。
### 2. 出厂固件分析
使用 [esptool-js](https://espressif.github.io/esptool-js/) 提取了完整的闪存备份,
并使用 PowerShell 字符串提取进行分析:
```
$bytes = [System.IO.File]::ReadAllBytes("C:\backup.bin")
[System.IO.File]::WriteAllText("C:\strings_out.txt", [System.Text.Encoding]::ASCII.GetString($bytes))
Select-String -Path "C:\strings_out.txt" -Pattern "gpio|i2s|audio|button|led" | Out-File "C:\results.txt"
```
这确认了 `NoAudioCodecSimplex` 驱动、用于按钮的 `AdcButton`、用于 LED 的 `SingleLed` 的使用,以及源文件路径 `./main/boards/bread-compact-wifi/compact_wifi_board.cc`。
### 3. 音频引脚确认
INMP441 和 MAX98357A 的 GPIO 分配与 Xiaozhi 固件源码进行了交叉引用,并通过 ESPHome 编译和测试得到确认。
### 4. 按钮发现
通过 ADC 扫描找到了按钮——为每个可用 GPIO 添加临时 ADC 传感器,并在按下每个按钮时监控电压变化:
- 当按下 WiFi 按钮时,GPIO1 降至 0V(已确认)
- 当按下音量减按钮时,GPIO39 状态改变(已确认)
- 当按下音量增按钮时,GPIO40 状态改变(已确认)
BOOT 和 EN 按钮是硬件引脚,无法通过 GPIO 访问。
### 5. PIR 引脚发现
通过在所有剩余未识别的 GPIO 引脚上添加数字二进制传感器输入,并连接 HC-SR501 PIR 传感器,找到了 PIR 针脚的 OUT 引脚。当 GPIO8 因运动检测而状态改变时得到确认。
### 6. LED 调查
对所有可用的 ESP32-S3 GPIO 引脚(GPIO1-21, GPIO38-42, GPIO48)作为数字输入和输出进行了彻底扫描。没有找到与 2 个红色或 1 个绿色 LED 对应的引脚。据信这些 LED 直接硬连接到电源轨,不受 ESP32 控制。
## 已知问题 / 待办事项
- [ ] 2个红色 LED GPIO 引脚未识别——据信硬连接到电源轨
- [ ] 1个绿色 LED GPIO 引脚未识别——据信硬连接为电源指示灯
- [ ] 音量按钮作为二进制传感器连接——实际音量控制需要 HA 自动化
- [ ] 蓝色电池 LED 无法通过软件禁用(TP5410 硬件控制)
## AI 辅助
本项目在 AI 语言模型的重大协助下进行了逆向工程。该过程涉及多个 AI 系统,各自贡献了不同的优势:
- **Claude (Anthropic)** —— 项目全过程的主要助手。主导了二进制固件分析、GPIO 扫描策略、ESPHome 配置开发,并在数天内进行了迭代调试。始终坚守在第一线。
- **DeepSeek** —— 在项目中期提供了一份详细的调查结果技术摘要,帮助整合了知识并识别出 `bread-compact-wifi` SKU 的重要性。
- **Copilot (Microsoft)** —— 对配置稳定性提供了第二意见。正确识别了 `on_error` lambda 日志记录修复,并建议添加了 WiFi RSSI 传感器。
人类的好奇心、毅力、烙铁与 AI 辅助的结合,将一块完全没有文档的 eBay 神秘板子变成了一份完全文档化、社区可用的 ESPHome 配置文件。
如果你正尝试对另一块无文档板子进行类似操作,这里可行的方法是:
1. 提取并分析出厂固件二进制文件
2. 捕获启动日志以识别 SKU/板子
3. 与开源固件仓库进行交叉引用
4. 系统化 GPIO 扫描——按钮用 ADC,PIR 用数字输入,LED 用输出
5. 迭代,迭代,再迭代
## 许可证
MIT —— 自由使用,欢迎注明出处但并非必须。
标签:ESP32-S3, ESP32开发板, ESPHome, GPIO配置, Home Assistant, I2S接口, I2S音频, INMP441麦克风, LED指示, MAX98357A放大器, WiFi通信, Xiaozhi AI, 云资产清单, 固件分析, 嵌入式开发, 嵌入式系统, 按钮控制, 无线语音控制, 智能家居, 物联网, 电池管理, 硬件开源, 硬件逆向工程, 语音助手, 语音卫星, 逆向工程