四博皮克斯苹果 AI 台灯 / AI 智能音箱 S3 视觉机械臂方案

According to a document from 2026-04-24,下面按"四博皮克斯苹果 AI 台灯 + AI 智能音箱一体化 S3 视觉机械臂版本 "来写方案:它不是单纯音箱,而是把 AI 音箱的语音交互能力AI 台灯的照明能力机械臂动作能力摄像头视觉能力大模型 / 多模态模型能力 合成一个可开源、可量产、可二次开发的平台。若客户只做纯 AI 智能音箱,可直接去掉机械臂、摄像头、灯光恒流驱动部分,保留 S3 + VB6824 + 屏幕 + 喇叭 + 联网 + MCP 即可。方案依据你上传的四博乐鑫系模组选型手册、AI 硬件选型表和《四博智联 AI 开发宝典》整理。

四博皮克斯苹果 AI 台灯 / AI 智能音箱 S3 视觉机械臂方案

1. 方案定位

本方案定位为 "AI 视觉台灯 + 智能音箱 + 机械臂执行器 + 屏幕交互终端",核心采用:

复制代码
ESP32-S3R8 + 16M Flash + 8M PSRAM
VB6824 离线语音 / AEC / 唤醒前端
摄像头模组
机械臂 / 云台舵机
LED 台灯恒流驱动
单屏 / 双屏 / 异显屏幕
喇叭 + 功放
Wi-Fi / BLE / 4G / 蓝牙 PAN 可选
小智 / 豆包 / ChatGPT / Coze / 客户私有大模型
AT+MCP / WebSocket / HTTP / MQTT / UART 二次开发接口

四博资料中,ESP32-S3 系列被归类到 音视频 / AI 市场 ,ESPS3-32 / ESPS3-32E 兼容官方 S3 系列模组;ESP32-S3 也具备 LCD 支持,适合做带屏 AI 设备主控。 AI 硬件选型表中已经出现 ESP32-S3 + 7014 + 摄像头 + 4G 高端方案 ,并说明其特点是开发者生态好、可对接各家平台、可多模态、可当蓝牙音箱;同时 AI 智能相机方案采用 ESP32S3R8 + 16M Flash + VB6824,可选 4G、摄像头、屏幕、麦克风、喇叭、电池包等配件。

开发宝典中,AI-S3 标准开发板是"四博 AI-Speaker 开发板",带 240×240 分辨率 1.3 寸屏,全开源,支持"四博小助手"小程序、声音克隆、知识库、自建大模型和 MCP。 另外,DOIT_ESPS3_AI_EYE_Vision 多模态开发板基于 ESP32-S3,集摄像头、双目显示和触摸交互于一体,硬件与软件全开源,可直接用于二次开发或量产制造,这一点非常适合"皮克斯苹果 AI 台灯再升级"的视觉版本。


2. 整机系统架构

复制代码
┌────────────────────────────────────────────────────────────┐
│          四博皮克斯苹果 AI 台灯 / AI 智能音箱 S3 版          │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  ┌────────────────────┐       UART / I2C / GPIO            │
│  │ VB6824 语音前端     │◄─────────────────────────────┐     │
│  │ - 离线唤醒           │                              │     │
│  │ - 远场拾音           │                              │     │
│  │ - AEC 回声消除       │                              │     │
│  │ - 高噪降噪           │                              │     │
│  │ - 唤醒词打断         │                              │     │
│  │ - 自定义唤醒词       │                              │     │
│  └─────────┬──────────┘                              │     │
│            │ MIC / 回采音频                           │     │
│                                                       ▼     │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ ESP32-S3R8 + 16M Flash + 8M PSRAM                   │   │
│  │ - Wi-Fi / BLE / BluFi                               │   │
│  │ - 4G PPP / ECM,可选                                │   │
│  │ - 蓝牙 PAN / 蓝牙音箱,可选 7014                    │   │
│  │ - WebSocket AI 对话                                 │   │
│  │ - 摄像头采集 / JPEG 编码                            │   │
│  │ - 视觉大模型请求 / 场景理解                         │   │
│  │ - 舵机 / 机械臂控制                                 │   │
│  │ - 灯光亮度 / 色温控制                               │   │
│  │ - 单屏 / 双屏 / 异显 UI                             │   │
│  │ - MCP 工具扩展 / 客户系统接入                       │   │
│  └───────┬───────────────┬───────────────┬─────────────┘   │
│          │               │               │                 │
│   ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐          │
│   │ Camera       │ │ Servo Arm   │ │ LED Driver  │          │
│   │ 视觉输入      │ │ 云台/机械臂  │ │ 冷暖光/亮度 │          │
│   └─────────────┘ └─────────────┘ └─────────────┘          │
│                                                            │
│   ┌─────────────┐ ┌─────────────┐ ┌────────────────────┐   │
│   │ LCD Screen A │ │ LCD Screen B │ │ I2S AMP + Speaker │   │
│   │ 表情 / 主 UI │ │ 信息 / 异显   │ │ TTS / 音乐 / 提示音 │   │
│   └─────────────┘ └─────────────┘ └────────────────────┘   │
│                                                            │
└────────────────────────────────────────────────────────────┘

云端 / 私有化后端:
┌────────────────────────────────────────────────────────────┐
│ OTA │ WebSocket │ ASR │ LLM │ TTS │ VLM │ MCP │ 客户业务系统 │
└────────────────────────────────────────────────────────────┘

3. 产品核心功能

3.1 AI 音箱能力

复制代码
1. 语音唤醒:
   默认"你好小智"或客户定制唤醒词。

2. 远场拾音:
   通过 VB6824 做语音前端,支持远距离拾音、降噪、唤醒识别。

3. 实时打断:
   AI 播报、蓝牙音乐、提示音播放过程中,用户可唤醒打断。

4. 大模型对话:
   接入小智、豆包、ChatGPT、Coze 或客户自有 LLM。

5. TTS 播放:
   支持标准 TTS、声音克隆、角色音色。

6. MCP 工具:
   可通过语音控制灯光、机械臂、摄像头、屏幕、客户系统。

开发宝典对 VB6824 的描述是:它采用语音识别算法和语音降噪算法,支持更远距离唤醒、更低误唤醒率、更强抗噪能力、更快响应识别时间和免联网离线识别。 自定义唤醒词升级完成后,可支持选定唤醒词,并能在 AI 说话过程中随时打断。

3.2 视觉台灯能力

复制代码
1. 摄像头识别:
   识别桌面、书本、人物、手势、物体位置。

2. 视觉问答:
   用户问"桌上有什么""这道题怎么做""帮我看看书本在哪里",设备拍照并请求视觉大模型。

3. 自动补光:
   根据摄像头亮度估计环境光,自动调节台灯亮度和色温。

