下面是头条推文版技术方案稿 ,已按你要求:不引用 TXT 文件内容 ,只结合前面几个 PDF 文件里的模组手册、AI 硬件选型表和 AI 开发宝典来写。重点强化了:5 米远场拾音、高噪声可用、唤醒词打断、实时打断、自定义唤醒词、蓝牙/Wi-Fi/4G 多联网、单屏/双屏/异显、ESP32-S3 二次开发、客户系统接入。
四博 AI 智能音箱方案:基于 ESP32-S3 打造远场拾音、多网络接入、可二次开发的 AI 语音终端
AI 音箱真正难的地方,不是"接一个大模型",而是把远场拾音、噪声抑制、实时打断、唤醒词管理、多网络接入、屏幕显示、客户系统对接和 OTA 量产升级全部打通。
李博士讲解的四博 AI 音箱方案,核心特点可以概括为:
拾音距离远:5 米以上仍可对话
高噪声可用:复杂噪声环境下仍能正常唤醒和识别
支持唤醒词打断:设备播放时可用唤醒词直接打断
支持实时打断:用户插话即可停止当前 TTS
支持自定义唤醒词:可按客户品牌修改唤醒词
联网方式多:蓝牙、Wi-Fi、4G 多种接入方式
显示能力强:可驱动单屏、双屏,也可左右屏异显
开发友好:基于 ESP32-S3,方便客户二次开发
系统开放:便于接入客户自有 App、IoT 平台和 AI 后端
从产品定位来看,四博 AI 音箱不是传统蓝牙音箱,而是一套面向 AIoT 量产落地的智能语音硬件平台。
它既可以作为 AI 智能音箱,也可以作为智能家居语音中控、AI 桌宠、儿童学习机、陪伴机器人、酒店客控入口、办公语音助手和客户自有系统的 AI 语音前端。
四博模组选型手册中,ESP32-S3 系列被明确归类到"音视频 / AI 市场",ESPS3-32、ESPS3-32E 等模组兼容官方模组形态,适合做音频、显示和 AI 类终端;同时 ESP32-S3 具备双核 240MHz、较多 GPIO、可扩展 PSRAM,并支持 SPI、RGB、I8080 等 LCD 接口,更适合做带屏 AI 终端。
一、方案整体定位
四博 AI 智能音箱可以定义为:
四博 AI 智能音箱 =
ESP32-S3 AI 主控
+ 远场麦克风阵列
+ 噪声抑制 / 回声消除 / 自动增益
+ 唤醒词识别
+ 实时打断
+ Wi-Fi / 蓝牙 / 4G 多网络
+ 单屏 / 双屏 / 异显
+ WebSocket AI 对话
+ MCP 工具调用
+ 客户系统接入
+ OTA 在线升级
四博 AI 硬件选型表中,AI-S3 双目双屏方案采用 ESP32S3R8 + 16M Flash + VB6824,配套 1.28 寸 LCD 显示屏 ×2、主板、麦克风、喇叭和线材,并支持小智、豆包、ChatGPT 等主流大模型,定位于高端 AI 市场和可定制开发场景。
四博 AI 开发宝典中也包含 AI-S3 标准开发板、AI-S3 双目、RoPet_ESPS3_AI_EYE、多模态、电子吧唧、AI-C5、设备配网、实时打断固件、自定义唤醒词、在线烧录平台等章节,说明该方案不是单点 Demo,而是一套围绕开发、烧录、配网、调试和量产扩展形成的完整开发体系。
二、系统总体架构
四博 AI 音箱可以采用"端侧实时交互 + 云端大模型 + 客户平台控制"的三层架构。
用户语音 / 唤醒词 / 插话 / 触控
↓
远场麦克风阵列
↓
音频前处理:AEC / NS / AGC / VAD / WakeWord
↓
ESP32-S3 主控
↓
Wi-Fi / 蓝牙代理 / 4G 模组
↓
AI 服务:ASR / LLM / TTS / 知识库 / MCP
↓
客户系统:App / IoT 平台 / MQTT / HTTP API
↓
音箱播放 / 屏幕显示 / 智能家居控制 / 场景联动
端侧 ESP32-S3 主要负责:
1. 麦克风音频采集
2. AEC 回声消除
3. NS 噪声抑制
4. AGC 自动增益
5. VAD 人声检测
6. 唤醒词检测
7. 实时打断检测
8. TTS 音频播放
9. 单屏 / 双屏 / 异显驱动
10. Wi-Fi / 蓝牙 / 4G 网络管理
11. WebSocket / MQTT / HTTP 通信
12. MCP 工具调用执行
13. OTA 在线升级
云端或客户服务器负责:
1. ASR 语音识别
2. LLM 大模型理解
3. TTS 语音合成
4. 知识库检索
5. 客户业务系统对接
6. 智能家居设备映射
7. MCP 工具调度
8. 用户账号和设备绑定
三、推荐硬件配置
| 模块 | 推荐配置 |
|---|---|
| 主控 | ESP32-S3R8 / ESPS3-32-N16R8 |
| 存储 | 16MB Flash + 8MB PSRAM |
| 语音唤醒 | VB6824 / 本地唤醒模块 / ESP-SR 可选 |
| 麦克风 | 双麦 / 多麦阵列,支持远场拾音 |
| 音频处理 | AEC、NS、AGC、VAD |
| 音频输出 | I2S Codec + Class-D 功放 |
| 喇叭 | 4Ω 3W 或更高规格 |
| 屏幕 | 单屏 / 双屏,支持同显和异显 |
| 网络 | Wi-Fi、蓝牙代理、外接 4G 模组 |
| 供电 | Type-C + 电池可选 |
| 扩展 | UART、I2C、SPI、I2S、PWM、GPIO |
| 升级 | HTTPS OTA / 在线烧录平台 |
四博模组手册中 ESPS3-32 系列包含 N4、N8、N8R2、N16R2、N16R8 等多个子型号,芯片覆盖 ESP32-S3、S3R2、S3R8,适合根据屏幕、音频缓存、OTA 和客户应用复杂度选择不同存储版本。
四、远场拾音与高噪声可用的技术路线
要实现 5 米以上拾音和高噪声环境下可用,不能只靠麦克风灵敏度,而要做完整音频链路。
建议链路如下:
Mic Array
↓
DC Remove
↓
AEC 回声消除
↓
NS 噪声抑制
↓
AGC 自动增益
↓
VAD 人声检测
↓
WakeWord 唤醒词
↓
ASR 上传
各模块作用:
AEC:设备自己播放 TTS 时,消除喇叭回声
NS:降低风扇声、空调声、人群背景噪声
AGC:远距离说话时自动拉高语音增益
VAD:判断当前是否有人说话,用于实时打断
WakeWord:离线识别唤醒词,弱网也能触发设备
核心音频状态机:
typedef enum {
AUDIO_STATE_IDLE = 0,
AUDIO_STATE_WAKEUP,
AUDIO_STATE_LISTENING,
AUDIO_STATE_UPLOADING,
AUDIO_STATE_THINKING,
AUDIO_STATE_SPEAKING,
AUDIO_STATE_INTERRUPTED,
AUDIO_STATE_ERROR
} audio_state_t;
static volatile audio_state_t g_audio_state = AUDIO_STATE_IDLE;
远场音频帧结构:
#define AUDIO_SAMPLE_RATE 16000
#define AUDIO_BITS 16
#define AUDIO_CHANNELS 1
#define AUDIO_FRAME_MS 20
#define AUDIO_FRAME_SAMPLES (AUDIO_SAMPLE_RATE * AUDIO_FRAME_MS / 1000)
typedef struct {
int16_t pcm[AUDIO_FRAME_SAMPLES];
size_t samples;
int vad_active;
int wake_active;
int noise_level;
int voice_energy;
} audio_frame_t;
VAD 简化示例:
static int audio_calc_energy(const int16_t *pcm, size_t samples)
{
int64_t sum = 0;
for (size_t i = 0; i < samples; i++) {
sum += abs(pcm[i]);
}
return (int)(sum / samples);
}
static bool vad_detect_voice(const int16_t *pcm, size_t samples)
{
int energy = audio_calc_energy(pcm, samples);
/*
* 量产时建议根据底噪动态调整阈值:
* 1. 安静环境阈值低
* 2. 高噪声环境阈值高
* 3. 可结合噪声估计和连续帧判断
*/
return energy > 800;
}
动态噪声门限:
typedef struct {
int noise_floor;
int vad_threshold;
int agc_gain;
} audio_env_t;
static audio_env_t g_audio_env = {
.noise_floor = 300,
.vad_threshold = 800,
.agc_gain = 1,
};
void audio_env_update(const int16_t *pcm, size_t samples)
{
int energy = audio_calc_energy(pcm, samples);
/*
* 如果长期处于低能量状态,认为是环境底噪。
*/
if (energy < g_audio_env.vad_threshold) {
g_audio_env.noise_floor =
(g_audio_env.noise_floor * 9 + energy) / 10;
}
g_audio_env.vad_threshold = g_audio_env.noise_floor + 500;
if (g_audio_env.vad_threshold < 700) {
g_audio_env.vad_threshold = 700;
}
if (g_audio_env.vad_threshold > 2000) {
g_audio_env.vad_threshold = 2000;
}
}
bool vad_detect_voice_dynamic(const int16_t *pcm, size_t samples)
{
int energy = audio_calc_energy(pcm, samples);
return energy > g_audio_env.vad_threshold;
}
五、实时打断:AI 音箱体验的关键
传统音箱最大的问题是:设备正在说话时,用户必须等它说完。
四博 AI 音箱要实现的是:
用户插话 → 立即停止 TTS → 取消当前云端回复 → 重新进入监听
打断来源可以有三种:
1. 唤醒词打断:用户说"你好小博"直接打断
2. VAD 打断:播放时检测到用户插话
3. 按键 / 触控打断:用户短按按键或触控区域打断
四博 AI 开发宝典目录中包含"编译实时打断固件"和"VB6824 如何自定义唤醒词"章节,说明实时打断和唤醒词定制已经是方案级能力,而不是单独宣传点。
打断核心代码:
void ai_interrupt_current_session(void)
{
if (g_audio_state == AUDIO_STATE_SPEAKING) {
audio_player_stop();
/*
* 通知云端取消当前 TTS / LLM 输出。
*/
ai_ws_send_control("{\"type\":\"interrupt\"}");
/*
* UI 进入监听状态。
*/
screen_show_status("已打断,请继续说");
/*
* 重新打开录音链路。
*/
audio_capture_start();
g_audio_state = AUDIO_STATE_INTERRUPTED;
}
}
播放中 VAD 插话检测:
void audio_capture_task(void *arg)
{
int16_t pcm[AUDIO_FRAME_SAMPLES];
size_t bytes_read = 0;
while (1) {
audio_read_pcm(pcm, sizeof(pcm), &bytes_read);
audio_env_update(pcm, AUDIO_FRAME_SAMPLES);
if (g_audio_state == AUDIO_STATE_SPEAKING) {
if (vad_detect_voice_dynamic(pcm, AUDIO_FRAME_SAMPLES)) {
ai_interrupt_current_session();
continue;
}
}
if (g_audio_state == AUDIO_STATE_LISTENING ||
g_audio_state == AUDIO_STATE_INTERRUPTED) {
ai_ws_send_audio((uint8_t *)pcm, bytes_read);
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
唤醒词打断回调:
void wakeword_on_detected(const char *word)
{
ESP_LOGI("WAKE", "wakeword detected: %s", word);
if (g_audio_state == AUDIO_STATE_SPEAKING) {
ai_interrupt_current_session();
} else {
audio_capture_start();
screen_show_status("我在听");
g_audio_state = AUDIO_STATE_LISTENING;
}
ai_ws_send_control("{\"type\":\"wakeup\"}");
}
六、自定义唤醒词
客户做品牌化 AI 设备时,唤醒词通常需要改成自己的品牌词。
例如:
你好四博
你好小博
小 C 小 C
Hi CozyLife
你好管家
小智小智
唤醒词配置结构:
typedef struct {
char wakeword[64];
int sensitivity;
int enable_barge_in;
int enabled;
} wakeword_config_t;
NVS 保存唤醒词:
#include "nvs_flash.h"
#include "nvs.h"
esp_err_t wakeword_save_config(const wakeword_config_t *cfg)
{
nvs_handle_t nvs;
esp_err_t ret = nvs_open("wakeword", NVS_READWRITE, &nvs);
if (ret != ESP_OK) {
return ret;
}
nvs_set_str(nvs, "word", cfg->wakeword);
nvs_set_i32(nvs, "sens", cfg->sensitivity);
nvs_set_i32(nvs, "bargein", cfg->enable_barge_in);
nvs_set_i32(nvs, "enable", cfg->enabled);
nvs_commit(nvs);
nvs_close(nvs);
return ESP_OK;
}
通过 UART 下发到离线唤醒模块:
#define WAKE_UART_PORT UART_NUM_2
static void wake_uart_send(const char *cmd)
{
uart_write_bytes(WAKE_UART_PORT, cmd, strlen(cmd));
}
/*
* 这里是工程封装示例。
* 实际量产时应按 VB6824 或客户离线语音固件协议调整。
*/
esp_err_t wakeword_apply_to_module(const wakeword_config_t *cfg)
{
char cmd[160];
snprintf(cmd, sizeof(cmd),
"AT+WAKEWORD=\"%s\",%d,%d\r\n",
cfg->wakeword,
cfg->sensitivity,
cfg->enable_barge_in);
wake_uart_send(cmd);
return ESP_OK;
}
客户 App 或小程序修改唤醒词:
void user_update_wakeword(const char *word, int sensitivity)
{
wakeword_config_t cfg = {0};
strncpy(cfg.wakeword, word, sizeof(cfg.wakeword) - 1);
cfg.sensitivity = sensitivity;
cfg.enable_barge_in = 1;
cfg.enabled = 1;
wakeword_save_config(&cfg);
wakeword_apply_to_module(&cfg);
screen_show_status("唤醒词已更新");
}
七、多网络接入:蓝牙、Wi-Fi、4G
四博 AI 音箱的联网方式可以设计为三层:
1. Wi-Fi 上网:家庭和办公环境首选
2. 4G 上网:无 Wi-Fi、移动场景、酒店公寓、海外产品
3. 蓝牙上网 / 蓝牙代理:通过手机 App 做轻量联网或配网通道
这里要注意:蓝牙更适合配网、绑定、轻量控制或手机代理,不适合长时间传输高码率音频流。AI 实时语音建议优先走 Wi-Fi 或 4G。
网络类型定义:
typedef enum {
NET_TYPE_NONE = 0,
NET_TYPE_WIFI,
NET_TYPE_BLE_PROXY,
NET_TYPE_4G
} net_type_t;
typedef enum {
NET_STATE_IDLE = 0,
NET_STATE_CONNECTING,
NET_STATE_CONNECTED,
NET_STATE_FAILED
} net_state_t;
typedef struct {
net_type_t type;
net_state_t state;
int rssi;
int online;
} net_status_t;
static net_status_t g_net_status;
网络优先级:
void net_manager_start(void)
{
screen_show_status("正在连接 Wi-Fi");
if (wifi_connect_saved() == ESP_OK) {
g_net_status.type = NET_TYPE_WIFI;
g_net_status.state = NET_STATE_CONNECTED;
g_net_status.online = 1;
ai_ws_client_start();
return;
}
screen_show_status("Wi-Fi失败,尝试4G");
if (modem_4g_connect() == ESP_OK) {
g_net_status.type = NET_TYPE_4G;
g_net_status.state = NET_STATE_CONNECTED;
g_net_status.online = 1;
ai_ws_client_start();
return;
}
screen_show_status("进入蓝牙代理模式");
if (ble_proxy_start() == ESP_OK) {
g_net_status.type = NET_TYPE_BLE_PROXY;
g_net_status.state = NET_STATE_CONNECTED;
g_net_status.online = 1;
return;
}
g_net_status.type = NET_TYPE_NONE;
g_net_status.state = NET_STATE_FAILED;
g_net_status.online = 0;
screen_show_status("网络不可用");
}
4G 模组 UART 初始化:
#define MODEM_UART_PORT UART_NUM_1
void modem_4g_uart_init(void)
{
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
uart_driver_install(MODEM_UART_PORT, 4096, 4096, 0, NULL, 0);
uart_param_config(MODEM_UART_PORT, &uart_config);
uart_set_pin(MODEM_UART_PORT,
GPIO_NUM_16,
GPIO_NUM_17,
UART_PIN_NO_CHANGE,
UART_PIN_NO_CHANGE);
}
4G AT 连接流程:
static esp_err_t modem_send_cmd(const char *cmd,
const char *expect,
int timeout_ms)
{
char rxbuf[256] = {0};
uart_write_bytes(MODEM_UART_PORT, cmd, strlen(cmd));
int len = uart_read_bytes(MODEM_UART_PORT,
rxbuf,
sizeof(rxbuf) - 1,
pdMS_TO_TICKS(timeout_ms));
if (len > 0) {
rxbuf[len] = 0;
ESP_LOGI("4G", "rsp: %s", rxbuf);
if (expect == NULL || strstr(rxbuf, expect)) {
return ESP_OK;
}
}
return ESP_FAIL;
}
esp_err_t modem_4g_connect(void)
{
modem_send_cmd("AT\r\n", "OK", 1000);
modem_send_cmd("ATE0\r\n", "OK", 1000);
modem_send_cmd("AT+CPIN?\r\n", "READY", 3000);
modem_send_cmd("AT+CSQ\r\n", "OK", 1000);
modem_send_cmd("AT+CREG?\r\n", "OK", 1000);
modem_send_cmd("AT+CGATT=1\r\n", "OK", 5000);
/*
* APN 需要根据运营商配置。
*/
modem_send_cmd("AT+CGDCONT=1,\"IP\",\"cmnet\"\r\n", "OK", 1000);
return ESP_OK;
}
四博 AI 开发宝典中 AI-C5 部分包含 Wi-Fi 模式和 4G 模式切换、设备配网等内容,可作为多联网版本开发参考;模组选型手册中 ESP32-C5 系列也提供了 Wi-Fi 6 2.4G/5G + BLE + Zigbee/Thread 的模组路线,适合扩展到双频 Wi-Fi 和多协议中控产品。
八、单屏、双屏和异显设计
四博 AI 音箱可以根据产品形态选择单屏或双屏。
单屏:适合普通 AI 音箱、智能中控、学习机
双屏同显:适合双目表情屏,左右眼同步显示
双屏异显:左屏显示表情,右屏显示文字、状态、二维码、歌词、设备状态
显示模式定义:
typedef enum {
DISPLAY_MODE_SINGLE = 0,
DISPLAY_MODE_DUAL_SAME,
DISPLAY_MODE_DUAL_DIFF
} display_mode_t;
typedef enum {
SCREEN_ROLE_MAIN = 0,
SCREEN_ROLE_LEFT_EYE,
SCREEN_ROLE_RIGHT_INFO
} screen_role_t;
双屏句柄:
typedef struct {
void *panel_left;
void *panel_right;
display_mode_t mode;
int width;
int height;
} dual_screen_t;
static dual_screen_t g_screen;
单屏显示:
void screen_show_single(const char *text)
{
lcd_fill(g_screen.panel_left, 0x0000);
lcd_draw_text(g_screen.panel_left, 20, 40, text, 0xFFFF);
}
双屏同显:
void screen_show_dual_same(const char *text)
{
lcd_fill(g_screen.panel_left, 0x0000);
lcd_fill(g_screen.panel_right, 0x0000);
lcd_draw_text(g_screen.panel_left, 20, 40, text, 0xFFFF);
lcd_draw_text(g_screen.panel_right, 20, 40, text, 0xFFFF);
}
双屏异显:
void screen_show_dual_diff(const char *emotion, const char *status)
{
/*
* 左屏:AI 表情
* 右屏:文字状态
*/
lcd_fill(g_screen.panel_left, 0x0000);
lcd_fill(g_screen.panel_right, 0x0000);
if (strcmp(emotion, "listening") == 0) {
lcd_draw_eye_listening(g_screen.panel_left);
} else if (strcmp(emotion, "thinking") == 0) {
lcd_draw_eye_thinking(g_screen.panel_left);
} else if (strcmp(emotion, "speaking") == 0) {
lcd_draw_eye_speaking(g_screen.panel_left);
} else {
lcd_draw_eye_normal(g_screen.panel_left);
}
lcd_draw_text(g_screen.panel_right, 10, 30, status, 0xFFFF);
}
根据 AI 状态自动刷新异显:
void ui_update_by_audio_state(audio_state_t state)
{
switch (state) {
case AUDIO_STATE_LISTENING:
screen_show_dual_diff("listening", "正在聆听...");
break;
case AUDIO_STATE_THINKING:
screen_show_dual_diff("thinking", "AI 思考中...");
break;
case AUDIO_STATE_SPEAKING:
screen_show_dual_diff("speaking", "正在回答");
break;
case AUDIO_STATE_INTERRUPTED:
screen_show_dual_diff("listening", "已打断,请继续说");
break;
default:
screen_show_dual_diff("normal", "AI 在线");
break;
}
}
开发宝典中 AI-S3 双目章节包含 RoPet_ESPS3_AI_EYE 快速入门,以及 1.28 寸和 0.71 寸屏幕参数等内容,说明双目屏和多屏显示已经纳入四博 AI-S3 开发体系。
九、WebSocket AI 对话链路
推荐 AI 对话采用 WebSocket 长连接,支持低延迟音频上传、TTS 下发、状态同步和实时打断。
设备上线消息:
{
"type": "hello",
"device_id": "doit_ai_speaker_s3_001",
"product": "doit_ai_speaker",
"firmware": "1.0.0",
"features": {
"far_field": true,
"noise_suppression": true,
"wakeword_interrupt": true,
"realtime_interrupt": true,
"custom_wakeword": true,
"wifi": true,
"ble_proxy": true,
"4g": true,
"single_screen": true,
"dual_screen": true,
"dual_diff_display": true,
"mcp": true,
"ota": true
},
"audio": {
"format": "pcm_s16le",
"sample_rate": 16000,
"channels": 1
}
}
WebSocket 事件处理:
static void ai_ws_handle_json(const char *data, int len)
{
char *buf = calloc(1, len + 1);
if (!buf) return;
memcpy(buf, data, len);
cJSON *root = cJSON_Parse(buf);
if (!root) {
free(buf);
return;
}
cJSON *type = cJSON_GetObjectItem(root, "type");
if (cJSON_IsString(type)) {
if (strcmp(type->valuestring, "stt") == 0) {
cJSON *text = cJSON_GetObjectItem(root, "text");
if (cJSON_IsString(text)) {
screen_show_dual_diff("listening", text->valuestring);
}
} else if (strcmp(type->valuestring, "llm") == 0) {
screen_show_dual_diff("thinking", "AI 思考中");
} else if (strcmp(type->valuestring, "tts_start") == 0) {
g_audio_state = AUDIO_STATE_SPEAKING;
screen_show_dual_diff("speaking", "正在回答");
audio_player_start();
} else if (strcmp(type->valuestring, "tts_end") == 0) {
g_audio_state = AUDIO_STATE_IDLE;
screen_show_dual_diff("normal", "AI 在线");
audio_player_stop();
} else if (strcmp(type->valuestring, "tool_call") == 0) {
mcp_service_handle(root);
}
}
cJSON_Delete(root);
free(buf);
}
发送音频:
esp_err_t ai_ws_send_audio_frame(const int16_t *pcm, size_t samples)
{
if (!ai_ws_is_connected()) {
return ESP_FAIL;
}
return ai_ws_send_binary((const uint8_t *)pcm,
samples * sizeof(int16_t));
}
十、MCP 工具调用:方便接入客户系统
客户系统接入通常有三种方式:
1. HTTP API:适合云平台、App 后端、智能家居平台
2. MQTT:适合 IoT 设备控制、状态上报、场景联动
3. UART / RS485:适合本地 MCU、家电主控板、酒店客控系统
MCP 工具定义:
typedef enum {
MCP_TOOL_DEVICE_CONTROL = 0,
MCP_TOOL_SCENE_RUN,
MCP_TOOL_SCREEN_SET,
MCP_TOOL_WAKEWORD_UPDATE,
MCP_TOOL_AUDIO_SET_VOLUME,
MCP_TOOL_NET_SWITCH,
MCP_TOOL_UNKNOWN
} mcp_tool_id_t;
typedef struct {
const char *name;
mcp_tool_id_t id;
} mcp_tool_map_t;
static const mcp_tool_map_t g_mcp_tools[] = {
{"customer.device.control", MCP_TOOL_DEVICE_CONTROL},
{"customer.scene.run", MCP_TOOL_SCENE_RUN},
{"screen.display.set", MCP_TOOL_SCREEN_SET},
{"device.wakeword.update", MCP_TOOL_WAKEWORD_UPDATE},
{"audio.volume.set", MCP_TOOL_AUDIO_SET_VOLUME},
{"network.switch", MCP_TOOL_NET_SWITCH},
};
MCP 分发:
static mcp_tool_id_t mcp_get_tool_id(const char *name)
{
for (int i = 0; i < sizeof(g_mcp_tools) / sizeof(g_mcp_tools[0]); i++) {
if (strcmp(name, g_mcp_tools[i].name) == 0) {
return g_mcp_tools[i].id;
}
}
return MCP_TOOL_UNKNOWN;
}
void mcp_service_handle(cJSON *root)
{
cJSON *tool = cJSON_GetObjectItem(root, "tool");
cJSON *args = cJSON_GetObjectItem(root, "arguments");
if (!cJSON_IsString(tool) || !cJSON_IsObject(args)) {
return;
}
switch (mcp_get_tool_id(tool->valuestring)) {
case MCP_TOOL_DEVICE_CONTROL:
mcp_handle_device_control(args);
break;
case MCP_TOOL_SCENE_RUN:
mcp_handle_scene_run(args);
break;
case MCP_TOOL_SCREEN_SET:
mcp_handle_screen_set(args);
break;
case MCP_TOOL_WAKEWORD_UPDATE:
mcp_handle_wakeword_update(args);
break;
case MCP_TOOL_AUDIO_SET_VOLUME:
mcp_handle_volume_set(args);
break;
case MCP_TOOL_NET_SWITCH:
mcp_handle_network_switch(args);
break;
default:
ESP_LOGW("MCP", "unknown tool: %s", tool->valuestring);
break;
}
}
HTTP 接入客户系统:
typedef struct {
char device_id[32];
char action[32];
int value;
} control_cmd_t;
esp_err_t customer_control_device(control_cmd_t *cmd)
{
char json[256];
snprintf(json, sizeof(json),
"{"
"\"device_id\":\"%s\","
"\"action\":\"%s\","
"\"value\":%d"
"}",
cmd->device_id,
cmd->action,
cmd->value);
return http_post_json("https://api.customer.com/device/control", json);
}
void mcp_handle_device_control(cJSON *args)
{
cJSON *device_id = cJSON_GetObjectItem(args, "device_id");
cJSON *action = cJSON_GetObjectItem(args, "action");
cJSON *value = cJSON_GetObjectItem(args, "value");
if (!cJSON_IsString(device_id) ||
!cJSON_IsString(action) ||
!cJSON_IsNumber(value)) {
return;
}
control_cmd_t cmd = {0};
strncpy(cmd.device_id, device_id->valuestring, sizeof(cmd.device_id) - 1);
strncpy(cmd.action, action->valuestring, sizeof(cmd.action) - 1);
cmd.value = value->valueint;
customer_control_device(&cmd);
}
MQTT 接入客户 IoT 平台:
static void mqtt_event_handler(void *handler_args,
esp_event_base_t base,
int32_t event_id,
void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
esp_mqtt_client_subscribe(event->client,
"customer/+/command/set",
1);
esp_mqtt_client_publish(event->client,
"customer/speaker/status",
"{\"online\":true}",
0,
1,
0);
break;
case MQTT_EVENT_DATA:
mqtt_handle_customer_command(event->topic,
event->topic_len,
event->data,
event->data_len);
break;
default:
break;
}
}
十一、OTA 与在线升级
AI 音箱量产后,OTA 非常关键。
可升级内容包括:
1. 主固件
2. 唤醒词配置
3. 噪声参数
4. VAD 阈值
5. AI 后端地址
6. MCP 工具列表
7. 屏幕 UI 资源
8. 提示音资源
9. 客户业务协议
10. 4G / Wi-Fi 网络策略
OTA 版本文件:
{
"project": "doit_ai_speaker_s3",
"version": "1.0.3",
"chip": "esp32s3",
"url": "https://ota.customer.com/doit_ai_speaker_s3_v1.0.3.bin",
"asset_url": "https://ota.customer.com/assets/speaker_assets_v3.bin",
"md5": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"force": false,
"note": "优化5米远场拾音、实时打断和双屏异显"
}
OTA 代码:
#include "esp_https_ota.h"
#include "esp_http_client.h"
void ota_check_update(void)
{
esp_http_client_config_t http_config = {
.url = "https://ota.customer.com/doit_ai_speaker/latest.bin",
.timeout_ms = 10000,
.keep_alive_enable = true,
};
esp_https_ota_config_t ota_config = {
.http_config = &http_config,
};
screen_show_dual_diff("thinking", "正在升级,请勿断电");
esp_err_t ret = esp_https_ota(&ota_config);
if (ret == ESP_OK) {
screen_show_dual_diff("normal", "升级成功,正在重启");
esp_restart();
} else {
screen_show_dual_diff("error", "升级失败");
}
}
分区表示例:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
otadata, data, ota, 0xf000, 0x2000,
phy_init, data, phy, 0x11000, 0x1000,
factory, app, factory, 0x20000, 0x300000,
ota_0, app, ota_0, , 0x300000,
ota_1, app, ota_1, , 0x300000,
assets, data, spiffs, , 0x200000,
storage, data, spiffs, , 0x100000,
四博 AI 开发宝典中说明,小智 AI 系统硬件设备的开源代码可通过 VSCode 安装 ESP-IDF 扩展和编译工具进行开发、编译和烧录,并且提供了 DOIT_AI 开源工程和后续编译运行流程,这对客户做二次开发和量产验证非常关键。
十二、推荐工程目录
doit_ai_speaker_s3/
├── main/
│ ├── app_main.c
│ ├── board_config.h
│ ├── audio_capture.c
│ ├── audio_frontend.c
│ ├── audio_player.c
│ ├── wakeword_service.c
│ ├── interrupt_service.c
│ ├── wifi_manager.c
│ ├── ble_proxy.c
│ ├── modem_4g.c
│ ├── net_manager.c
│ ├── screen_single.c
│ ├── screen_dual.c
│ ├── ai_ws_client.c
│ ├── mcp_service.c
│ ├── mqtt_service.c
│ ├── customer_api.c
│ └── ota_service.c
├── components/
│ ├── codec/
│ ├── lcd_driver/
│ ├── wakeword/
│ ├── modem/
│ └── audio_afe/
├── partitions_ota.csv
└── sdkconfig.defaults
主程序框架:
void app_main(void)
{
nvs_flash_init();
esp_netif_init();
esp_event_loop_create_default();
board_init();
screen_init();
screen_show_dual_diff("normal", "四博 AI 启动中");
audio_capture_init();
audio_player_init();
audio_frontend_init();
wakeword_service_init();
interrupt_service_init();
wifi_manager_init();
ble_proxy_init();
modem_4g_init();
net_manager_start();
ai_ws_client_init();
mcp_service_init();
mqtt_service_init();
ota_service_init();
xTaskCreate(audio_capture_task, "audio_capture", 8192, NULL, 5, NULL);
xTaskCreate(audio_frontend_task, "audio_frontend", 8192, NULL, 6, NULL);
xTaskCreate(ai_ws_client_task, "ai_ws_client", 10240, NULL, 6, NULL);
xTaskCreate(net_monitor_task, "net_monitor", 4096, NULL, 3, NULL);
xTaskCreate(ota_service_task, "ota_service", 6144, NULL, 3, NULL);
screen_show_dual_diff("normal", "AI 在线");
}
十三、开发与量产流程
客户拿到四博 AI 音箱方案后,可以按以下流程开发:
1. 选择 ESP32-S3 / S3R8 硬件版本
2. 确认单屏、双屏或双屏异显方案
3. 确认麦克风数量和远场拾音结构
4. 配置 ESP-IDF 开发环境
5. 下载 DOIT_AI 或客户定制工程
6. 编译基础固件
7. 配置 Wi-Fi / 蓝牙 / 4G 联网方式
8. 配置唤醒词和实时打断参数
9. 接入客户 AI 后端或小智服务
10. 接入客户 App、IoT 平台或 MQTT
11. 配置 OTA 地址
12. 进行噪声、距离、打断、稳定性测试
13. 进入量产烧录和出厂测试
编译命令示例:
git clone https://github.com/SmartArduino/DOIT_AI.git
cd DOIT_AI
idf.py set-target esp32s3
idf.py menuconfig
idf.py build
idf.py -p COMx flash monitor
十四、方案核心价值
四博 AI 音箱方案的核心价值,不是单纯"接入大模型",而是把 AI 对话能力和端侧工程能力结合起来。
1. 5 米以上远场拾音,适合客厅、会议室、酒店房间
2. 高噪声环境可用,适合真实家庭和商业空间
3. 支持唤醒词打断,交互更自然
4. 支持实时打断,用户不用等设备说完
5. 支持自定义唤醒词,适合品牌客户
6. 支持蓝牙、Wi-Fi、4G 多种联网方式
7. 支持单屏、双屏和双屏异显
8. 基于 ESP32-S3,方便二次开发
9. 可接入客户自己的 App、IoT 平台和业务系统
10. 支持 OTA,量产后仍可持续升级
结语
四博 AI 智能音箱方案,本质上是一套面向真实产品落地的 AIoT 语音平台。
它既解决"能不能对话"的问题,也解决"能不能听远、能不能抗噪、能不能打断、能不能改唤醒词、能不能多网络联网、能不能带屏显示、能不能接客户系统、能不能量产升级"的问题。
普通 AI 音箱只是:
听得见,说得出
四博 AI 音箱要做到的是:
听得远
抗得住噪
打断得快
联网方式多
屏幕显示灵活
客户系统接入方便
二次开发成本低
量产升级可持续
一句话总结:
四博 AI 音箱不是简单的语音播放器,
而是基于 ESP32-S3 打造的远场拾音、多网络接入、多屏显示、
实时打断、可自定义唤醒词、可接入客户系统的 AI 智能硬件平台。