news 2026/5/13 1:25:04

基于 ESP32-S3 的四博 AI 墨水屏智能音箱方案:CozyLife、Find My、Google 防丢与 MCP 工具控制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 ESP32-S3 的四博 AI 墨水屏智能音箱方案:CozyLife、Find My、Google 防丢与 MCP 工具控制

一、项目背景

传统智能音箱主要解决两个问题:语音交互和音频播放。
但如果产品只停留在“语音 + 喇叭”层面,差异化会比较弱。

本文整理一套基于ESP32-S3 + CozyLife + 墨水屏 + Apple Find My + Google 防丢 + AI 大模型的四博 AI 智能音箱方案。

整体方案可以抽象为:

ESP32-S3 AI 音箱主控 + CozyLife APP / 小程序控制 + 墨水屏低功耗常显 + Apple Find My 防丢 + Google 防丢 + AI 大模型语音交互 + 声音克隆 / 声纹识别 + MCP 自然语言工具调用 + OTA / 产测 / 低功耗策略 = 四博 AI 墨水屏双防丢智能音箱

该产品不是普通音箱,而是一个融合了智能家居控制、AI 陪伴、墨水屏状态显示、防丢提醒、低功耗常显的桌面 AIoT 终端。


二、产品功能定义

1. AI 智能音箱能力

1. 语音唤醒 2. AI 大模型对话 3. 连续对话 4. 实时打断 5. TTS 语音播报 6. 声音克隆 7. 声纹识别 8. 蓝牙音箱 9. 闹钟 / 日程 / 提醒

2. CozyLife 智能家居能力

1. APP / 小程序绑定 2. 远程控制 3. 定时任务 4. 群组控制 5. 场景联动 6. 设备状态上报 7. 智能音箱语音控制

3. 墨水屏显示能力

1. 时间 / 日期 2. 天气 / 温湿度 3. AI 对话摘要 4. 日程 / 闹钟 5. CozyLife 场景状态 6. Find My 绑定状态 7. Google 防丢绑定状态 8. 防丢电量 / 遗失模式 9. 配网二维码 / 设备二维码

4. 双系统防丢能力

1. Apple Find My 防丢 2. Google 防丢 3. 本地蜂鸣器寻物 4. 低电量提醒 5. 遗失状态提醒 6. CozyLife 端状态同步 7. 墨水屏常显防丢状态 8. 语音播报防丢状态

三、系统总体架构

┌────────────────────────────────────────────────────┐ │ 四博 AI 墨水屏双防丢智能音箱 │ ├────────────────────────────────────────────────────┤ │ 交互层 │ │ ├─ 麦克风:语音采集 │ │ ├─ 喇叭:TTS / 蓝牙音乐 / 提示音 │ │ ├─ 墨水屏:时间 / 场景 / 防丢状态 / 二维码 │ │ ├─ 按键:唤醒 / 音量 / 翻页 / 配网 │ │ ├─ RGB 灯:网络 / AI / 防丢状态提示 │ │ └─ 蜂鸣器:本地寻物提醒 │ ├────────────────────────────────────────────────────┤ │ 主控层 │ │ ├─ ESP32-S3:AI、Wi-Fi、BLE、I2S、SPI、UART │ │ ├─ VB6824:离线唤醒、离线命令、打断 │ │ ├─ ES8311 / I2S Codec:音频采集与播放 │ │ ├─ E-Paper Driver:墨水屏驱动 │ │ └─ Power Manager:电源与低功耗管理 │ ├────────────────────────────────────────────────────┤ │ 防丢层 │ │ ├─ Find My / Google 双系统防丢模块 │ │ ├─ BLE 广播 / 平台协议 │ │ ├─ 密钥 / Token / 安全存储 │ │ └─ UART / I2C 与 ESP32-S3 通信 │ ├────────────────────────────────────────────────────┤ │ 固件层 │ │ ├─ app_event_bus:事件总线 │ │ ├─ audio_mgr:音频采集 / 播放 │ │ ├─ ai_ws_client:AI WebSocket │ │ ├─ epaper_ui:墨水屏页面管理 │ │ ├─ cozy_cloud:CozyLife 云端同步 │ │ ├─ tag_bridge:防丢模块通信 │ │ ├─ mcp_tools:自然语言工具控制 │ │ ├─ ota_mgr:OTA 升级 │ │ └─ factory_test:产测 │ ├────────────────────────────────────────────────────┤ │ 云端 / APP 层 │ │ ├─ CozyLife APP / 小程序 │ │ ├─ AI Gateway:ASR / LLM / TTS / Voice Clone │ │ ├─ RAG 知识库 │ │ ├─ MCP 工具服务 │ │ └─ Apple / Google 防丢平台 │ └────────────────────────────────────────────────────┘