4. 机械臂指向:
   根据视觉目标位置,机械臂转向书本、用户、物体或展示区域。

5. 屏幕反馈:
   屏幕显示识别结果、AI 表情、台灯状态、机械臂状态、网络状态。

开发宝典中的多模态方案已经覆盖 摄像头 + 双目显示 + 触摸交互 + 小智云端 / 本地服务,并强调硬件原理图、BOM、固件源码齐全,便于二次开发和量产制造。

3.3 机械臂能力

推荐机械结构:

复制代码
基础版:
  2 自由度云台
  - pan:左右旋转
  - tilt:上下俯仰

增强版:
  3 自由度机械臂
  - base:底座旋转
  - shoulder:大臂俯仰
  - head:灯头角度

高端版:
  3 自由度机械臂 + 限位检测 + 电流保护 + 姿态回零

典型语音指令:

复制代码
"小博,转过来看我"
"把灯光照向书本"
"台灯抬高一点"
"低一点,亮一点"
"看一下桌面上有什么"
"帮我拍一下这张纸"
"切换专注学习模式"

3.4 三种联网能力

复制代码
1. Wi-Fi:
   ESP32-S3 原生 Wi-Fi,用于家庭、办公室、展厅、OTA。

2. BLE / BluFi:
   用于四博小助手小程序配网、绑定设备、参数配置。

3. 4G:
   外接 4G 模组,用于户外、移动、展厅、无 Wi-Fi 环境。

4. 蓝牙 PAN,可选:
   通过 7014 或蓝牙 PAN 模组使用手机网络,适合低成本户外联网。

AI 选型表中,7014 蓝牙 PAN 方案的特点是成本低、可脱离 APP、可通过手机网络通信解决户外网络问题;四博 AI-C5 开发板资料也显示其支持 2.4G / 5G Wi-Fi、4G 模组、喇叭、麦克风、电池和屏幕,可作为三网设计参考。


4. 推荐硬件方案

4.1 主控

复制代码
主控:ESP32-S3R8
模组:ESPS3-32-N16R8 / ESPS3-32E-N16R8
Flash:16MB
PSRAM:8MB
无线:2.4GHz Wi-Fi + BLE
显示:SPI / RGB / I8080 LCD
摄像头:DVP Camera,具体传感器按 BOM 选型

四博乐鑫系手册中,ESPS3-32 提供 N4、N8、N8R2、N16R2、N16R8 等子型号,芯片覆盖 ESP32-S3 / S3R2 / S3R8,ESPS3-32E 则兼容 ESP32-S3-WROOM-1U 系列模组。

4.2 语音与音频

复制代码
语音前端:VB6824
麦克风:单麦 / 双麦,根据结构选型
功放:I2S 数字功放或模拟功放
喇叭:3W / 4Ω 或 5W / 4Ω
回采:功放输出或 I2S 回采给 AEC

4.3 摄像头

复制代码
接口:ESP32-S3 DVP Camera
格式:JPEG / RGB565 / YUV
用途:
  - 拍照上传给视觉模型
  - 桌面物体识别
  - 手势 / 人脸方向检测
  - 机械臂目标定位

4.4 机械臂

复制代码
执行器:
  - PWM 舵机:成本低、控制简单
  - 串口舵机:支持角度反馈和力矩控制
  - 步进电机:定位稳定,适合高端版

保护:
  - 上电回零
  - 角度限幅
  - 堵转检测
  - 低电量禁止大动作
  - 儿童安全限速

4.5 灯光

复制代码
灯光驱动:
  - 冷暖双色 LED
  - 恒流驱动
  - ESP32-S3 PWM 调光

控制参数:
  - brightness:0~100
  - color_temp:2700K~6500K
  - mode:阅读 / 护眼 / 夜灯 / 氛围 / 专注

5. 软件系统架构

复制代码
app_main
 ├── board_init()
 ├── nvs_config_init()
 ├── audio_frontend_start()
 ├── mcp_uart_bridge_start()
 ├── network_policy_start()
 ├── ai_websocket_start()
 ├── camera_service_start()
 ├── vision_ai_service_start()
 ├── servo_arm_start()
 ├── lamp_driver_start()
 ├── display_manager_start()
 ├── ota_manager_start()
 └── factory_test_start()

FreeRTOS 任务建议:

任务 优先级 功能
audio_frontend_task VB6824 唤醒、打断、状态同步
ai_session_task WebSocket、ASR、LLM、TTS
camera_task 中高 摄像头采集、JPEG 缓存
vision_task 中高 图片上传、视觉模型识别
servo_task 机械臂动作队列
lamp_task 亮度、色温、场景模式
display_task 单屏 / 双屏 / 异显 UI
network_task Wi-Fi / 4G / 蓝牙 PAN 策略
mcp_uart_task 中高 语义到动作的 MCP 映射
ota_task 固件与资源 OTA
factory_task 产测与老化

6. AI 交互链路

6.1 语音对话链路

复制代码
用户说话
  ↓
VB6824 离线唤醒 / AEC / 降噪
  ↓
ESP32-S3 进入 Listening
  ↓
WebSocket 上传音频
  ↓
ASR
  ↓
LLM / MCP 工具决策
  ↓
TTS
  ↓
ESP32-S3 播放
  ↓
喇叭输出

6.2 视觉问答链路

复制代码
用户:"小博,看看桌上有什么"
  ↓
唤醒 + 语音识别
  ↓
LLM 判断需要视觉工具
  ↓
ESP32-S3 摄像头拍照
  ↓
JPEG 上传到后端 VLM
  ↓
VLM 返回识别结果
  ↓
LLM 组织语言
  ↓
TTS 播报 + 屏幕显示

6.3 机械臂动作链路

复制代码
用户:"把灯转向书本"
  ↓
语音识别
  ↓
LLM 调用 vision_detect_book
  ↓
摄像头识别书本中心点
  ↓
坐标换算为 pan / tilt 角度
  ↓
ESP32-S3 控制舵机
  ↓
灯光切换阅读模式

7. 开发环境与编译

开发宝典建议使用 VSCode + ESP-IDF 扩展进行编译烧录;AI-S3 标准开发板章节使用 ESP-IDF 5.4.1,多模态 Vision 工程说明设置目标芯片为 esp32s3

7.1 AI-Speaker 基础工程

复制代码
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 /dev/ttyUSB0 flash monitor

7.2 多模态视觉工程

复制代码
git clone https://github.com/SmartArduino/DOIT_ESPS3_AI_EYE_Vision.git
cd DOIT_ESPS3_AI_EYE_Vision

idf.py set-target esp32s3
idf.py menuconfig
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor
复制代码
Board Type:
  Sibo Pixar Apple AI Lamp Speaker S3

