四博 AI 智能音箱 4G S3 版本工程落地方案:三模联网、远场唤醒、打断播放与 AI 会话框架

四博 AI 智能音箱 4G S3 版本工程落地方案:三模联网、远场唤醒、打断播放与 AI 会话框架

1. 方案定位

四博 AI 智能音箱 4G S3 版本是一套基于 ESP32-S3 + VB6824 + Wi-Fi/BLE/4G 的 AI 语音终端方案。它不是传统意义上的蓝牙音箱,而是面向家庭、厨房、展厅、户外、门店和 B 端定制场景的联网 AI 音箱。

四博模组选型资料中,ESP32-S3 系列被定位在 音视频 / AI 市场,ESPS3-32、ESPS3-32E 系列兼容官方 ESP32-S3 模组封装,适合 AI 音箱、AI 相机、多模态设备等产品开发。 四博 AI 方案资料中也明确给出 ESP32-C2/C3/S3 + VB6824 语音方案,VB6824 可完成音频编解码、AEC、语音唤醒和唤醒词修改,让主控芯片专注通信及 UI。

本方案采用"三层解耦"架构:

复制代码
  1. 网络平面:Wi-Fi / BLE / 4G

  2. 语音平面:VB6824 / 唤醒 / 打断 / 离线命令

  3. AI 平面:WebSocket / 大模型 / TTS / OTA / 工具调用


2. 硬件组合建议

复制代码

主控:ESP32-S3R8 / ESPS3-32 N16R8

语音:VB6824

联网:Wi-Fi + BLE + 4G Cat.1

音频:MIC + 功放 + 喇叭

显示:LED 灯效 / 小屏 / 点阵屏可选

存储:16MB Flash + 8MB PSRAM

电源:Type-C / 锂电池 / DC 供电

扩展:外置经典蓝牙音频芯片 / TF Card / 按键

需要特别说明:

ESP32-S3 原生支持 Wi-Fi + BLE,BLE 适合配网、绑定、小程序控制;如果要实现真正的手机蓝牙音乐播放,也就是 A2DP 经典蓝牙音频,建议增加外置蓝牙音频芯片或采用 7014 类蓝牙音频方案。四博资料中也单独列出了 7014 蓝牙 PAN AI 手机伴侣方案和 AI 智能音响方案,强调可做蓝牙音响、闹钟、声音克隆、声纹识别、APP、小程序和改唤醒词等功能。


3. 总体软件框架

这次不采用普通 while(1) 轮询写法,而是采用 Bus + Manager + Port + Policy 的工程结构。

复制代码

sibo_ai_speaker_4g_s3/

├── app/

│ ├── app_main.c

│ ├── app_bus.c

│ ├── app_bus.h

│ ├── app_fsm.c

│ └── app_fsm.h

├── board/

│ ├── board_config.h

│ └── board_init.c

├── network/

│ ├── net_policy.c

│ ├── wifi_port.c

│ ├── ble_provision.c

│ └── modem_4g_port.c

├── voice/

│ ├── vb6824_port.c

│ ├── voice_cmd_map.c

│ └── wakeup_controller.c

├── audio/

│ ├── audio_route.c

│ ├── tts_player.c

│ └── prompt_player.c

├── ai/

│ ├── ai_session.c

│ ├── ai_protocol.c

│ └── ai_action.c

├── ota/

│ └── ota_service.c

└── ui/

├── speaker_ui.c

└── led_effect.c

核心思想:

复制代码

驱动层只负责收发数据;

Manager 层只负责状态管理;

Policy 层只负责选择策略;

App 层只处理业务事件;

AI 层只处理协议与云端交互。


4. board_config.h

复制代码

#pragma once

#include "driver/gpio.h"

#include "driver/uart.h"

#define PRODUCT_NAME "SIBO_AI_SPEAKER_4G_S3"

#define DEVICE_ID "SIBO_S3_4G_001122334455"

/* AI Server */

#define AI_WS_URI "wss://ai.example.com/sibo/speaker/ws"

/* VB6824 UART */

#define VB6824_UART UART_NUM_1

#define VB6824_TXD GPIO_NUM_17

#define VB6824_RXD GPIO_NUM_18

#define VB6824_BAUD 115200

/* 4G UART */