四、硬件设计建议

1. 主控选择

推荐使用ESP32-S3 N16R8 / N16R2

原因如下:

1. 双核 240MHz,适合多任务调度 2. GPIO 资源充足,可以挂接 I2S、SPI、UART、按键、RGB、蜂鸣器 3. 支持 Wi-Fi + BLE 4. 支持 PSRAM,适合音频缓存、墨水屏 UI 缓存、WebSocket 数据流 5. 适合 AI 音频、智能家居和显示类产品

2. 双防丢模块设计

Apple Find My 和 Google 防丢属于平台认证生态,量产时不建议直接在 ESP32-S3 主控中实现完整协议。

推荐结构如下:

ESP32-S3: 负责 AI、CozyLife、墨水屏、音频、按键、MCP、OTA。 独立防丢模块: 负责 Apple Find My / Google 防丢协议、BLE 广播、密钥存储和低功耗运行。 通信方式: ESP32-S3 与防丢模块通过 UART / I2C 通信。

这种方式的好处:

1. 平台认证边界清晰 2. 防丢协议和主控业务解耦 3. 防丢模块可独立升级 4. 主控固件维护更简单 5. 同一套 ESP32-S3 主板可适配不同防丢 SKU

3. 推荐 BOM

模块推荐方案说明
主控ESP32-S3 N16R8AI、Wi-Fi、BLE、音频、墨水屏
语音模块VB6824离线唤醒、离线命令、打断
CodecES8311 / I2S Codec麦克风采集、喇叭播放
功放3W~5W D 类功放音箱播放
墨水屏2.13 / 2.9 / 3.7 寸低功耗常显
防丢模块Find My + Google 双系统模块独立认证协议
蜂鸣器80dB~100dB寻物提醒
RGBWS2812 / PWM RGB状态提示
电源Type-C + 锂电池可选桌面 / 便携
存储16MB Flash + 8MB PSRAMUI、音频缓存、OTA

五、工程目录设计

sibo_ai_epaper_speaker/ ├── CMakeLists.txt ├── sdkconfig.defaults ├── partitions.csv ├── main/ │ ├── app_main.c │ ├── app_config.h │ ├── board_pins.h │ ├── app_event_bus.c │ ├── app_event_bus.h │ ├── key_mgr.c │ ├── audio_mgr.c │ ├── ai_ws_client.c │ ├── epaper_ui.c │ ├── cozy_cloud.c │ ├── tag_bridge.c │ ├── tag_bridge.h │ ├── mcp_tools.c │ ├── power_mgr.c │ ├── ota_mgr.c │ └── factory_test.c ├── components/ │ ├── epaper_driver/ │ ├── audio_codec/ │ ├── json_parser/ │ ├── qr_render/ │ └── font_assets/ └── server/ ├── ai_gateway.py ├── mcp_server.py └── cozy_bridge.py

六、基础配置代码

app_config.h

#pragma once #define PRODUCT_NAME "SIBO_AI_EPAPER_SPEAKER" #define FIRMWARE_VERSION "v1.0.0" /* 功能开关 */ #define ENABLE_WIFI 1 #define ENABLE_BLE 1 #define ENABLE_BLUFI 1 #define ENABLE_COZYLIFE 1 #define ENABLE_AI_ASSISTANT 1 #define ENABLE_EPAPER 1 #define ENABLE_FINDMY_GOOGLE_TAG 1 #define ENABLE_MCP 1 #define ENABLE_OTA 1 /* 音频参数 */ #define AUDIO_SAMPLE_RATE 16000 #define AUDIO_BITS_PER_SAMPLE 16 #define AUDIO_FRAME_MS 20 #define AUDIO_FRAME_SAMPLES (AUDIO_SAMPLE_RATE * AUDIO_FRAME_MS / 1000) /* 云端服务 */ #define AI_WS_URL "wss://your-ai-gateway.example.com/device/ws" #define COZY_DEVICE_TYPE "ai_epaper_speaker" /* 墨水屏参数 */ #define EPAPER_WIDTH 296 #define EPAPER_HEIGHT 128 /* 防丢模块通信参数 */ #define TAG_UART_BAUD 115200 #define TAG_QUERY_INTERVAL_MS 5000 /* 音量 */ #define DEFAULT_VOLUME 45 #define MAX_VOLUME 100