Audio:
  VB6824
  USE_DEVICE_AEC = y
  USE_SERVER_AEC = n

Network:
  Wi-Fi = y
  BLE BluFi = y
  LTE 4G = optional
  Bluetooth PAN = optional

Vision:
  Camera = y
  JPEG Capture = y
  VLM Upload = y

Actuator:
  Servo Arm = y
  Lamp PWM = y

Display:
  Single / Dual Mirror / Dual Heterogeneous

MCP:
  Enable AT+MCP = y

8. 关键代码示例

下面代码按 ESP-IDF 风格给出,GPIO 仅为示例,实际量产需按 PCB 调整。


8.1 板级配置 board_config.h

复制代码
#pragma once

#include "driver/gpio.h"
#include "driver/uart.h"
#include "driver/spi_master.h"

/*
 * 四博皮克斯苹果 AI 台灯 / AI 智能音箱 S3 视觉机械臂版
 */

#define BOARD_NAME                  "SIBO_PIXAR_AI_LAMP_SPEAKER_S3"

/* ---------- 主控 ---------- */
#define SOC_NAME                    "ESP32-S3R8"
#define FLASH_SIZE_MB               16
#define PSRAM_SIZE_MB               8

/* ---------- VB6824 / AI MCP UART ---------- */
#define AI_UART                     UART_NUM_1
#define AI_UART_BAUD                115200
#define AI_UART_TX_GPIO             GPIO_NUM_17
#define AI_UART_RX_GPIO             GPIO_NUM_18
#define AI_RESET_GPIO               GPIO_NUM_21

/* ---------- 4G Modem,可选 ---------- */
#define LTE_UART                    UART_NUM_2
#define LTE_UART_BAUD               115200
#define LTE_TX_GPIO                 GPIO_NUM_39
#define LTE_RX_GPIO                 GPIO_NUM_40
#define LTE_PWRKEY_GPIO             GPIO_NUM_41
#define LTE_RESET_GPIO              GPIO_NUM_42

/* ---------- 7014 Bluetooth PAN / A2DP,可选 ---------- */
#define BT7014_UART                 UART_NUM_0
#define BT7014_TX_GPIO              GPIO_NUM_43
#define BT7014_RX_GPIO              GPIO_NUM_44
#define BT7014_EN_GPIO              GPIO_NUM_45

/* ---------- Camera,GPIO 需按实际摄像头模组调整 ---------- */
#define CAM_PIN_PWDN                GPIO_NUM_NC
#define CAM_PIN_RESET               GPIO_NUM_NC
#define CAM_PIN_XCLK                GPIO_NUM_15
#define CAM_PIN_SIOD                GPIO_NUM_4
#define CAM_PIN_SIOC                GPIO_NUM_5
#define CAM_PIN_D0                  GPIO_NUM_11
#define CAM_PIN_D1                  GPIO_NUM_9
#define CAM_PIN_D2                  GPIO_NUM_8
#define CAM_PIN_D3                  GPIO_NUM_10
#define CAM_PIN_D4                  GPIO_NUM_12
#define CAM_PIN_D5                  GPIO_NUM_18
#define CAM_PIN_D6                  GPIO_NUM_17
#define CAM_PIN_D7                  GPIO_NUM_16
#define CAM_PIN_VSYNC               GPIO_NUM_6
#define CAM_PIN_HREF                GPIO_NUM_7
#define CAM_PIN_PCLK                GPIO_NUM_13

/* ---------- Servo Arm ---------- */
#define SERVO_BASE_GPIO             GPIO_NUM_1
#define SERVO_SHOULDER_GPIO         GPIO_NUM_2
#define SERVO_HEAD_GPIO             GPIO_NUM_3

/* ---------- Lamp PWM ---------- */
#define LAMP_WARM_PWM_GPIO          GPIO_NUM_35
#define LAMP_COLD_PWM_GPIO          GPIO_NUM_36

/* ---------- Audio ---------- */
#define AMP_EN_GPIO                 GPIO_NUM_46
#define I2S_BCLK_GPIO               GPIO_NUM_6
#define I2S_LRCK_GPIO               GPIO_NUM_7
#define I2S_DOUT_GPIO               GPIO_NUM_8

/* ---------- Display A ---------- */
#define LCD_A_SPI_HOST              SPI2_HOST
#define LCD_A_CS_GPIO               GPIO_NUM_10
#define LCD_A_DC_GPIO               GPIO_NUM_11
#define LCD_A_RST_GPIO              GPIO_NUM_12
#define LCD_A_BL_GPIO               GPIO_NUM_13

/* ---------- Display B,可选异显 ---------- */
#define LCD_B_SPI_HOST              SPI2_HOST
#define LCD_B_CS_GPIO               GPIO_NUM_14
#define LCD_B_DC_GPIO               GPIO_NUM_15
#define LCD_B_RST_GPIO              GPIO_NUM_16
#define LCD_B_BL_GPIO               GPIO_NUM_4

/* ---------- Keys ---------- */
#define KEY_BOOT_GPIO               GPIO_NUM_0
#define KEY_TOUCH_1_GPIO            GPIO_NUM_47
#define KEY_TOUCH_2_GPIO            GPIO_NUM_48

/* ---------- Safety ---------- */
#define BAT_ADC_CHANNEL             3
#define SERVO_CURRENT_ADC_CHANNEL   4

8.2 机械臂舵机控制 servo_arm.c

复制代码
#include <math.h>
#include "esp_log.h"
#include "driver/ledc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "board_config.h"

#define TAG "SERVO_ARM"

#define SERVO_TIMER             LEDC_TIMER_0
#define SERVO_MODE              LEDC_LOW_SPEED_MODE
#define SERVO_FREQ_HZ           50
#define SERVO_RESOLUTION        LEDC_TIMER_14_BIT

#define SERVO_MIN_US            500
#define SERVO_MAX_US            2500
#define SERVO_PERIOD_US         20000

typedef enum {
    SERVO_CH_BASE = 0,
    SERVO_CH_SHOULDER,
    SERVO_CH_HEAD,
} servo_id_t;

typedef struct {
    gpio_num_t gpio;
    ledc_channel_t ch;
    float min_angle;
    float max_angle;
    float current_angle;
} servo_t;

static servo_t s_servos[] = {
    {
        .gpio = SERVO_BASE_GPIO,
        .ch = LEDC_CHANNEL_0,
        .min_angle = 0,
        .max_angle = 180,
        .current_angle = 90,
    },
    {
        .gpio = SERVO_SHOULDER_GPIO,
        .ch = LEDC_CHANNEL_1,
        .min_angle = 20,
        .max_angle = 160,
        .current_angle = 90,
    },
    {
        .gpio = SERVO_HEAD_GPIO,
        .ch = LEDC_CHANNEL_2,
        .min_angle = 30,
        .max_angle = 150,
        .current_angle = 90,
    },
};

