上篇我们把硬件接好了,喇叭会响、麦克风能被识别——但那都是"裸板 + 自己写的音频测试"。本篇要干一件真正关键的事:把"小智"这个AI对话固件烧进去,让你的盒子从"能录能放"变成"能聊天、能给孩子讲睡前故事"。

说实话,环境搭建和接线是"体力活",而烧录小智才是"临门一脚"。我这一周里,git clone 卡死、手动下 ZIP、menuconfig 选项挑花眼、烧进去发现引脚又白调、最后还被OTA自动升级反手覆盖——每一个坑都踩得结结实实。

本系列设计每篇聚焦一个难点,贴关键命令、与大家探讨一下原理、附实测结果,确保真实可复现验证。本文聚焦最深的两个坑:引脚被固件默认配置覆盖,以及OTA自动升级把你的自定义引脚一键打回原形。

目前来看,要"联网对话 + 云端大模型",小智固件是目前最省事的现成方案。

一、获取小智固件源码

小智官方仓库是 xiaozhi-esp32。理论上一条命令搞定:

git clone --recursive https://github.com/78/xiaozhi-esp32.git

但和第一篇的环境一样,我这里的网络又卡了——git clone 进度条不动,死活拉不下来。

破局方法:浏览器手动下 ZIP。

我直接去GitHub页面点了Download ZIP,拿到的是 Xiaozhi_Esp32S3_reSpeaker-main.zip。解压到本地后,剩下的步骤和普通 clone 下来的一模一样。--recursive 的子模块如果也卡,处理方式同第一篇(手动下 + 解压进目录)。

解压后记得先激活环境(接第一篇章的 get_idf 别名):

cd xiaozhi-esp32
get_idf                      # 激活 ESP-IDF 环境
idf.py set-target esp32s3    # 锁定芯片为 ESP32-S3

二、menuconfig:在板型里选对你的那一个

这是新手最容易懵的一步。执行:

idf.py menuconfig

小智的菜单在 Top -> Xiaozhi Assistant 下面,关键选项有:

选项我选的说明
Board Typebread-compact-wifi对应裸 I2S 麦克风 + 功放的最通用板型
Default LanguageChinese中文对话
Enable Wake Word Detection (AFE)[*] 勾选离线唤醒词,必须开
Enable Acoustic WiFi Provisioning[ ]声波配网,后面烧完再处理

注意:Board Type 列表巨长(几十种商业开发板)。我们的板子是纯 I2S 模块,选错板型编出来的固件会去驱动不存在的芯片,直接没声音甚至崩溃。认准"bread-compact-wifi"这种通用项。

三、编译与烧录

配置完直接编:

idf.py build

我这边编译产物大约 xiaozhi.bin 2.5MB,空间充裕。编译通过后烧录——注意串口设备名(接USB后 ls /dev/cu.* 看到的那个,我的是 /dev/cu.usbmodem1101):

idf.py -p /dev/cu.usbmodem1101 flash monitor

flash 烧固件,monitor 顺带打开串口看日志。烧完按一下 RST 复位,设备会自动开一个Wi-Fi热点(通常叫 Xiaozhi-XXXX)。掏出手机连上去,浏览器访问 192.168.4.1,填入你家的Wi-Fi账号密码,配网完成。
在这里插入图片描述

四、第一道坑:引脚又被"默认配置"覆盖了

烧进去、配完网、喊"你好小智"——结果麦克风没反应。

原因很隐晦:当前选择的板型,它自己有一套默认引脚表。所以即使第二篇我改好了测试固件的 board_config.h,小智这边用的还是它自己的 config.h,引脚又一次对不上。

解决办法:改小智源码里的 config.h。

路径通常在 main/boards/bread-compact-wifi/config.h。和你的物理接线对齐:

#define AUDIO_I2S_MIC_GPIO_WS   GPIO_NUM_4
#define AUDIO_I2S_MIC_GPIO_SCK  GPIO_NUM_5   
#define AUDIO_I2S_MIC_GPIO_DIN  GPIO_NUM_6
#define AUDIO_I2S_SPK_GPIO_DOUT GPIO_NUM_7
#define AUDIO_I2S_SPK_GPIO_BCLK GPIO_NUM_15
#define AUDIO_I2S_SPK_GPIO_LRCK GPIO_NUM_16