board_pins.h

#pragma once #include "driver/gpio.h" /* I2S 音频 */ #define PIN_I2S_BCLK GPIO_NUM_4 #define PIN_I2S_WS GPIO_NUM_5 #define PIN_I2S_DIN_MIC GPIO_NUM_6 #define PIN_I2S_DOUT_SPK GPIO_NUM_7 /* 墨水屏 SPI */ #define PIN_EPAPER_SCLK GPIO_NUM_12 #define PIN_EPAPER_MOSI GPIO_NUM_13 #define PIN_EPAPER_CS GPIO_NUM_14 #define PIN_EPAPER_DC GPIO_NUM_15 #define PIN_EPAPER_RST GPIO_NUM_16 #define PIN_EPAPER_BUSY GPIO_NUM_17 /* 防丢模块 UART */ #define PIN_TAG_UART_TX GPIO_NUM_18 #define PIN_TAG_UART_RX GPIO_NUM_19 /* 蜂鸣器 / RGB */ #define PIN_BUZZER_PWM GPIO_NUM_21 #define PIN_RGB_LED GPIO_NUM_48 /* 按键 */ #define PIN_KEY_WAKE GPIO_NUM_38 #define PIN_KEY_VOL_UP GPIO_NUM_39 #define PIN_KEY_VOL_DOWN GPIO_NUM_40 #define PIN_KEY_PAGE GPIO_NUM_41

七、分区表设计

# partitions.csv # Name, Type, SubType, Offset, Size nvs, data, nvs, 0x9000, 0x6000 otadata, data, ota, 0xf000, 0x2000 phy_init, data, phy, 0x11000, 0x1000 factory, app, factory, 0x20000, 3M ota_0, app, ota_0, , 3M ota_1, app, ota_1, , 3M assets, data, spiffs, , 4M storage, data, nvs, , 0x10000

八、事件总线设计

设备中有多个模块:AI、CozyLife、墨水屏、防丢模块、按键、OTA。为了避免模块之间直接耦合,可以使用事件总线。

app_event_bus.h

#pragma once #include <stdint.h> #include "freertos/FreeRTOS.h" #include "freertos/queue.h" typedef enum { EVT_KEY_WAKE, EVT_KEY_WAKE_LONG, EVT_KEY_VOL_UP, EVT_KEY_VOL_DOWN, EVT_KEY_PAGE, EVT_AI_IDLE, EVT_AI_LISTENING, EVT_AI_THINKING, EVT_AI_SPEAKING, EVT_AI_INTERRUPTED, EVT_COZY_ONLINE, EVT_COZY_OFFLINE, EVT_COZY_SCENE_CHANGED, EVT_EPAPER_REFRESH, EVT_EPAPER_SHOW_QR, EVT_EPAPER_NEXT_PAGE, EVT_TAG_FINDMY_BOUND, EVT_TAG_GOOGLE_BOUND, EVT_TAG_LOST_MODE, EVT_TAG_NEARBY, EVT_TAG_LOW_BAT, EVT_TAG_BUZZER_ON, EVT_TAG_BUZZER_OFF, EVT_OTA_START, EVT_OTA_DONE, EVT_OTA_FAIL, } app_evt_type_t; typedef struct { app_evt_type_t type; int32_t value; int64_t ts_ms; } app_evt_t; void app_event_bus_init(void); QueueHandle_t app_event_bus_register(const char *name, uint32_t len); void app_event_post(app_evt_type_t type, int32_t value);

app_event_bus.c