static uint32_t servo_angle_to_duty(float angle)
{
    if (angle < 0) {
        angle = 0;
    }

    if (angle > 180) {
        angle = 180;
    }

    float pulse_us = SERVO_MIN_US +
        (SERVO_MAX_US - SERVO_MIN_US) * angle / 180.0f;

    uint32_t max_duty = (1 << 14) - 1;
    return (uint32_t)(max_duty * pulse_us / SERVO_PERIOD_US);
}

static float clamp_angle(servo_t *servo, float angle)
{
    if (angle < servo->min_angle) {
        return servo->min_angle;
    }

    if (angle > servo->max_angle) {
        return servo->max_angle;
    }

    return angle;
}

void servo_arm_init(void)
{
    ledc_timer_config_t timer = {
        .speed_mode = SERVO_MODE,
        .timer_num = SERVO_TIMER,
        .duty_resolution = SERVO_RESOLUTION,
        .freq_hz = SERVO_FREQ_HZ,
        .clk_cfg = LEDC_AUTO_CLK,
    };

    ESP_ERROR_CHECK(ledc_timer_config(&timer));

    for (int i = 0; i < 3; i++) {
        ledc_channel_config_t ch = {
            .gpio_num = s_servos[i].gpio,
            .speed_mode = SERVO_MODE,
            .channel = s_servos[i].ch,
            .intr_type = LEDC_INTR_DISABLE,
            .timer_sel = SERVO_TIMER,
            .duty = servo_angle_to_duty(s_servos[i].current_angle),
            .hpoint = 0,
        };

        ESP_ERROR_CHECK(ledc_channel_config(&ch));
    }

    ESP_LOGI(TAG, "servo arm init done");
}

void servo_set_angle(servo_id_t id, float angle)
{
    if (id < 0 || id >= 3) {
        return;
    }

    servo_t *servo = &s_servos[id];
    angle = clamp_angle(servo, angle);

    uint32_t duty = servo_angle_to_duty(angle);

    ledc_set_duty(SERVO_MODE, servo->ch, duty);
    ledc_update_duty(SERVO_MODE, servo->ch);

    servo->current_angle = angle;

    ESP_LOGI(TAG, "servo %d angle %.1f", id, angle);
}

void servo_move_smooth(servo_id_t id, float target, float step, int delay_ms)
{
    if (id < 0 || id >= 3 || step <= 0) {
        return;
    }

    servo_t *servo = &s_servos[id];
    target = clamp_angle(servo, target);

    float current = servo->current_angle;
    float dir = target > current ? 1.0f : -1.0f;

    while (fabsf(target - current) > step) {
        current += dir * step;
        servo_set_angle(id, current);
        vTaskDelay(pdMS_TO_TICKS(delay_ms));
    }

    servo_set_angle(id, target);
}

void servo_look_at_percent(float x_percent, float y_percent)
{
    /*
     * x_percent: 0~100, 图像左到右
     * y_percent: 0~100, 图像上到下
     *
     * 简化映射:
     * 图像中心 50,50 对应 pan=90, tilt=90。
     */
    float pan = 90.0f + (x_percent - 50.0f) * 0.8f;
    float tilt = 90.0f + (y_percent - 50.0f) * 0.6f;

    servo_move_smooth(SERVO_CH_BASE, pan, 2.0f, 20);
    servo_move_smooth(SERVO_CH_HEAD, tilt, 2.0f, 20);
}

void servo_home(void)
{
    servo_move_smooth(SERVO_CH_BASE, 90, 2.0f, 15);
    servo_move_smooth(SERVO_CH_SHOULDER, 90, 2.0f, 15);
    servo_move_smooth(SERVO_CH_HEAD, 90, 2.0f, 15);
}

8.3 台灯亮度与色温控制 lamp_driver.c

复制代码
#include "esp_log.h"
#include "driver/ledc.h"
#include "board_config.h"

#define TAG "LAMP"

#define LAMP_TIMER              LEDC_TIMER_1
#define LAMP_MODE               LEDC_LOW_SPEED_MODE
#define LAMP_FREQ_HZ            20000
#define LAMP_RESOLUTION         LEDC_TIMER_12_BIT
#define LAMP_MAX_DUTY           ((1 << 12) - 1)

typedef enum {
    LAMP_MODE_OFF = 0,
    LAMP_MODE_READING,
    LAMP_MODE_EYE_CARE,
    LAMP_MODE_NIGHT,
    LAMP_MODE_FOCUS,
    LAMP_MODE_AMBIENT,
} lamp_mode_t;

static uint8_t s_brightness = 50;
static uint16_t s_color_temp = 4000;

static uint32_t percent_to_duty(uint8_t percent)
{
    if (percent > 100) {
        percent = 100;
    }

    return (uint32_t)(LAMP_MAX_DUTY * percent / 100);
}

void lamp_driver_init(void)
{
    ledc_timer_config_t timer = {
        .speed_mode = LAMP_MODE,
        .timer_num = LAMP_TIMER,
        .duty_resolution = LAMP_RESOLUTION,
        .freq_hz = LAMP_FREQ_HZ,
        .clk_cfg = LEDC_AUTO_CLK,
    };

    ledc_timer_config(&timer);

    ledc_channel_config_t warm = {
        .gpio_num = LAMP_WARM_PWM_GPIO,
        .speed_mode = LAMP_MODE,
        .channel = LEDC_CHANNEL_3,
        .timer_sel = LAMP_TIMER,
        .duty = 0,
        .hpoint = 0,
    };

    ledc_channel_config_t cold = {
        .gpio_num = LAMP_COLD_PWM_GPIO,
        .speed_mode = LAMP_MODE,
        .channel = LEDC_CHANNEL_4,
        .timer_sel = LAMP_TIMER,
        .duty = 0,
        .hpoint = 0,
    };

    ledc_channel_config(&warm);
    ledc_channel_config(&cold);

    ESP_LOGI(TAG, "lamp driver init done");
}

void lamp_set(uint8_t brightness, uint16_t color_temp)
{
    if (brightness > 100) {
        brightness = 100;
    }

    if (color_temp < 2700) {
        color_temp = 2700;
    }

    if (color_temp > 6500) {
        color_temp = 6500;
    }

    /*
     * 色温线性映射:
     * 2700K: warm=100%, cold=0%
     * 6500K: warm=0%, cold=100%
     */
    float cold_ratio = (float)(color_temp - 2700) / (6500 - 2700);
    float warm_ratio = 1.0f - cold_ratio;

    uint8_t warm_percent = (uint8_t)(brightness * warm_ratio);
    uint8_t cold_percent = (uint8_t)(brightness * cold_ratio);

    ledc_set_duty(LAMP_MODE, LEDC_CHANNEL_3, percent_to_duty(warm_percent));
    ledc_update_duty(LAMP_MODE, LEDC_CHANNEL_3);

    ledc_set_duty(LAMP_MODE, LEDC_CHANNEL_4, percent_to_duty(cold_percent));
    ledc_update_duty(LAMP_MODE, LEDC_CHANNEL_4);

    s_brightness = brightness;
    s_color_temp = color_temp;

    ESP_LOGI(TAG, "lamp brightness=%u color_temp=%u warm=%u cold=%u",
             brightness, color_temp, warm_percent, cold_percent);
}