改完 idf.py build 重新烧录,麦克风就认了。

划重点:小智的引脚定义不在 board_config.h,而在它 boards/ 目录下的板型 config.h 里。两个文件都得改、且得改到同一组数字,这是最容易漏的一步。

五、最阴间的坑:OTA自动升级,把你的修改一键打回原形

你以为改完引脚就万事大吉?并没有。

小智固件开机时会自动检查新版本,如果有更新,就静默下载并覆盖整个固件——包括你刚改好的 config.h 引脚。如果没有注意引脚的设置,一次自动升级,全白调,麦克风又哑了。

源码里这个机制长这样(main/application.cc):

// 开机时检查新固件版本或获取 MQTT 服务器地址
Ota ota;
CheckNewVersion(ota);   // ← 这一行触发自动升级检查

而 CheckNewVersion() 内部,一旦发现 HasNewVersion(),就调用 ota.StartUpgrade() 把官方固件刷进去——你的自定义引脚就这么没了。

怎么锁死它?

关键认知:不能简单注释掉 CheckNewVersion(ota) 这一行,因为后面 ota.HasMqttConfig() / ota.HasWebsocketConfig() 还要靠这个 ota 对象去拿 xiaozhi.me 的服务器地址(连接云端大模型就靠它)。所以必须保留 ota 对象,只让"升级检查"不执行。

最干净的做法——在 CheckNewVersion 函数体第一行直接 return:

void Application::CheckNewVersion(Ota& ota) {
    return;   // 【修改】锁死 OTA 自动升级,保护自定义引脚不被覆盖
    // ... 下面原有的检查/升级逻辑全部跳过
}

或者更"显眼"地用 if (false) 把整个函数体包起来(方便日后想升级时一处改回)。这样:设备不再联网拉新固件,你的引脚修改永久生效;但云端连接所需的服务器地址仍由 ota 对象正常提供,不影响对话功能。

一句经验:凡是改了源码引脚/硬件绑定的,烧录前务必先锁OTA。不然每次开机自动升级,等于你永远在和官方默认配置打架。

六、绑定 xiaozhi.me,喊出第一声"你好小智"

固件烧好、引脚锁死、配网完成,接下来去 xiaozhi.me 控制台注册设备(设备会显示一个激活码,填进控制台即可绑定)。绑定后默认走官方免费 Qwen 实时模型,喊"你好小智"就能对话了。

不过我一开始发现一个有趣的现象——小智默认说话带台湾腔。

“为什么小智是台湾腔”

这是默认模型/音色的语言风格使然。在浏览器中修改成你偏好的就可以了。
在这里插入图片描述

七、硬件与软件配置清单(实测可复现)

项值
固件xiaozhi-esp32(手动下 ZIP,非 clone 拉取)
板型bread-compact-wifi
引脚(config.h 修改后)WS=4, SCK=8, DIN=6 / DOUT=7, BCLK=15, LRCK=16
OTA已锁死(CheckNewVersion 首行 return)
配网设备热点 + 192.168.4.1 填密码
云端xiaozhi.me 控制台绑定,默认 Qwen 模型
唤醒词你好小智

八、下一步

到这一步,一个能联网对话、给孩子讲睡前故事的实体AI盒子就真正跑通了。但有两个收尾值得写:

  1. 自托管服务器——自己部署 xiaozhi-esp32-server,接DeepSeek / Qwen,定制小智性格、音色、限制等,还顺手把"依赖官方服务器"的平台风险降为零。
  2. 成本复盘——算一笔账:裸板 + 麦 + 喇叭 + 辅料一共多少钱,对比市面 成品 AI 玩具,差距有多大。

如果你也在烧小智,欢迎在评论区留下你卡在的板型或引脚问题。动手是最好的学习方式,我们一起填坑。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