#define MODEM_UART UART_NUM_2

#define MODEM_TXD GPIO_NUM_40

#define MODEM_RXD GPIO_NUM_41

#define MODEM_PWR GPIO_NUM_42

#define MODEM_BAUD 115200

/* Audio */

#define I2S_BCLK GPIO_NUM_5

#define I2S_WS GPIO_NUM_6

#define I2S_DOUT GPIO_NUM_7

#define I2S_DIN GPIO_NUM_8

#define AMP_EN GPIO_NUM_9

/* Keys */

#define KEY_WAKEUP GPIO_NUM_0

#define KEY_VOL_UP GPIO_NUM_10

#define KEY_VOL_DOWN GPIO_NUM_11

/* Network Policy */

#define WIFI_SCORE 100

#define MODEM_4G_SCORE 70

#define NET_RETRY_INTERVAL_MS 3000


5. 应用事件总线

AI 音箱有大量异步事件:网络上线、4G 断线、语音唤醒、播放中打断、AI 返回、TTS 播放完成、OTA 通知。建议统一走事件总线。

复制代码

#pragma once

#include <stdint.h>

#include <stddef.h>

typedef enum {

BUS_EVT_NONE = 0,

BUS_EVT_WIFI_UP,

BUS_EVT_WIFI_DOWN,

BUS_EVT_4G_UP,

BUS_EVT_4G_DOWN,

BUS_EVT_BLE_CONFIG_OK,

BUS_EVT_NET_SELECTED,

BUS_EVT_NET_LOST,

BUS_EVT_WAKEUP,

BUS_EVT_BARGE_IN,

BUS_EVT_CMD_CHAT,

BUS_EVT_CMD_STOP,

BUS_EVT_CMD_VOL_UP,

BUS_EVT_CMD_VOL_DOWN,

BUS_EVT_CMD_BT_MODE,

BUS_EVT_CMD_MUSIC,

BUS_EVT_CMD_ALARM,

BUS_EVT_AI_CONNECTED,

BUS_EVT_AI_DISCONNECTED,

BUS_EVT_AI_JSON,

BUS_EVT_TTS_START,

BUS_EVT_TTS_DONE,

BUS_EVT_OTA_NOTIFY,

BUS_EVT_OTA_START,

BUS_EVT_OTA_DONE,

BUS_EVT_OTA_FAIL,

} bus_evt_id_t;

typedef struct {

bus_evt_id_t id;

void *payload;

size_t length;

} bus_evt_t;

复制代码

#include "freertos/FreeRTOS.h"

#include "freertos/queue.h"

#include "app_bus.h"

static QueueHandle_t s_bus_queue = NULL;

void app_bus_init(void)

{

s_bus_queue = xQueueCreate(32, sizeof(bus_evt_t));

}

bool app_bus_post(bus_evt_id_t id, void *payload, size_t length)

{

if (!s_bus_queue) {

return false;

}

bus_evt_t evt = {

.id = id,

.payload = payload,

.length = length,

};

return xQueueSend(s_bus_queue, &evt, pdMS_TO_TICKS(20)) == pdTRUE;

}

QueueHandle_t app_bus_queue(void)

{

return s_bus_queue;

}


6. 三模联网策略:Wi-Fi 优先,4G 兜底,BLE 配网

这版代码用"评分制"来选择网络,比简单 if/else 更适合后续扩展。

复制代码

typedef enum {

NET_IF_NONE = 0,

NET_IF_WIFI,

NET_IF_4G,

} net_if_t;

typedef struct {

bool wifi_ready;

bool g4_ready;

int wifi_rssi;

int g4_csq;

net_if_t active;

} net_policy_ctx_t;

static net_policy_ctx_t s_net;

static int net_score_wifi(void)

{

if (!s_net.wifi_ready) {

return 0;

}

if (s_net.wifi_rssi > -60) {

return 100;

} else if (s_net.wifi_rssi > -75) {

return 85;

}

return 60;

}

static int net_score_4g(void)

{

if (!s_net.g4_ready) {

return 0;

}

if (s_net.g4_csq >= 20) {

return 80;

} else if (s_net.g4_csq >= 12) {

return 70;

}

return 50;

}

static void net_policy_select(void)