void lamp_apply_mode(lamp_mode_t mode)
{
    switch (mode) {
    case LAMP_MODE_OFF:
        lamp_set(0, 4000);
        break;

    case LAMP_MODE_READING:
        lamp_set(85, 4200);
        break;

    case LAMP_MODE_EYE_CARE:
        lamp_set(60, 3600);
        break;

    case LAMP_MODE_NIGHT:
        lamp_set(10, 2700);
        break;

    case LAMP_MODE_FOCUS:
        lamp_set(95, 5000);
        break;

    case LAMP_MODE_AMBIENT:
        lamp_set(35, 3000);
        break;

    default:
        lamp_set(s_brightness, s_color_temp);
        break;
    }
}

8.4 摄像头初始化与拍照上传框架

复制代码
#include "esp_log.h"
#include "esp_camera.h"
#include "board_config.h"

#define TAG "CAMERA"

static camera_fb_t *s_last_fb = NULL;

esp_err_t camera_service_init(void)
{
    camera_config_t config = {
        .pin_pwdn = CAM_PIN_PWDN,
        .pin_reset = CAM_PIN_RESET,
        .pin_xclk = CAM_PIN_XCLK,
        .pin_sccb_sda = CAM_PIN_SIOD,
        .pin_sccb_scl = CAM_PIN_SIOC,

        .pin_d7 = CAM_PIN_D7,
        .pin_d6 = CAM_PIN_D6,
        .pin_d5 = CAM_PIN_D5,
        .pin_d4 = CAM_PIN_D4,
        .pin_d3 = CAM_PIN_D3,
        .pin_d2 = CAM_PIN_D2,
        .pin_d1 = CAM_PIN_D1,
        .pin_d0 = CAM_PIN_D0,

        .pin_vsync = CAM_PIN_VSYNC,
        .pin_href = CAM_PIN_HREF,
        .pin_pclk = CAM_PIN_PCLK,

        .xclk_freq_hz = 20000000,
        .ledc_timer = LEDC_TIMER_2,
        .ledc_channel = LEDC_CHANNEL_5,

        .pixel_format = PIXFORMAT_JPEG,
        .frame_size = FRAMESIZE_VGA,
        .jpeg_quality = 12,
        .fb_count = 2,
        .fb_location = CAMERA_FB_IN_PSRAM,
        .grab_mode = CAMERA_GRAB_LATEST,
    };

    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "camera init failed: 0x%x", err);
        return err;
    }

    ESP_LOGI(TAG, "camera init done");
    return ESP_OK;
}

camera_fb_t *camera_capture_jpeg(void)
{
    if (s_last_fb) {
        esp_camera_fb_return(s_last_fb);
        s_last_fb = NULL;
    }

    s_last_fb = esp_camera_fb_get();
    if (!s_last_fb) {
        ESP_LOGE(TAG, "capture failed");
        return NULL;
    }

    ESP_LOGI(TAG, "capture jpeg size=%u", s_last_fb->len);
    return s_last_fb;
}

void camera_release_last(void)
{
    if (s_last_fb) {
        esp_camera_fb_return(s_last_fb);
        s_last_fb = NULL;
    }
}

/*
 * TODO:
 * 量产工程中可实现:
 * 1. HTTP multipart 上传 JPEG;
 * 2. WebSocket binary 上传 JPEG;
 * 3. 本地 SD 卡保存;
 * 4. 返回 vision_result_t 给机械臂和 TTS 使用。
 */

8.5 视觉结果到机械臂动作

复制代码
#include <stdint.h>
#include <stdbool.h>
#include "esp_log.h"

#define TAG "VISION_ACTION"

typedef struct {
    bool found;
    char label[32];
    float x_percent;
    float y_percent;
    float confidence;
} vision_object_t;

extern void servo_look_at_percent(float x_percent, float y_percent);
extern void lamp_apply_mode(int mode);
extern void lamp_set(uint8_t brightness, uint16_t color_temp);

typedef enum {
    LAMP_MODE_READING = 1,
    LAMP_MODE_EYE_CARE = 2,
    LAMP_MODE_FOCUS = 4,
} lamp_mode_t;

void vision_handle_object(const vision_object_t *obj)
{
    if (!obj || !obj->found) {
        ESP_LOGW(TAG, "object not found");
        return;
    }

    ESP_LOGI(TAG, "object=%s x=%.1f y=%.1f conf=%.2f",
             obj->label,
             obj->x_percent,
             obj->y_percent,
             obj->confidence);

    /*
     * 让灯头看向目标。
     */
    servo_look_at_percent(obj->x_percent, obj->y_percent);

    /*
     * 根据识别物体切换灯光模式。
     */
    if (strcmp(obj->label, "book") == 0 ||
        strcmp(obj->label, "paper") == 0) {
        lamp_apply_mode(LAMP_MODE_READING);
    } else if (strcmp(obj->label, "face") == 0) {
        lamp_set(45, 3600);
    } else {
        lamp_apply_mode(LAMP_MODE_FOCUS);
    }
}

8.6 AT+MCP:把自然语言变成设备动作

开发宝典中的 AT+MCP 非常适合这类"AI 台灯 + 音箱 + 机械臂"产品。协议使用 UART,默认 115200, 8N1,所有指令以回车换行结束;AT+ADDMCP 可以把"人话"映射成 MCU 可执行的二进制控制帧;模块还会上报开机、配网、联网、监听、说话、升级、激活等状态。 当 MCU 收到 55 AA 01 FC AA 55 时,需要重启 AI 模组并重新发送 MCP 映射。

MCP 命令设计

复制代码
CMD_LAMP_SET        0xF1
CMD_ARM_MOVE        0xF2
CMD_CAPTURE         0xF3
CMD_VISION_ASK      0xF4
CMD_SCREEN_MODE     0xF5
CMD_NETWORK_MODE    0xF6
CMD_CUSTOMER_API    0xF7

代码

复制代码
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "esp_log.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "board_config.h"

#define TAG "MCP"

#define FRAME_H1            0x55
#define FRAME_H2            0xAA
#define FRAME_T1            0xAA
#define FRAME_T2            0x55

#define CMD_STATUS          0xFF
#define CMD_RECOVER         0xFC