#include <string.h> #include "esp_timer.h" #include "app_event_bus.h" #define SUB_MAX 12 typedef struct { char name[24]; QueueHandle_t q; } app_sub_t; static app_sub_t s_subs[SUB_MAX]; static int s_sub_count = 0; void app_event_bus_init(void) { memset(s_subs, 0, sizeof(s_subs)); s_sub_count = 0; } QueueHandle_t app_event_bus_register(const char *name, uint32_t len) { if (s_sub_count >= SUB_MAX) { return NULL; } QueueHandle_t q = xQueueCreate(len, sizeof(app_evt_t)); if (!q) { return NULL; } strncpy(s_subs[s_sub_count].name, name, sizeof(s_subs[s_sub_count].name) - 1); s_subs[s_sub_count].q = q; s_sub_count++; return q; } void app_event_post(app_evt_type_t type, int32_t value) { app_evt_t evt = { .type = type, .value = value, .ts_ms = esp_timer_get_time() / 1000 }; for (int i = 0; i < s_sub_count; i++) { if (s_subs[i].q) { xQueueSend(s_subs[i].q, &evt, 0); } } }

九、主程序入口

#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "app_config.h" #include "app_event_bus.h" extern void key_mgr_start(void); extern void audio_mgr_start(void); extern void ai_ws_client_start(void); extern void epaper_ui_start(void); extern void cozy_cloud_start(void); extern void tag_bridge_start(void); extern void mcp_tools_start(void); extern void ota_mgr_start(void); extern void power_mgr_start(void); static const char *TAG = "app_main"; void app_main(void) { ESP_LOGI(TAG, "boot %s %s", PRODUCT_NAME, FIRMWARE_VERSION); app_event_bus_init(); key_mgr_start(); audio_mgr_start(); power_mgr_start(); #if ENABLE_EPAPER epaper_ui_start(); #endif #if ENABLE_COZYLIFE cozy_cloud_start(); #endif #if ENABLE_FINDMY_GOOGLE_TAG tag_bridge_start(); #endif #if ENABLE_AI_ASSISTANT ai_ws_client_start(); #endif #if ENABLE_MCP mcp_tools_start(); #endif #if ENABLE_OTA ota_mgr_start(); #endif while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); } }

十、双防丢模块通信协议设计

ESP32-S3 与防丢模块通过 UART 通信,防丢模块内部负责 Find My / Google 协议栈。

Frame: +--------+--------+------+-----+----------+------+ | 0x55 | 0xAA | LEN | CMD | PAYLOAD | XOR | +--------+--------+------+-----+----------+------+ CMD: 0x01 查询状态 0x02 启动蜂鸣器 0x03 停止蜂鸣器 0x04 查询绑定状态 0x05 查询电量 0x06 进入配对模式 Event: 0x81 Find My 已绑定 0x82 Google 已绑定 0x83 低电量 0x84 遗失模式 0x85 附近找到

tag_bridge.h

#pragma once #include <stdint.h> #include <stdbool.h> typedef enum { TAG_BIND_NONE = 0, TAG_BIND_FINDMY = 1 << 0, TAG_BIND_GOOGLE = 1 << 1, } tag_bind_mask_t; typedef struct { uint8_t bind_mask; uint8_t battery_percent; bool lost_mode; bool buzzer_on; int8_t rssi; } tag_status_t; void tag_bridge_start(void); void tag_query_status(void); void tag_start_buzzer(void); void tag_stop_buzzer(void); void tag_enter_pair_mode(void); bool tag_get_status(tag_status_t *out);

tag_bridge.c