{

int wifi_score = net_score_wifi();

int g4_score = net_score_4g();

net_if_t next = NET_IF_NONE;

if (wifi_score >= g4_score && wifi_score > 0) {

next = NET_IF_WIFI;

} else if (g4_score > 0) {

next = NET_IF_4G;

}

if (next != s_net.active) {

s_net.active = next;

if (next == NET_IF_NONE) {

app_bus_post(BUS_EVT_NET_LOST, NULL, 0);

} else {

app_bus_post(BUS_EVT_NET_SELECTED, NULL, 0);

}

}

}

void net_policy_on_event(bus_evt_id_t evt)

{

switch (evt) {

case BUS_EVT_WIFI_UP:

s_net.wifi_ready = true;

break;

case BUS_EVT_WIFI_DOWN:

s_net.wifi_ready = false;

modem_4g_connect_async();

break;

case BUS_EVT_4G_UP:

s_net.g4_ready = true;

break;

case BUS_EVT_4G_DOWN:

s_net.g4_ready = false;

break;

case BUS_EVT_BLE_CONFIG_OK:

wifi_connect_saved_profile();

break;

default:

break;

}

net_policy_select();

}

const char *net_policy_active_name(void)

{

switch (s_net.active) {

case NET_IF_WIFI:

return "wifi";

case NET_IF_4G:

return "4g";

default:

return "none";

}

}


7. 4G 模块 AT 命令封装

复制代码

#include "driver/uart.h"

#include "esp_log.h"

#include "board_config.h"

static const char *TAG = "MODEM4G";

void modem_4g_init(void)