#define CMD_LAMP_SET        0xF1
#define CMD_ARM_MOVE        0xF2
#define CMD_CAPTURE         0xF3
#define CMD_VISION_ASK      0xF4
#define CMD_SCREEN_MODE     0xF5
#define CMD_NETWORK_MODE    0xF6
#define CMD_CUSTOMER_API    0xF7

typedef enum {
    AI_STARTING     = 0x01,
    AI_CONFIGURING  = 0x02,
    AI_IDLE         = 0x03,
    AI_CONNECTING   = 0x04,
    AI_LISTENING    = 0x05,
    AI_SPEAKING     = 0x06,
    AI_UPGRADING    = 0x07,
    AI_ACTIVATING   = 0x08,
} ai_status_t;

extern void lamp_set(uint8_t brightness, uint16_t color_temp);
extern void servo_move_smooth(int id, float target, float step, int delay_ms);
extern void servo_home(void);
extern void on_capture_and_vision_ask(void);
extern void camera_capture_jpeg(void);

static void ai_reset_module(void)
{
    gpio_set_direction(AI_RESET_GPIO, GPIO_MODE_OUTPUT);
    gpio_set_level(AI_RESET_GPIO, 0);
    vTaskDelay(pdMS_TO_TICKS(300));
    gpio_set_level(AI_RESET_GPIO, 1);
    vTaskDelay(pdMS_TO_TICKS(1500));
}

static void mcp_send_line(const char *line)
{
    uart_write_bytes(AI_UART, line, strlen(line));
    uart_write_bytes(AI_UART, "\r\n", 2);
    ESP_LOGI(TAG, "MCU -> AI: %s", line);
}

static void ui_on_ai_status(ai_status_t status)
{
    switch (status) {
    case AI_STARTING:
        ESP_LOGI(TAG, "AI starting");
        break;
    case AI_CONFIGURING:
        ESP_LOGI(TAG, "AI configuring");
        break;
    case AI_IDLE:
        ESP_LOGI(TAG, "AI idle");
        break;
    case AI_CONNECTING:
        ESP_LOGI(TAG, "AI connecting");
        break;
    case AI_LISTENING:
        ESP_LOGI(TAG, "AI listening");
        break;
    case AI_SPEAKING:
        ESP_LOGI(TAG, "AI speaking");
        break;
    case AI_UPGRADING:
        ESP_LOGI(TAG, "AI upgrading");
        break;
    case AI_ACTIVATING:
        ESP_LOGI(TAG, "AI activating");
        break;
    default:
        ESP_LOGW(TAG, "unknown AI status: 0x%02X", status);
        break;
    }
}

static void mcp_register_tools(void)
{
    mcp_send_line("AT");
    mcp_send_line("AT+WIFICFG=0");
    mcp_send_line("AT+CONNECT");

    /*
     * 用户:"把灯调亮一点 / 色温调暖一点"
     * 返回:55 AA 04 F1 brightness color_temp_hi color_temp_lo AA 55
     */
    mcp_send_line(
        "AT+ADDMCP=1,set_lamp,设置台灯亮度和色温,F1,3,brightness,color_temp_hi,color_temp_lo"
    );

    /*
     * 用户:"台灯转过来看我 / 灯头抬高一点"
     * 返回:55 AA 04 F2 servo_id angle_hi angle_lo AA 55
     */
    mcp_send_line(
        "AT+ADDMCP=1,move_arm,控制机械臂或灯头角度,F2,3,servo_id,angle_hi,angle_lo"
    );

    /*
     * 用户:"拍一张照片"
     */
    mcp_send_line(
        "AT+ADDMCP=0,capture_photo,控制摄像头拍照,2,F3,01"
    );

    /*
     * 用户:"看看桌上有什么 / 帮我看这道题"
     */
    mcp_send_line(
        "AT+ADDMCP=0,vision_question,调用摄像头和视觉大模型识别当前画面,2,F4,01"
    );

    /*
     * 用户:"切换到双屏异显 / 只显示时钟"
     */
    mcp_send_line(
        "AT+ADDMCP=1,set_screen_mode,设置屏幕显示模式,F5,1,mode"
    );

    /*
     * 用户:"切换到 4G 网络 / 打开蓝牙上网"
     */
    mcp_send_line(
        "AT+ADDMCP=1,set_network_mode,切换联网方式,F6,1,mode"
    );

    /*
     * 用户:"打开客户系统的一号场景"
     */
    mcp_send_line(
        "AT+ADDMCP=1,customer_api,调用客户系统接口,F7,2,scene_id,action"
    );
}

static void mcp_handle_frame(uint8_t cmd, const uint8_t *data, uint8_t len)
{
    if (cmd == CMD_RECOVER) {
        ai_reset_module();
        mcp_register_tools();
        return;
    }

    if (cmd == CMD_STATUS && len >= 1) {
        ui_on_ai_status((ai_status_t)data[0]);
        return;
    }

    switch (cmd) {
    case CMD_LAMP_SET:
        if (len >= 3) {
            uint8_t brightness = data[0];
            uint16_t color_temp = ((uint16_t)data[1] << 8) | data[2];
            lamp_set(brightness, color_temp);
        }
        break;

    case CMD_ARM_MOVE:
        if (len >= 3) {
            uint8_t servo_id = data[0];
            uint16_t angle_raw = ((uint16_t)data[1] << 8) | data[2];
            servo_move_smooth(servo_id, (float)angle_raw, 2.0f, 15);
        }
        break;

    case CMD_CAPTURE:
        camera_capture_jpeg();
        break;

    case CMD_VISION_ASK:
        on_capture_and_vision_ask();
        break;

    case CMD_SCREEN_MODE:
        if (len >= 1) {
            ESP_LOGI(TAG, "screen mode=%u", data[0]);
            /*
             * TODO:
             * display_set_mode(data[0]);
             */
        }
        break;

    case CMD_NETWORK_MODE:
        if (len >= 1) {
            ESP_LOGI(TAG, "network mode=%u", data[0]);
            /*
             * mode:
             * 1 Wi-Fi
             * 2 4G
             * 3 Bluetooth PAN
             */
        }
        break;

    case CMD_CUSTOMER_API:
        if (len >= 2) {
            ESP_LOGI(TAG, "customer scene=%u action=%u", data[0], data[1]);
            /*
             * TODO:
             * mqtt_publish_customer_scene(data[0], data[1]);
             * 或 HTTP 调客户系统。
             */
        }
        break;

    default:
        ESP_LOGW(TAG, "unhandled cmd=0x%02X len=%u", cmd, len);
        break;
    }
}