#include <string.h> #include "driver/uart.h" #include "esp_log.h" #include "board_pins.h" #include "app_config.h" #include "app_event_bus.h" #include "tag_bridge.h" #define TAG_UART_NUM UART_NUM_1 #define TAG_RX_BUF_SIZE 512 #define TAG_CMD_QUERY_STATUS 0x01 #define TAG_CMD_BUZZER_ON 0x02 #define TAG_CMD_BUZZER_OFF 0x03 #define TAG_CMD_PAIR_MODE 0x06 #define TAG_EVT_FINDMY_BOUND 0x81 #define TAG_EVT_GOOGLE_BOUND 0x82 #define TAG_EVT_LOW_BAT 0x83 #define TAG_EVT_LOST_MODE 0x84 #define TAG_EVT_NEARBY 0x85 static const char *TAG = "tag_bridge"; static tag_status_t s_status; static uint8_t calc_xor(const uint8_t *buf, int len) { uint8_t x = 0; for (int i = 0; i < len; i++) { x ^= buf[i]; } return x; } static void tag_send_cmd(uint8_t cmd, const uint8_t *payload, uint8_t payload_len) { uint8_t frame[64]; int idx = 0; frame[idx++] = 0x55; frame[idx++] = 0xAA; frame[idx++] = payload_len + 1; frame[idx++] = cmd; if (payload && payload_len > 0) { memcpy(&frame[idx], payload, payload_len); idx += payload_len; } frame[idx] = calc_xor(frame, idx); idx++; uart_write_bytes(TAG_UART_NUM, (const char *)frame, idx); } void tag_query_status(void) { tag_send_cmd(TAG_CMD_QUERY_STATUS, NULL, 0); } void tag_start_buzzer(void) { tag_send_cmd(TAG_CMD_BUZZER_ON, NULL, 0); s_status.buzzer_on = true; app_event_post(EVT_TAG_BUZZER_ON, 0); } void tag_stop_buzzer(void) { tag_send_cmd(TAG_CMD_BUZZER_OFF, NULL, 0); s_status.buzzer_on = false; app_event_post(EVT_TAG_BUZZER_OFF, 0); } void tag_enter_pair_mode(void) { tag_send_cmd(TAG_CMD_PAIR_MODE, NULL, 0); } bool tag_get_status(tag_status_t *out) { if (!out) { return false; } memcpy(out, &s_status, sizeof(tag_status_t)); return true; }

事件解析:

static void tag_handle_event(uint8_t cmd, const uint8_t *payload, int len) { switch (cmd) { case TAG_EVT_FINDMY_BOUND: s_status.bind_mask |= TAG_BIND_FINDMY; app_event_post(EVT_TAG_FINDMY_BOUND, 1); break; case TAG_EVT_GOOGLE_BOUND: s_status.bind_mask |= TAG_BIND_GOOGLE; app_event_post(EVT_TAG_GOOGLE_BOUND, 1); break; case TAG_EVT_LOW_BAT: s_status.battery_percent = len > 0 ? payload[0] : 0; app_event_post(EVT_TAG_LOW_BAT, s_status.battery_percent); break; case TAG_EVT_LOST_MODE: s_status.lost_mode = true; app_event_post(EVT_TAG_LOST_MODE, 1); break; case TAG_EVT_NEARBY: s_status.lost_mode = false; app_event_post(EVT_TAG_NEARBY, 1); break; default: ESP_LOGW(TAG, "unknown tag event: 0x%02X", cmd); break; } }

十一、墨水屏 UI 设计

墨水屏适合做低功耗常显,建议设计多个页面:

Page 0:首页 - 时间 - 日期 - 天气 - AI 状态 - CozyLife 在线状态 Page 1:防丢状态页 - Find My 已绑定 / 未绑定 - Google 已绑定 / 未绑定 - 防丢电量 - 遗失模式 - 蜂鸣器状态 Page 2:智能家居页 - 当前场景 - 房间温湿度 - 设备数量 - 回家 / 离家模式 Page 3:AI 摘要页 - 用户问题摘要 - AI 回复摘要 - 当前模型 Page 4:配网页 - CozyLife 绑定二维码 - BluFi 配网提示

epaper_ui.c 核心状态

typedef enum { EPAPER_PAGE_HOME = 0, EPAPER_PAGE_TAG, EPAPER_PAGE_COZY, EPAPER_PAGE_AI, EPAPER_PAGE_QR, EPAPER_PAGE_MAX, } epaper_page_t; static QueueHandle_t s_epaper_q; static epaper_page_t s_page = EPAPER_PAGE_HOME; static char s_ai_summary[128] = "Hello, I am Sibo AI."; static char s_cozy_scene[64] = "Home"; static bool s_cozy_online = false;

防丢页面绘制:

static void draw_tag_page(void) { tag_status_t st; char line[64]; tag_get_status(&st); epaper_clear(); epaper_draw_text(0, 0, "Anti-Lost Status"); snprintf(line, sizeof(line), "Find My: %s", (st.bind_mask & TAG_BIND_FINDMY) ? "Bound" : "Unbound"); epaper_draw_text(0, 24, line); snprintf(line, sizeof(line), "Google: %s", (st.bind_mask & TAG_BIND_GOOGLE) ? "Bound" : "Unbound"); epaper_draw_text(0, 44, line); snprintf(line, sizeof(line), "Battery: %d%%", st.battery_percent); epaper_draw_text(0, 64, line); snprintf(line, sizeof(line), "Lost: %s", st.lost_mode ? "YES" : "NO"); epaper_draw_text(0, 84, line); epaper_update(); }

页面切换:

static void epaper_task(void *arg) { app_evt_t evt; while (1) { if (xQueueReceive(s_epaper_q, &evt, portMAX_DELAY)) { switch (evt.type) { case EVT_KEY_PAGE: case EVT_EPAPER_NEXT_PAGE: s_page++; if (s_page >= EPAPER_PAGE_MAX) { s_page = EPAPER_PAGE_HOME; } epaper_draw_page(); break; case EVT_TAG_FINDMY_BOUND: case EVT_TAG_GOOGLE_BOUND: case EVT_TAG_LOW_BAT: case EVT_TAG_LOST_MODE: if (s_page == EPAPER_PAGE_TAG) { epaper_draw_page(); } break; case EVT_EPAPER_SHOW_QR: s_page = EPAPER_PAGE_QR; epaper_draw_page(); break; default: break; } } } }

十二、CozyLife 状态模型

AI 音箱可以作为 CozyLife 生态中的“显示 + 语音 + 防丢状态聚合终端”。

typedef struct { char device_id[32]; bool online; int volume; bool ai_enabled; bool findmy_bound; bool google_bound; bool lost_mode; int tag_battery; char epaper_page[16]; char scene_name[32]; } cozy_shadow_t;

生成上报 JSON:

static char *cozy_build_status_json(void) { cJSON *root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "device_id", s_shadow.device_id); cJSON_AddBoolToObject(root, "online", s_shadow.online); cJSON_AddNumberToObject(root, "volume", s_shadow.volume); cJSON_AddBoolToObject(root, "ai_enabled", s_shadow.ai_enabled); cJSON_AddBoolToObject(root, "findmy_bound", s_shadow.findmy_bound); cJSON_AddBoolToObject(root, "google_bound", s_shadow.google_bound); cJSON_AddBoolToObject(root, "lost_mode", s_shadow.lost_mode); cJSON_AddNumberToObject(root, "tag_battery", s_shadow.tag_battery); cJSON_AddStringToObject(root, "epaper_page", s_shadow.epaper_page); cJSON_AddStringToObject(root, "scene_name", s_shadow.scene_name); char *json = cJSON_PrintUnformatted(root); cJSON_Delete(root); return json; }

解析 APP 命令:

static void cozy_handle_cmd(const char *json) { cJSON *root = cJSON_Parse(json); if (!root) { return; } cJSON *cmd = cJSON_GetObjectItem(root, "cmd"); if (!cJSON_IsString(cmd)) { cJSON_Delete(root); return; } if (!strcmp(cmd->valuestring, "show_qr")) { app_event_post(EVT_EPAPER_SHOW_QR, 0); } else if (!strcmp(cmd->valuestring, "next_page")) { app_event_post(EVT_EPAPER_NEXT_PAGE, 0); } else if (!strcmp(cmd->valuestring, "find_device")) { tag_start_buzzer(); } else if (!strcmp(cmd->valuestring, "stop_find_device")) { tag_stop_buzzer(); } else if (!strcmp(cmd->valuestring, "enter_pair_mode")) { tag_enter_pair_mode(); } cJSON_Delete(root); }

十三、MCP 自然语言控制

MCP 用来把自然语言转换成设备动作。

比如:

用户说:帮我找一下音箱 执行:find_speaker 用户说:显示防丢状态 执行:show_tag_status 用户说:显示配网二维码 执行:show_qr

工具注册:

static void mcp_register_tools(void) { mcp_send_at("AT"); mcp_send_at("AT+CONNECT"); mcp_send_at("AT+ADDMCP=0,show_home,显示首页,2,E1,00"); mcp_send_at("AT+ADDMCP=0,show_tag_status,显示防丢状态,2,E1,01"); mcp_send_at("AT+ADDMCP=0,show_qr,显示配网二维码,2,E1,02"); mcp_send_at("AT+ADDMCP=0,find_speaker,查找音箱,2,F1,01"); mcp_send_at("AT+ADDMCP=0,stop_find_speaker,停止查找音箱,2,F1,00"); mcp_send_at("AT+ADDMCP=1,set_volume,设置音量,F2,1,V"); mcp_send_at("AT+ADDMCP=0,scene_home,打开回家模式,2,F3,01"); }

命令解析:

static void handle_mcp_frame(const uint8_t *buf, int len) { if (len < 5) { return; } if (buf[0] != 0x55 || buf[1] != 0xAA) { return; } switch (buf[3]) { case 0xE1: if (buf[4] == 0x00) { app_event_post(EVT_EPAPER_REFRESH, 0); } else if (buf[4] == 0x01) { app_event_post(EVT_EPAPER_NEXT_PAGE, 1); } else if (buf[4] == 0x02) { app_event_post(EVT_EPAPER_SHOW_QR, 0); } break; case 0xF1: if (buf[4] == 0x01) { tag_start_buzzer(); } else { tag_stop_buzzer(); } break; case 0xF3: app_event_post(EVT_COZY_SCENE_CHANGED, buf[4]); break; default: break; } }

十四、AI WebSocket 客户端

设备端和 AI 网关通信,接收状态并驱动本地 UI。

static void ai_handle_json(const char *data, int len) { cJSON *root = cJSON_ParseWithLength(data, len); if (!root) { return; } cJSON *type = cJSON_GetObjectItem(root, "type"); if (cJSON_IsString(type)) { if (!strcmp(type->valuestring, "idle")) { app_event_post(EVT_AI_IDLE, 0); } else if (!strcmp(type->valuestring, "listening")) { app_event_post(EVT_AI_LISTENING, 0); } else if (!strcmp(type->valuestring, "thinking")) { app_event_post(EVT_AI_THINKING, 0); } else if (!strcmp(type->valuestring, "speaking")) { app_event_post(EVT_AI_SPEAKING, 0); } } cJSON_Delete(root); }

连接成功后上报设备信息:

esp_websocket_client_send_text( s_ws, "{\"type\":\"hello\",\"product\":\"SIBO_AI_EPAPER_SPEAKER\"}", strlen("{\"type\":\"hello\",\"product\":\"SIBO_AI_EPAPER_SPEAKER\"}"), portMAX_DELAY );

十五、后端 AI 网关示例

from fastapi import FastAPI, WebSocket from typing import Optional app = FastAPI(title="SIBO AI Epaper Speaker Gateway") @app.websocket("/device/ws") async def device_ws(ws: WebSocket): await ws.accept() await ws.send_json({"type": "idle", "msg": "device connected"}) while True: msg = await ws.receive() if "bytes" in msg and msg["bytes"]: pcm = msg["bytes"] text = asr_decode(pcm) if text: await ws.send_json({"type": "thinking", "text": text}) tool = parse_tool_intent(text) answer = llm_reply(text) if tool: await ws.send_json({ "type": "tool", "tool": tool["name"], "args": tool.get("args", {}) }) await ws.send_json({"type": "speaking", "text": answer}) await ws.send_json({"type": "idle"}) def asr_decode(pcm: bytes) -> Optional[str]: return None def parse_tool_intent(text: str) -> Optional[dict]: if "找音箱" in text or "帮我找" in text: return {"name": "find_speaker"} if "防丢状态" in text: return {"name": "show_tag_status"} if "二维码" in text: return {"name": "show_qr"} if "回家模式" in text: return {"name": "scene_home"} return None def llm_reply(text: str) -> str: return "好的,已为你处理。"

十六、CozyLife APP 配置 JSON