{

uart_config_t cfg = {

.baud_rate = MODEM_BAUD,

.data_bits = UART_DATA_8_BITS,

.parity = UART_PARITY_DISABLE,

.stop_bits = UART_STOP_BITS_1,

.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,

.source_clk = UART_SCLK_DEFAULT,

};

uart_driver_install(MODEM_UART, 4096, 4096, 0, NULL, 0);

uart_param_config(MODEM_UART, &cfg);

uart_set_pin(MODEM_UART, MODEM_TXD, MODEM_RXD,

UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

ESP_LOGI(TAG, "4G modem uart initialized");

}

static void modem_send_line(const char *cmd)

{

uart_write_bytes(MODEM_UART, cmd, strlen(cmd));

uart_write_bytes(MODEM_UART, "\r\n", 2);

}

void modem_4g_probe_basic(void)

{

modem_send_line("AT");

vTaskDelay(pdMS_TO_TICKS(300));

modem_send_line("ATE0");

vTaskDelay(pdMS_TO_TICKS(300));

modem_send_line("AT+CPIN?");

vTaskDelay(pdMS_TO_TICKS(300));

modem_send_line("AT+CSQ");

vTaskDelay(pdMS_TO_TICKS(300));

modem_send_line("AT+CREG?");

vTaskDelay(pdMS_TO_TICKS(300));

modem_send_line("AT+CGATT?");

vTaskDelay(pdMS_TO_TICKS(300));

}

void modem_4g_start_data_call(void)

{

modem_send_line("AT+CGDCONT=1,\"IP\",\"cmnet\"");

vTaskDelay(pdMS_TO_TICKS(500));

modem_send_line("ATD*99#");

/*

* 后续进入 PPP:

* 1. esp_modem 建立 DTE/DCE

* 2. esp_netif_attach PPP

* 3. 等待 IP_EVENT_PPP_GOT_IP

* 4. 成功后 app_bus_post(BUS_EVT_4G_UP)

*/

}


8. VB6824 串口流式解析器

上一版是简单判断 buf[0] == 0xAA,真实产品建议写成流式解析器,避免串口分包、粘包导致解析失败。

协议示例:

复制代码

AA 55 LEN CMD PAYLOAD... CHECKSUM

复制代码

typedef enum {

PARSE_WAIT_AA = 0,

PARSE_WAIT_55,

PARSE_WAIT_LEN,

PARSE_WAIT_BODY,

PARSE_WAIT_SUM,

} vb_parse_state_t;

typedef struct {

vb_parse_state_t state;

uint8_t len;

uint8_t index;

uint8_t cmd;

uint8_t body[32];

uint8_t sum;

} vb_parser_t;

static vb_parser_t s_vb_parser;

static uint8_t vb_sum_calc(uint8_t len, uint8_t cmd, uint8_t *body)

{

uint8_t sum = 0xAA + 0x55 + len + cmd;

for (int i = 0; i < len - 1; i++) {

sum += body[i];

}

return sum;

}

static void vb_dispatch_cmd(uint8_t cmd)

{

switch (cmd) {

case 0x01:

app_bus_post(BUS_EVT_WAKEUP, NULL, 0);

break;

case 0x02:

app_bus_post(BUS_EVT_BARGE_IN, NULL, 0);

break;

case 0x03:

app_bus_post(BUS_EVT_CMD_CHAT, NULL, 0);

break;

case 0x04:

app_bus_post(BUS_EVT_CMD_STOP, NULL, 0);

break;

case 0x05:

app_bus_post(BUS_EVT_CMD_VOL_UP, NULL, 0);

break;

case 0x06:

app_bus_post(BUS_EVT_CMD_VOL_DOWN, NULL, 0);

break;

case 0x07:

app_bus_post(BUS_EVT_CMD_BT_MODE, NULL, 0);

break;

default:

break;

}

}

static void vb_parser_input(uint8_t byte)

{

switch (s_vb_parser.state) {

case PARSE_WAIT_AA:

if (byte == 0xAA) {

s_vb_parser.state = PARSE_WAIT_55;

}

break;

case PARSE_WAIT_55:

if (byte == 0x55) {

s_vb_parser.state = PARSE_WAIT_LEN;

} else {

s_vb_parser.state = PARSE_WAIT_AA;

}

break;

case PARSE_WAIT_LEN:

s_vb_parser.len = byte;

s_vb_parser.index = 0;

if (s_vb_parser.len == 1) {

s_vb_parser.state = PARSE_WAIT_SUM;

} else {

s_vb_parser.state = PARSE_WAIT_BODY;

}

break;

case PARSE_WAIT_BODY:

if (s_vb_parser.index == 0) {

s_vb_parser.cmd = byte;

} else {

s_vb_parser.body[s_vb_parser.index - 1] = byte;

}

s_vb_parser.index++;

if (s_vb_parser.index >= s_vb_parser.len) {

s_vb_parser.state = PARSE_WAIT_SUM;

}

break;

case PARSE_WAIT_SUM: {

uint8_t calc = vb_sum_calc(

s_vb_parser.len,

s_vb_parser.cmd,

s_vb_parser.body

);

if (calc == byte) {

vb_dispatch_cmd(s_vb_parser.cmd);

}

memset(&s_vb_parser, 0, sizeof(s_vb_parser));

s_vb_parser.state = PARSE_WAIT_AA;

break;

}

default:

s_vb_parser.state = PARSE_WAIT_AA;

break;

}

}

串口任务:

复制代码

void vb6824_task(void *arg)

{

uint8_t buf[64];

while (1) {

int len = uart_read_bytes(VB6824_UART, buf, sizeof(buf), pdMS_TO_TICKS(100));

for (int i = 0; i < len; i++) {

vb_parser_input(buf[i]);

}

}

}


9. 音频状态机:远场唤醒 + 播放中打断

复制代码

typedef enum {

AUDIO_IDLE = 0,

AUDIO_LISTENING,

AUDIO_UPLOADING,

AUDIO_PLAYING_TTS,

AUDIO_BT_MUSIC,

AUDIO_INTERRUPTED,

} audio_state_t;

static audio_state_t s_audio_state = AUDIO_IDLE;

static int s_volume = 70;

void audio_set_state(audio_state_t state)

{

s_audio_state = state;

}

void audio_barge_in(void)

{

if (s_audio_state == AUDIO_PLAYING_TTS ||

s_audio_state == AUDIO_BT_MUSIC) {

audio_player_stop();

s_audio_state = AUDIO_INTERRUPTED;

speaker_ui_status("已打断,请继续说");

}

}

void audio_volume_up(void)

{

if (s_volume < 100) {

s_volume += 5;

}

audio_player_set_volume(s_volume);

}

void audio_volume_down(void)

{

if (s_volume > 0) {

s_volume -= 5;

}

audio_player_set_volume(s_volume);

}

VB6824 的价值就在这里:它把唤醒、AEC、离线命令和抗噪能力前置到语音芯片,让 ESP32-S3 主要负责通信、状态机和 AI 协议。四博 AI 开发宝典中提到,VB6824 具备更远距离唤醒、更低误唤醒率、更强抗噪能力和更快响应识别时间。


10. AI 会话协议

设备上线:

复制代码

{

"type": "hello",

"device_id": "SIBO_S3_4G_001122334455",

"product": "SIBO_AI_SPEAKER_4G_S3",

"net": "wifi",

"capability": {

"wifi": true,

"ble": true,

"g4": true,

"far_field": true,

"barge_in": true,

"wake_word": "小博小博"

}

}

用户语音请求:

复制代码

{

"type": "chat",

"session_id": "session_0001",

"text": "帮我设置一个晚上八点的提醒",

"scene": "ai_speaker",

"tts": true

}

AI 返回:

复制代码

{

"type": "ai_result",

"text": "好的,已为你设置晚上八点的提醒。",

"tts_url": "https://cdn.example.com/tts/001.mp3",

"action": {

"name": "set_alarm",

"params": {

"time": "20:00"

}

}

}

WebSocket 客户端:

复制代码

static esp_websocket_client_handle_t s_ws;

static void ai_ws_event_handler(void *arg,

esp_event_base_t base,

int32_t event_id,

void *event_data)

{

esp_websocket_event_data_t *data = event_data;

switch (event_id) {

case WEBSOCKET_EVENT_CONNECTED:

app_bus_post(BUS_EVT_AI_CONNECTED, NULL, 0);

break;

case WEBSOCKET_EVENT_DISCONNECTED:

app_bus_post(BUS_EVT_AI_DISCONNECTED, NULL, 0);

break;

case WEBSOCKET_EVENT_DATA:

if (data->op_code == 0x1) {

char *json = calloc(1, data->data_len + 1);

if (json) {

memcpy(json, data->data_ptr, data->data_len);

app_bus_post(BUS_EVT_AI_JSON, json, data->data_len);

}

}

break;

default:

break;

}

}

void ai_session_start(void)

{

esp_websocket_client_config_t cfg = {

.uri = AI_WS_URI,

.reconnect_timeout_ms = 3000,

.network_timeout_ms = 10000,

};

s_ws = esp_websocket_client_init(&cfg);

esp_websocket_register_events(s_ws, WEBSOCKET_EVENT_ANY, ai_ws_event_handler, NULL);

esp_websocket_client_start(s_ws);

}

static void ai_send_json(cJSON *root)

{

if (!s_ws || !esp_websocket_client_is_connected(s_ws)) {

return;

}

char *text = cJSON_PrintUnformatted(root);

if (!text) {

return;

}

esp_websocket_client_send_text(s_ws, text, strlen(text), portMAX_DELAY);

cJSON_free(text);

}


11. 设备 Hello 上报

复制代码

void ai_send_hello(void)

{

cJSON *root = cJSON_CreateObject();

cJSON_AddStringToObject(root, "type", "hello");

cJSON_AddStringToObject(root, "device_id", DEVICE_ID);

cJSON_AddStringToObject(root, "product", PRODUCT_NAME);

cJSON_AddStringToObject(root, "net", net_policy_active_name());

cJSON *cap = cJSON_CreateObject();

cJSON_AddBoolToObject(cap, "wifi", true);

cJSON_AddBoolToObject(cap, "ble", true);

cJSON_AddBoolToObject(cap, "g4", true);

cJSON_AddBoolToObject(cap, "far_field", true);

cJSON_AddBoolToObject(cap, "barge_in", true);

cJSON_AddStringToObject(cap, "wake_word", "小博小博");

cJSON_AddItemToObject(root, "capability", cap);

ai_send_json(root);

cJSON_Delete(root);

}


12. AI 返回解析与 Action 分发

复制代码

static void ai_handle_action(cJSON *action)

{

cJSON *name = cJSON_GetObjectItem(action, "name");

cJSON *params = cJSON_GetObjectItem(action, "params");

if (!cJSON_IsString(name)) {

return;

}

if (strcmp(name->valuestring, "set_alarm") == 0) {

cJSON *time = cJSON_GetObjectItem(params, "time");

if (cJSON_IsString(time)) {

alarm_set(time->valuestring);

}

} else if (strcmp(name->valuestring, "play_music") == 0) {

cJSON *keyword = cJSON_GetObjectItem(params, "keyword");

if (cJSON_IsString(keyword)) {

music_search_and_play(keyword->valuestring);

}

} else if (strcmp(name->valuestring, "switch_bt") == 0) {

audio_route_set_bt_mode(true);

}

}

void ai_parse_json(const char *json)

{

cJSON *root = cJSON_Parse(json);

if (!root) {

return;

}

cJSON *type = cJSON_GetObjectItem(root, "type");

if (cJSON_IsString(type) && strcmp(type->valuestring, "ai_result") == 0) {

cJSON *text = cJSON_GetObjectItem(root, "text");

cJSON *tts = cJSON_GetObjectItem(root, "tts_url");

cJSON *action = cJSON_GetObjectItem(root, "action");

if (cJSON_IsString(text)) {

speaker_ui_text(text->valuestring);

}

if (cJSON_IsString(tts)) {

audio_set_state(AUDIO_PLAYING_TTS);

tts_player_play_url(tts->valuestring);

}

if (cJSON_IsObject(action)) {

ai_handle_action(action);

}

}

if (cJSON_IsString(type) && strcmp(type->valuestring, "ota_notify") == 0) {

cJSON *url = cJSON_GetObjectItem(root, "firmware_url");

if (cJSON_IsString(url)) {

char *copy = strdup(url->valuestring);

app_bus_post(BUS_EVT_OTA_NOTIFY, copy, strlen(copy));

}

}

cJSON_Delete(root);

}


13. 音频路由:AI TTS / 本地提示音 / 蓝牙音频

复制代码

typedef enum {

AUDIO_ROUTE_PROMPT = 0,

AUDIO_ROUTE_AI_TTS,

AUDIO_ROUTE_BT_AUDIO,

} audio_route_t;

static audio_route_t s_route = AUDIO_ROUTE_PROMPT;

void audio_route_set(audio_route_t route)

{

s_route = route;

switch (route) {

case AUDIO_ROUTE_PROMPT:

external_bt_audio_enable(false);

amp_enable(true);

break;

case AUDIO_ROUTE_AI_TTS:

external_bt_audio_enable(false);

amp_enable(true);

break;

case AUDIO_ROUTE_BT_AUDIO:

external_bt_audio_enable(true);

amp_enable(true);

audio_set_state(AUDIO_BT_MUSIC);

break;

}

}

void audio_route_set_bt_mode(bool enable)

{

if (enable) {

audio_route_set(AUDIO_ROUTE_BT_AUDIO);

speaker_ui_status("蓝牙音箱模式");

} else {

audio_route_set(AUDIO_ROUTE_PROMPT);

speaker_ui_status("AI 音箱模式");

}

}


14. App 事件分发

复制代码

static void app_handle_event(bus_evt_t *evt)

{

switch (evt->id) {

case BUS_EVT_WIFI_UP:

case BUS_EVT_WIFI_DOWN:

case BUS_EVT_4G_UP:

case BUS_EVT_4G_DOWN:

case BUS_EVT_BLE_CONFIG_OK:

net_policy_on_event(evt->id);

break;

case BUS_EVT_NET_SELECTED:

speaker_ui_status("网络已连接");

ai_session_start();

break;

case BUS_EVT_AI_CONNECTED:

speaker_ui_status("AI 服务在线");

ai_send_hello();

break;

case BUS_EVT_WAKEUP:

audio_barge_in();

audio_set_state(AUDIO_LISTENING);

prompt_player_play("/spiffs/wakeup.mp3");

speaker_ui_status("我在,请说");

break;

case BUS_EVT_BARGE_IN:

audio_barge_in();

break;

case BUS_EVT_CMD_CHAT:

speaker_ui_status("正在思考...");

ai_send_chat_text("用户发起语音对话");

break;

case BUS_EVT_CMD_STOP:

audio_player_stop();

audio_set_state(AUDIO_IDLE);

speaker_ui_status("已停止");

break;

case BUS_EVT_CMD_VOL_UP:

audio_volume_up();

break;

case BUS_EVT_CMD_VOL_DOWN:

audio_volume_down();

break;

case BUS_EVT_CMD_BT_MODE:

audio_route_set_bt_mode(true);

break;

case BUS_EVT_AI_JSON:

ai_parse_json((char *)evt->payload);

free(evt->payload);

break;

case BUS_EVT_OTA_NOTIFY:

ota_start((char *)evt->payload);

free(evt->payload);

break;

default:

break;

}

}

void app_dispatch_task(void *arg)

{

QueueHandle_t q = app_bus_queue();

bus_evt_t evt;

while (1) {

if (xQueueReceive(q, &evt, portMAX_DELAY) == pdTRUE) {

app_handle_event(&evt);

}

}

}


15. app_main.c

复制代码

void app_main(void)

{

nvs_flash_init();

app_bus_init();

board_init();

speaker_ui_init();

speaker_ui_status("四博 AI 智能音箱启动中...");

audio_route_init();

wifi_port_init();

ble_provision_init();

modem_4g_init();

vb6824_port_init();

ota_service_init();

xTaskCreate(app_dispatch_task, "app_dispatch", 8192, NULL, 8, NULL);

xTaskCreate(vb6824_task, "vb6824_task", 4096, NULL, 7, NULL);

wifi_connect_saved_profile();

ble_provision_start();

modem_4g_probe_basic();

speaker_ui_status("正在连接 Wi-Fi / 4G...");

}


16. sdkconfig.defaults

复制代码

CONFIG_IDF_TARGET="esp32s3"

CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

CONFIG_SPIRAM=y

CONFIG_SPIRAM_USE_MALLOC=y

CONFIG_SPIRAM_SPEED_80M=y

CONFIG_FREERTOS_HZ=1000

CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192

CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10

CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32

CONFIG_ESP_WIFI_TX_BUFFER_TYPE_DYNAMIC=y

CONFIG_LWIP_TCP_SND_BUF_DEFAULT=8192

CONFIG_LWIP_TCP_WND_DEFAULT=8192

CONFIG_LWIP_TCP_RECVMBOX_SIZE=16

CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384

CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096

CONFIG_BT_ENABLED=y

CONFIG_BT_NIMBLE_ENABLED=y

CONFIG_LWIP_PPP_SUPPORT=y

CONFIG_PPP_SUPPORT=y


17. 总结

四博 AI 智能音箱 4G S3 版本的关键不是"能播放声音",而是构建一套稳定的 AI 语音终端架构:

复制代码

ESP32-S3:系统主控、三模联网、AI 协议、OTA

VB6824:远场唤醒、AEC、离线命令、高噪声识别

Wi-Fi:家庭和固定场景主网络

4G:户外、门店、展厅兜底网络

BLE:小程序配网、绑定、控制

WebSocket:AI 长连接、TTS、工具调用

外置蓝牙音频芯片:扩展传统蓝牙音箱能力

这套架构适合 AI 音箱、厨房语音助手、户外便携音箱、门店讲解终端、展厅接待设备和 B 端定制语音硬件。

相关推荐
薛定猫AI2 小时前
【深度解析】Gemma Chat 本地 AI 编程 Agent:Electron + MLX + 开源模型的离线 Vibe Coding 实战
javascript·人工智能·electron
txg6662 小时前
MDVul:用语义路径重塑漏洞检测的图模型能力
人工智能·安全·网络安全
人工智能培训2 小时前
工程科研中的AI应用:结构力学分析技巧
人工智能·深度学习·机器学习·docker·容器
qq_411262422 小时前
四博 AI 智能音箱 4G S3 版本工程方案:三模联网、远场唤醒、AI 会话与打断架构设计
人工智能·智能音箱
风落无尘2 小时前
Claude Code 常用命令速查手册
人工智能
努力努力再努力FFF2 小时前
律师想了解AI法律咨询工具,能否用它提升案件检索效率?
大数据·人工智能
极智视界2 小时前
分类数据集 - 自然灾害场景飓风野火洪水地震分类数据集下载
人工智能·yolo·数据集·图像分类·算法训练·自然灾害检测
GlobalInfo2 小时前
全球人工智能停车机器人市场份额、规模、技术研究报告2026
人工智能·机器人
XD7429716363 小时前
科技早报|2026年4月30日:AI 基础设施竞赛继续升温
人工智能·科技·科技新闻·科技早报