static void mcp_rx_task(void *arg)
{
    uint8_t frame[160];
    uint8_t pos = 0;
    int expected = -1;

    while (1) {
        uint8_t b = 0;
        int n = uart_read_bytes(AI_UART, &b, 1, pdMS_TO_TICKS(100));

        if (n <= 0) {
            continue;
        }

        if (pos == 0 && b != FRAME_H1) {
            continue;
        }

        if (pos == 1 && b != FRAME_H2) {
            pos = 0;
            expected = -1;
            continue;
        }

        frame[pos++] = b;

        if (pos == 3) {
            uint8_t len = frame[2];
            if (len == 0 || len > 150) {
                pos = 0;
                expected = -1;
                continue;
            }

            expected = 2 + 1 + len + 2;
        }

        if (expected > 0 && pos >= expected) {
            uint8_t len = frame[2];

            if (frame[3 + len] == FRAME_T1 &&
                frame[4 + len] == FRAME_T2) {

                uint8_t cmd = frame[3];
                const uint8_t *data = &frame[4];
                uint8_t data_len = len - 1;

                mcp_handle_frame(cmd, data, data_len);
            } else {
                ESP_LOGW(TAG, "bad frame tail");
            }

            pos = 0;
            expected = -1;
        }

        if (pos >= sizeof(frame)) {
            pos = 0;
            expected = -1;
        }
    }
}

void mcp_uart_bridge_start(void)
{
    uart_config_t cfg = {
        .baud_rate = AI_UART_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(AI_UART, 2048, 2048, 0, NULL, 0);
    uart_param_config(AI_UART, &cfg);
    uart_set_pin(
        AI_UART,
        AI_UART_TX_GPIO,
        AI_UART_RX_GPIO,
        UART_PIN_NO_CHANGE,
        UART_PIN_NO_CHANGE
    );

    ai_reset_module();
    mcp_register_tools();

    xTaskCreate(mcp_rx_task, "mcp_rx", 4096, NULL, 10, NULL);
}

8.7 视觉问答流程框架

复制代码
#include "esp_log.h"
#include "esp_http_client.h"
#include "esp_camera.h"

#define TAG "VISION_AI"

extern camera_fb_t *camera_capture_jpeg(void);
extern void camera_release_last(void);
extern void ai_tts_speak_text(const char *text);

typedef struct {
    bool found;
    char label[32];
    float x_percent;
    float y_percent;
    float confidence;
    char answer[256];
} vision_result_t;

static esp_err_t vision_upload_jpeg(camera_fb_t *fb, vision_result_t *result)
{
    if (!fb || !result) {
        return ESP_ERR_INVALID_ARG;
    }

    /*
     * 这里给框架,不限定具体后端。
     * 可以对接:
     * 1. 小智私有化后端的视觉工具;
     * 2. 客户自己的 VLM 服务;
     * 3. OpenAI / 豆包 / 通义 / 自建多模态模型。
     */

    esp_http_client_config_t config = {
        .url = "https://your-server.com/api/v1/vision/analyze",
        .method = HTTP_METHOD_POST,
        .timeout_ms = 15000,
    };

    esp_http_client_handle_t client = esp_http_client_init(&config);

    esp_http_client_set_header(client, "Content-Type", "image/jpeg");
    esp_http_client_set_post_field(client, (const char *)fb->buf, fb->len);

    esp_err_t err = esp_http_client_perform(client);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "vision request failed: %s", esp_err_to_name(err));
        esp_http_client_cleanup(client);
        return err;
    }

    int status = esp_http_client_get_status_code(client);
    ESP_LOGI(TAG, "vision status=%d", status);

    /*
     * TODO:
     * 实际工程中读取 response JSON:
     * {
     *   "answer": "桌面上有一本书和一支笔",
     *   "object": {
     *      "label": "book",
     *      "x": 63.5,
     *      "y": 54.2,
     *      "confidence": 0.91
     *   }
     * }
     */

    result->found = true;
    snprintf(result->label, sizeof(result->label), "book");
    result->x_percent = 60.0f;
    result->y_percent = 55.0f;
    result->confidence = 0.90f;
    snprintf(result->answer, sizeof(result->answer),
             "我看到了桌面上的书本,已经把灯光转向书本位置。");

    esp_http_client_cleanup(client);
    return ESP_OK;
}

extern void vision_handle_object(const vision_object_t *obj);

void on_capture_and_vision_ask(void)
{
    camera_fb_t *fb = camera_capture_jpeg();
    if (!fb) {
        ai_tts_speak_text("摄像头打开失败,请检查摄像头连接。");
        return;
    }

    vision_result_t result = {0};
    esp_err_t err = vision_upload_jpeg(fb, &result);
    camera_release_last();

    if (err != ESP_OK) {
        ai_tts_speak_text("视觉识别失败,请稍后再试。");
        return;
    }

    vision_object_t obj = {
        .found = result.found,
        .x_percent = result.x_percent,
        .y_percent = result.y_percent,
        .confidence = result.confidence,
    };

    snprintf(obj.label, sizeof(obj.label), "%s", result.label);

    vision_handle_object(&obj);
    ai_tts_speak_text(result.answer);
}

8.8 主程序 app_main.c

复制代码
#include "esp_log.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define TAG "APP"

extern void servo_arm_init(void);
extern void servo_home(void);
extern void lamp_driver_init(void);
extern void lamp_apply_mode(int mode);
extern esp_err_t camera_service_init(void);
extern void mcp_uart_bridge_start(void);
extern void network_policy_start(void);
extern void display_manager_start(void);
extern void ai_websocket_start(void);
extern void ota_manager_start(void);

void app_main(void)
{
    ESP_LOGI(TAG, "boot %s", "SIBO_PIXAR_AI_LAMP_SPEAKER_S3");

    ESP_ERROR_CHECK(nvs_flash_init());

    /*
     * 板级外设
     */
    lamp_driver_init();
    servo_arm_init();
    servo_home();

    /*
     * 摄像头
     */
    if (camera_service_init() != ESP_OK) {
        ESP_LOGW(TAG, "camera not ready, continue audio only mode");
    }

    /*
     * 显示与联网
     */
    display_manager_start();
    network_policy_start();

    /*
     * AI 服务
     */
    ai_websocket_start();
    mcp_uart_bridge_start();

    /*
     * OTA
     */
    ota_manager_start();

    /*
     * 默认护眼模式
     */
    lamp_apply_mode(2);

    ESP_LOGI(TAG, "system started");
}

9. 三种产品形态

9.1 标准 AI 音箱版

复制代码
ESP32-S3R8 + 16M Flash
VB6824
Wi-Fi + BLE BluFi
1.3 / 1.54 寸屏
麦克风 + 喇叭
小智 / 豆包 / ChatGPT
MCP 控制灯光、音乐、闹钟、客户系统

适合:智能音箱、桌面助手、儿童故事机、智能家居语音入口。