{ "device_id": "sibo_epaper_speaker_001", "name": "四博AI墨水屏音箱", "type": "ai_epaper_speaker", "features": { "ai": true, "epaper": true, "findmy": true, "google_finder": true, "bluetooth_speaker": true, "voice_clone": true, "voiceprint": true }, "state": { "online": true, "volume": 45, "epaper_page": "home", "findmy_bound": true, "google_bound": true, "lost_mode": false, "tag_battery": 86 }, "actions": [ "show_home", "show_tag_status", "show_qr", "find_speaker", "stop_find_speaker", "set_volume", "scene_home", "scene_sleep" ] }

十七、低功耗设计

1. 墨水屏只在状态变化时刷新 2. AI 空闲时降低麦克风采样频率 3. 防丢模块独立低功耗运行 4. ESP32-S3 根据供电状态进入 light sleep 5. Wi-Fi 低频上报 CozyLife 状态 6. Find My / Google 广播由独立防丢模块负责 7. 蜂鸣器只在寻物时工作 8. OTA 和墨水屏全刷避免同时执行

十八、量产测试

1. 麦克风采集测试 2. 喇叭播放测试 3. 墨水屏黑白刷新测试 4. 按键测试 5. RGB 灯测试 6. 防丢模块 UART 通信测试 7. Find My 绑定状态检测 8. Google 绑定状态检测 9. 蜂鸣器测试 10. Wi-Fi RSSI 测试 11. BLE 广播测试 12. SN 写入 13. 证书写入 14. OTA 测试

十九、总结

这套四博 AI 墨水屏双防丢智能音箱方案,核心不是简单地把一个音箱接入网络,而是把多个能力整合到一个桌面 AI 终端中:

AI 大模型语音交互 + CozyLife APP / 小程序控制 + 墨水屏低功耗常显 + 蓝牙音箱 + 闹钟提醒 + 声音克隆 + 声纹识别 + Apple Find My 防丢 + Google 防丢 + MCP 自然语言控制

推荐的量产架构是:

ESP32-S3: 负责 AI、CozyLife、墨水屏、音频和系统逻辑。 独立防丢模块: 负责 Apple Find My / Google 防丢协议和 BLE 广播。 CozyLife APP: 负责用户配置、状态查看、场景联动和设备管理。 AI 后端: 负责语音理解、TTS、声音克隆、RAG 和 MCP 工具调用。

这种架构的优势是:功能边界清晰、认证风险低、固件维护简单、后续 SKU 扩展方便

对于智能音箱、桌面 AI 助手、家庭中控、品牌 IP 硬件和防丢设备融合类产品来说,ESP32-S3 + 墨水屏 + CozyLife + 双防丢模块 + AI 大模型是一个非常适合落地的产品方向

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 1:20:06

是德科技 安捷伦 Agilent 16089C 夹子测试夹具Keysight 16089C

Agilent 16089C是安捷伦&#xff08;Agilent&#xff09;生产的电桥夹具治具&#xff0c;主要用于半导体测试领域&#xff0c;可兼容多种阻抗分析仪型号。以下是详细信息&#xff1a;主要特性 ‌兼容设备‌&#xff1a;适用于Keysight 4192A、4194A&#xff08;阻抗模式&#x…

作者头像 李华
网站建设 2026/5/13 1:19:07

国央企如何高效推进技术创新与成果转化?

观点作者&#xff1a;科易网-国家科技成果转化&#xff08;厦门&#xff09;示范基地 一、现状概述&#xff1a;成效与短板 近年来&#xff0c;国央企在国家创新体系中扮演着关键角色&#xff0c;在重大科技攻关、产业升级和基础设施建设等领域取得了显著成就。然而&#xff0c…

作者头像 李华
网站建设 2026/5/13 1:12:05

【智慧社区实战】2026 门禁行业分水岭:不做“认得出”的机器,要做“懂你”的智能体

摘要 当人脸识别精度触及99.9%的天花板&#xff0c;门禁赛道的下一程拼什么&#xff1f;本文基于济南老旧小区真实改造案例&#xff0c;分享一套从“认得出”到“懂你要干什么”的门禁系统设计思路。涵盖4G免布线部署、多模态意图感知、场景模板引擎、适老化交互、鲁通码接入&a…

作者头像 李华