9.2 AI 台灯音箱版

复制代码
ESP32-S3R8 + VB6824
摄像头
冷暖双色 LED 台灯
2 自由度云台
单屏 UI
Wi-Fi / BLE / 可选 4G
视觉问答 + 语音控制 + 灯光控制

适合:学习台灯、陪伴台灯、办公桌面 AI 助手。

9.3 皮克斯苹果 AI 台灯高端版

复制代码
ESP32-S3R8 + 16M Flash + 8M PSRAM
VB6824
摄像头
3 自由度机械臂
双屏 / 异显
4G 模组
7014 蓝牙 PAN / 蓝牙音箱
声音克隆
知识库
MCP 工具
视觉大模型
客户私有化后端
全开源生产资料

适合:品牌 B 端客户、方案商客户、高端 AI 玩具、AI 桌宠、教育台灯、展厅导览、桌面机器人。


10. 后端服务建议

开发宝典中说明,设备默认可连接小智官方服务,也可以运行开源后端服务,让设备连接到自己的后端;后端包括 OTA 接口和 WebSocket 接口,并可配置 LLM、TTS、人设等参数。 文档还提到,如果服务部署在服务器上反馈会更快,有显卡资源时还可以自建 LLM 和 TTS 服务。

推荐后端:

复制代码
Nginx / Caddy
 ├── HTTPS OTA
 ├── WSS WebSocket
 ├── Device Auth
 ├── ASR
 ├── LLM
 ├── TTS
 ├── VLM Vision API
 ├── MCP Tool Server
 └── Customer API Gateway

配置示例:

复制代码
server:
  websocket_url: "wss://ai.customer.com/xiaozhi/v1/"
  ota_url: "https://ai.customer.com/xiaozhi/ota/"

selected_module:
  VAD: SileroVAD
  ASR: FunASR
  LLM: CustomerLLM
  TTS: CustomerTTS
  Vision: CustomerVLM
  Intent: function_call

device_profile:
  name: "四博皮克斯苹果AI台灯"
  capabilities:
    - voice_wakeup
    - realtime_barge_in
    - camera_capture
    - vision_question
    - servo_arm
    - lamp_control
    - display
    - mcp

11. 量产与产测

11.1 产测项目

复制代码
主控:
  - ESP32-S3 Flash / PSRAM 检测
  - NVS 写入 SN / Batch ID
  - Wi-Fi MAC / BLE MAC 读取

语音:
  - VB6824 UART 通信
  - 唤醒词测试
  - 播放中打断测试
  - 麦克风电平
  - 喇叭测试
  - AEC 回采测试

视觉:
  - 摄像头初始化
  - 拍照 JPEG 大小检测
  - 亮度 / 焦距 / 图像方向测试

机械臂:
  - 舵机回零
  - pan / tilt / head 动作测试
  - 限位测试
  - 堵转电流测试

灯光:
  - 暖光 PWM
  - 冷光 PWM
  - 亮度 0/50/100
  - 色温 2700K / 4000K / 6500K

屏幕:
  - 单屏显示
  - 双屏镜像
  - 双屏异显
  - 背光 PWM

网络:
  - Wi-Fi 扫描
  - BluFi 配网
  - 4G CSQ / 注册 / PPP
  - 蓝牙 PAN

云端:
  - OTA 请求
  - WebSocket 连接
  - VLM 请求
  - MCP 指令闭环

11.2 工厂串口命令建议

复制代码
FACTORY ENTER
FACTORY SET_SN=SBOPIXAR20260001
FACTORY WIFI_SCAN
FACTORY LTE_CSQ
FACTORY MIC_LEVEL
FACTORY SPK_PLAY=1000HZ
FACTORY WAKE_TEST
FACTORY CAMERA_CAPTURE
FACTORY SERVO_HOME
FACTORY SERVO_MOVE=0,90
FACTORY LAMP_SET=80,4000
FACTORY LCD_TEST
FACTORY MCP_TEST
FACTORY OTA_CHECK
FACTORY EXIT

12. 安全与可靠性设计

复制代码
1. 机械臂限位:
   所有角度必须软件限幅,避免打到用户或结构件。

2. 堵转保护:
   通过电流采样或动作超时判断,异常立即断开舵机电源。

3. 儿童模式:
   降低机械臂运动速度,禁用快速甩动动作。

4. 摄像头隐私:
   摄像头工作时屏幕 / LED 明确提示。
   支持物理遮挡片或隐私开关。

5. 4G 流量控制:
   图片上传与 OTA 优先走 Wi-Fi。
   4G 下限制高频视觉请求。

6. OTA 回滚:
   S3 主控双 OTA 分区,失败自动回滚。

7. VB6824 固件:
   语音前端固件独立升级,避免和主控 OTA 混淆。

13. 一句话总结

这套方案可以定义为:基于 ESP32-S3R8 + 16M Flash + VB6824 的四博皮克斯苹果 AI 台灯 / AI 智能音箱一体化平台。S3 负责联网、屏幕、摄像头、机械臂、灯光、WebSocket、OTA 和二次开发;VB6824 负责离线唤醒、远场拾音、AEC、降噪、唤醒词打断和自定义唤醒词;摄像头接入视觉大模型实现"看得见";机械臂和灯光系统实现"会动作、会照明";AT+MCP 把自然语言转成可执行控制帧;小智 / 私有化后端 / 客户大模型负责对话、视觉理解和工具调用。整体硬件和软件可开源,适合快速样机、客户定制和量产落地。

相关推荐
了不起的云计算V1 小时前
从DeepSeek V4适配看国产算力的三个拐点
数据库·人工智能
Cosolar2 小时前
大模型应用开发工程师 · 学习路线(完整技术栈版)
人工智能·面试·架构
MadPrinter2 小时前
Ollama 本地部署 Google Gemma 4 26B MoE 旗舰模型
人工智能
憨波个2 小时前
【说话人日志】多说话人数据仿真 Property-Aware Simulation
人工智能·深度学习·音频·语音识别
code_pgf2 小时前
MNN Whisper 实时 ASR 工程实现
人工智能·whisper·mnn
AC赳赳老秦2 小时前
OpenClaw实战案例:用Agent实现每日工作日报自动生成+发送
人工智能·python·职场和发展·eclipse·github·deepseek·openclaw
敢敢のwings2 小时前
NVIDIA Thor学习之 |在Jetson AGX Thor上部署OpenClaw并基于Ollama的边缘AI协作实战(二)
人工智能·学习
OFIRM碳基硅基2 小时前
OFIRM-AGI-ASI官方标志图01版,发布
人工智能·agi·ofirm颠覆性
haina20192 小时前
海纳AI正式发布“面试Agent”——实现千岗千面与人机共管的智面新纪元
人工智能·面试·职场和发展