四博 AI 机械臂台灯智能音箱方案

四博 AI 机械臂台灯智能音箱方案

基于 ESP32-S3 打造带视觉感知、机械臂控制和学习陪伴能力的 AI 桌面终端

传统台灯只解决照明问题,传统音箱只解决语音交互问题。而四博 AI 机械臂台灯智能音箱,可以把 照明、语音、视觉、机械臂、学习陪伴、环境感知、智能家居控制 融合到一个桌面终端中。

它不是普通台灯,也不是普通 AI 音箱,而是一个具备"看、听、说、动、照明、陪伴、提醒、控制"能力的 AI 桌面机器人。

复制代码
四博 AI 机械臂台灯 =
ESP32-S3 AI 主控
+ 摄像头视觉识别
+ 远场语音交互
+ TTS 语音播放
+ 机械臂云台 / 灯头控制
+ 智能照明调光
+ 屏幕 / 双目屏显示
+ 学习陪伴智能体
+ 天气与环境识别
+ MCP 工具调用
+ OTA 在线升级

一、产品定位

四博 AI 机械臂台灯智能音箱可以定位为:

复制代码
AI 桌面学习陪伴终端
+ 视觉感知台灯
+ AI 语音音箱
+ 智能照明控制器
+ 桌面机械臂机器人
+ 家庭 AI 助手
+ CozyLife 智能家居入口

它可以实现以下场景:

复制代码
1. 看窗外天气:通过摄像头识别窗外光照、天空状态、雨雾情况
2. 看周边环境:识别桌面亮度、用户是否在座位、书本/作业区域
3. 学习陪伴:语音问答、英语陪练、古诗背诵、口算训练、学习提醒
4. 自动调灯:根据环境亮度和学习状态调节亮度 / 色温
5. 机械臂跟随:灯头自动转向书桌、书本、用户位置
6. AI 对话:接入小智、豆包、ChatGPT 或客户自有智能体
7. 智能家居控制:通过 MCP / MQTT / HTTP 控制灯具、空调、窗帘等设备
8. OTA 升级:持续更新固件、提示音、识别模型、表情素材和工具列表

四博 AI 硬件选型资料里已经展示了 AI 智能相机、AI 智能小夜灯、AI 智能音响、AI-S3 双目双屏等形态,这些能力可以组合成"带视觉与机械臂控制的 AI 台灯音箱"产品形态。


二、硬件方案设计

推荐采用 ESP32-S3R8 / ESPS3-32-N16R8 作为主控。ESP32-S3 适合做 AI 音频、摄像头、LCD、触控和机械控制的组合方案。模组选型手册中 ESPS3-32 系列包含 N4、N8、N8R2、N16R2、N16R8 等多个规格,可按显示、视觉、音频缓存、OTA 空间需求选择不同版本。

推荐硬件配置

模块 推荐配置
主控 ESP32-S3R8 / ESPS3-32-N16R8
Flash 16MB
PSRAM 8MB
摄像头 OV2640 / GC2145 / USB Camera 方案可选
音频输入 I2S 数字麦克风 / 双麦阵列
音频输出 I2S Codec + Class-D 功放
喇叭 4Ω 3W
屏幕 1.54 寸 / 2.0 寸 LCD,或双目屏
机械臂 2~4 自由度舵机 / 步进电机 / 云台结构
灯光 PWM 调光,支持亮度和色温
传感器 环境光、温湿度、人体感应、三轴姿态可选
联网 Wi-Fi + BLE,4G 可扩展
供电 Type-C 5V / 12V 适配器,电池可选
升级 HTTPS OTA / 在线烧录平台

三、系统总体架构

复制代码
用户语音 / 桌面动作 / 周边环境
        ↓
麦克风 + 摄像头 + 环境传感器
        ↓
ESP32-S3 AI 主控
        ↓
音频前处理 / 视觉采集 / 机械臂控制 / 屏幕显示
        ↓
Wi-Fi / BLE / 4G
        ↓
ASR / LLM / TTS / 视觉识别 / MCP 工具调用
        ↓
台灯照明 / 机械臂动作 / 语音回复 / 学习陪伴 / 智能家居控制

设备端负责:

复制代码
1. 麦克风采集
2. 喇叭播放
3. 摄像头图像采集
4. 环境亮度检测
5. 机械臂运动控制
6. 灯光亮度 / 色温控制
7. 屏幕显示
8. Wi-Fi / BLE 联网
9. WebSocket AI 通信
10. MCP 工具执行
11. OTA 升级

云端负责:

复制代码
1. ASR 语音识别
2. LLM 大模型理解
3. TTS 语音合成
4. 图像识别 / 视觉理解
5. 天气判断 / 环境分析
6. 学习陪伴智能体
7. 知识库问答
8. MCP 工具调度

四、软件模块设计

推荐工程结构如下:

复制代码
doit_ai_arm_lamp/
├── main/
│   ├── app_main.c
│   ├── board_config.h
│   ├── wifi_manager.c
│   ├── audio_capture.c
│   ├── audio_player.c
│   ├── camera_service.c
│   ├── vision_service.c
│   ├── arm_servo.c
│   ├── lamp_light.c
│   ├── sensor_service.c
│   ├── study_assistant.c
│   ├── ai_ws_client.c
│   ├── mcp_service.c
│   ├── lcd_ui.c
│   └── ota_service.c
├── components/
│   ├── camera_driver/
│   ├── lcd_driver/
│   ├── codec/
│   ├── servo_driver/
│   └── audio_afe/
├── partitions_ota.csv
└── sdkconfig.defaults

系统状态机:

复制代码
typedef enum {
    SYS_STATE_BOOT = 0,
    SYS_STATE_WIFI_CONFIG,
    SYS_STATE_IDLE,
    SYS_STATE_LISTENING,
    SYS_STATE_THINKING,
    SYS_STATE_SPEAKING,
    SYS_STATE_VISION_ANALYZE,
    SYS_STATE_ARM_MOVING,
    SYS_STATE_STUDY_MODE,
    SYS_STATE_SLEEP_MODE,
    SYS_STATE_OTA,
    SYS_STATE_ERROR
} system_state_t;

static volatile system_state_t g_sys_state = SYS_STATE_BOOT;

五、板级配置示例

复制代码
#pragma once

#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "driver/ledc.h"

/* 产品名称 */
#define BOARD_NAME                  "DOIT_AI_ARM_LAMP_S3"

/* I2S Audio */
#define PIN_I2S_BCLK                GPIO_NUM_4
#define PIN_I2S_WS                  GPIO_NUM_5
#define PIN_I2S_DIN                 GPIO_NUM_6
#define PIN_I2S_DOUT                GPIO_NUM_7
#define PIN_I2S_MCLK                GPIO_NUM_16

/* I2C: Sensor / Codec */
#define I2C_PORT_MAIN               I2C_NUM_0
#define PIN_I2C_SDA                 GPIO_NUM_8
#define PIN_I2C_SCL                 GPIO_NUM_9

/* Camera */
#define PIN_CAM_XCLK                GPIO_NUM_10
#define PIN_CAM_PCLK                GPIO_NUM_11
#define PIN_CAM_VSYNC               GPIO_NUM_12
#define PIN_CAM_HREF                GPIO_NUM_13
#define PIN_CAM_SIOD                GPIO_NUM_8
#define PIN_CAM_SIOC                GPIO_NUM_9
#define PIN_CAM_D0                  GPIO_NUM_14
#define PIN_CAM_D1                  GPIO_NUM_15
#define PIN_CAM_D2                  GPIO_NUM_17
#define PIN_CAM_D3                  GPIO_NUM_18
#define PIN_CAM_D4                  GPIO_NUM_19
#define PIN_CAM_D5                  GPIO_NUM_20
#define PIN_CAM_D6                  GPIO_NUM_21
#define PIN_CAM_D7                  GPIO_NUM_47

/* LCD SPI */
#define LCD_HOST                    SPI2_HOST
#define PIN_LCD_MOSI                GPIO_NUM_35
#define PIN_LCD_SCLK                GPIO_NUM_36
#define PIN_LCD_CS                  GPIO_NUM_37
#define PIN_LCD_DC                  GPIO_NUM_38
#define PIN_LCD_RST                 GPIO_NUM_39
#define PIN_LCD_BL                  GPIO_NUM_40

/* Servo PWM */
#define PIN_SERVO_BASE              GPIO_NUM_1
#define PIN_SERVO_SHOULDER          GPIO_NUM_2
#define PIN_SERVO_ELBOW             GPIO_NUM_3
#define PIN_SERVO_LAMP_HEAD         GPIO_NUM_41

/* LED Light PWM */
#define PIN_LED_COLD                GPIO_NUM_42
#define PIN_LED_WARM                GPIO_NUM_45

/* User keys */
#define PIN_KEY_WAKE                GPIO_NUM_0
#define PIN_KEY_MODE                GPIO_NUM_46

/* Audio */
#define AUDIO_SAMPLE_RATE           16000
#define AUDIO_FRAME_MS              20
#define AUDIO_FRAME_SAMPLES         (AUDIO_SAMPLE_RATE * AUDIO_FRAME_MS / 1000)

六、主程序框架

复制代码
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"

#include "board_config.h"
#include "wifi_manager.h"
#include "audio_capture.h"
#include "audio_player.h"
#include "camera_service.h"
#include "vision_service.h"
#include "arm_servo.h"
#include "lamp_light.h"
#include "sensor_service.h"
#include "study_assistant.h"
#include "ai_ws_client.h"
#include "mcp_service.h"
#include "lcd_ui.h"
#include "ota_service.h"

static const char *TAG = "AI_ARM_LAMP";

void app_main(void)
{
    ESP_LOGI(TAG, "%s booting...", BOARD_NAME);

    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    lcd_ui_init();
    lcd_ui_show_status("四博AI机械臂台灯启动中");

    wifi_manager_init();
    audio_capture_init();
    audio_player_init();

    camera_service_init();
    vision_service_init();

    arm_servo_init();
    lamp_light_init();
    sensor_service_init();
    study_assistant_init();

    ai_ws_client_init();
    mcp_service_init();
    ota_service_init();

    wifi_manager_start();

    xTaskCreatePinnedToCore(audio_capture_task,
                            "audio_capture",
                            8192,
                            NULL,
                            5,
                            NULL,
                            0);

    xTaskCreatePinnedToCore(ai_ws_client_task,
                            "ai_ws_client",
                            10240,
                            NULL,
                            6,
                            NULL,
                            1);

    xTaskCreatePinnedToCore(camera_service_task,
                            "camera_service",
                            8192,
                            NULL,
                            4,
                            NULL,
                            1);

    xTaskCreatePinnedToCore(vision_service_task,
                            "vision_service",
                            8192,
                            NULL,
                            4,
                            NULL,
                            1);

    xTaskCreatePinnedToCore(sensor_service_task,
                            "sensor_service",
                            4096,
                            NULL,
                            3,
                            NULL,
                            0);

    xTaskCreatePinnedToCore(ota_service_task,
                            "ota_service",
                            6144,
                            NULL,
                            3,
                            NULL,
                            0);

    arm_servo_home();
    lamp_set_brightness_color_temp(60, 4000);

    g_sys_state = SYS_STATE_IDLE;
    lcd_ui_show_status("AI台灯已就绪");
}

七、视觉功能设计:看窗外天气和周边环境

1. 视觉能力定义

四博 AI 机械臂台灯的视觉功能可以分成三类:

复制代码
1. 窗外天气观察
   - 识别晴天 / 阴天 / 雨天 / 夜晚
   - 判断窗外亮度
   - 辅助决定是否需要开灯

2. 周边环境识别
   - 识别用户是否在座位
   - 识别桌面是否过暗
   - 识别书本 / 作业区域
   - 判断是否适合学习

3. 学习陪伴
   - 拍摄书本或作业区域
   - 提醒坐姿和学习时长
   - 结合大模型进行语音讲解

多模态 AI 开发宝典中的 DOIT_ESPS3_AI_EYE_Vision 方案已经提供摄像头、双目显示、触摸交互和 ESP32-S3 开发路径,适合作为视觉 AI 终端开发参考。

2. 摄像头初始化示例

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

esp_err_t camera_service_init(void)
{
    camera_config_t config = {
        .pin_xclk = PIN_CAM_XCLK,
        .pin_pclk = PIN_CAM_PCLK,
        .pin_vsync = PIN_CAM_VSYNC,
        .pin_href = PIN_CAM_HREF,

        .pin_sscb_sda = PIN_CAM_SIOD,
        .pin_sscb_scl = PIN_CAM_SIOC,

        .pin_d0 = PIN_CAM_D0,
        .pin_d1 = PIN_CAM_D1,
        .pin_d2 = PIN_CAM_D2,
        .pin_d3 = PIN_CAM_D3,
        .pin_d4 = PIN_CAM_D4,
        .pin_d5 = PIN_CAM_D5,
        .pin_d6 = PIN_CAM_D6,
        .pin_d7 = PIN_CAM_D7,

        .pin_pwdn = -1,
        .pin_reset = -1,

        .xclk_freq_hz = 20000000,
        .pixel_format = PIXFORMAT_JPEG,
        .frame_size = FRAMESIZE_QVGA,
        .jpeg_quality = 12,
        .fb_count = 2,
        .grab_mode = CAMERA_GRAB_LATEST,
    };

    return esp_camera_init(&config);
}

3. 拍照并上传 AI 视觉分析

复制代码
esp_err_t vision_capture_and_upload(const char *task)
{
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
        lcd_ui_show_status("摄像头采集失败");
        return ESP_FAIL;
    }

    /*
     * task 可选:
     * "weather_view"  看窗外天气
     * "desk_view"     看桌面环境
     * "study_help"    学习陪伴识别
     */
    esp_err_t ret = ai_ws_send_image(task, fb->buf, fb->len);

    esp_camera_fb_return(fb);
    return ret;
}

4. 视觉任务调度

复制代码
typedef enum {
    VISION_TASK_NONE = 0,
    VISION_TASK_WEATHER,
    VISION_TASK_DESK_ENV,
    VISION_TASK_STUDY_HELP,
    VISION_TASK_USER_POSITION
} vision_task_t;

void vision_run_task(vision_task_t task)
{
    switch (task) {
    case VISION_TASK_WEATHER:
        lcd_ui_show_status("正在观察窗外天气");
        vision_capture_and_upload("weather_view");
        break;

    case VISION_TASK_DESK_ENV:
        lcd_ui_show_status("正在分析桌面环境");
        vision_capture_and_upload("desk_view");
        break;

    case VISION_TASK_STUDY_HELP:
        lcd_ui_show_status("正在分析学习内容");
        vision_capture_and_upload("study_help");
        break;

    case VISION_TASK_USER_POSITION:
        lcd_ui_show_status("正在检测用户位置");
        vision_capture_and_upload("user_position");
        break;

    default:
        break;
    }
}

八、机械臂控制设计

机械臂台灯的关键是"灯头可以动"。它可以自动转向用户、书本、窗户或指定方向。

1. 自由度设计

推荐机械结构:

复制代码
2 自由度:底座左右旋转 + 灯头俯仰
3 自由度:底座旋转 + 大臂俯仰 + 灯头俯仰
4 自由度:底座旋转 + 大臂 + 小臂 + 灯头

舵机控制结构:

复制代码
typedef enum {
    SERVO_BASE = 0,
    SERVO_SHOULDER,
    SERVO_ELBOW,
    SERVO_HEAD,
    SERVO_MAX
} servo_id_t;

typedef struct {
    gpio_num_t gpio;
    int min_angle;
    int max_angle;
    int current_angle;
    ledc_channel_t channel;
} servo_t;

static servo_t g_servos[SERVO_MAX] = {
    [SERVO_BASE] = {
        .gpio = PIN_SERVO_BASE,
        .min_angle = 0,
        .max_angle = 180,
        .current_angle = 90,
        .channel = LEDC_CHANNEL_0,
    },
    [SERVO_SHOULDER] = {
        .gpio = PIN_SERVO_SHOULDER,
        .min_angle = 20,
        .max_angle = 160,
        .current_angle = 90,
        .channel = LEDC_CHANNEL_1,
    },
    [SERVO_ELBOW] = {
        .gpio = PIN_SERVO_ELBOW,
        .min_angle = 20,
        .max_angle = 160,
        .current_angle = 90,
        .channel = LEDC_CHANNEL_2,
    },
    [SERVO_HEAD] = {
        .gpio = PIN_SERVO_LAMP_HEAD,
        .min_angle = 30,
        .max_angle = 150,
        .current_angle = 90,
        .channel = LEDC_CHANNEL_3,
    },
};

2. 舵机 PWM 输出

复制代码
#define SERVO_MIN_US       500
#define SERVO_MAX_US       2500
#define SERVO_PERIOD_US    20000

static uint32_t servo_angle_to_duty(int angle)
{
    int pulse_us = SERVO_MIN_US +
                   (SERVO_MAX_US - SERVO_MIN_US) * angle / 180;

    /*
     * LEDC 16bit 分辨率
     */
    return (uint32_t)((pulse_us * 65535) / SERVO_PERIOD_US);
}

void servo_set_angle(servo_id_t id, int angle)
{
    if (id >= SERVO_MAX) {
        return;
    }

    servo_t *s = &g_servos[id];

    if (angle < s->min_angle) {
        angle = s->min_angle;
    }

    if (angle > s->max_angle) {
        angle = s->max_angle;
    }

    uint32_t duty = servo_angle_to_duty(angle);

    ledc_set_duty(LEDC_LOW_SPEED_MODE, s->channel, duty);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, s->channel);

    s->current_angle = angle;
}

3. 机械臂初始化

复制代码
void arm_servo_init(void)
{
    ledc_timer_config_t timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_0,
        .duty_resolution = LEDC_TIMER_16_BIT,
        .freq_hz = 50,
        .clk_cfg = LEDC_AUTO_CLK,
    };
    ledc_timer_config(&timer);

    for (int i = 0; i < SERVO_MAX; i++) {
        ledc_channel_config_t ch = {
            .gpio_num = g_servos[i].gpio,
            .speed_mode = LEDC_LOW_SPEED_MODE,
            .channel = g_servos[i].channel,
            .timer_sel = LEDC_TIMER_0,
            .duty = 0,
            .hpoint = 0,
        };
        ledc_channel_config(&ch);
    }

    arm_servo_home();
}

void arm_servo_home(void)
{
    servo_set_angle(SERVO_BASE, 90);
    servo_set_angle(SERVO_SHOULDER, 90);
    servo_set_angle(SERVO_ELBOW, 90);
    servo_set_angle(SERVO_HEAD, 90);
}

4. 常用动作

复制代码
void arm_point_to_book(void)
{
    servo_set_angle(SERVO_BASE, 90);
    servo_set_angle(SERVO_SHOULDER, 70);
    servo_set_angle(SERVO_ELBOW, 110);
    servo_set_angle(SERVO_HEAD, 80);
}

void arm_point_to_window(void)
{
    servo_set_angle(SERVO_BASE, 150);
    servo_set_angle(SERVO_SHOULDER, 85);
    servo_set_angle(SERVO_ELBOW, 95);
    servo_set_angle(SERVO_HEAD, 75);
}

void arm_sleep_pose(void)
{
    servo_set_angle(SERVO_BASE, 90);
    servo_set_angle(SERVO_SHOULDER, 130);
    servo_set_angle(SERVO_ELBOW, 140);
    servo_set_angle(SERVO_HEAD, 120);
}

九、灯光控制设计

台灯部分建议支持:

复制代码
亮度调节:0~100%
色温调节:2700K~6500K
学习模式:高亮中性光
阅读模式:柔和暖白光
休息模式:低亮暖光
自动模式:根据环境光自动调节

1. 灯光参数结构

复制代码
typedef struct {
    int brightness;     // 0~100
    int color_temp;     // 2700~6500
    int auto_mode;
} lamp_config_t;

static lamp_config_t g_lamp = {
    .brightness = 60,
    .color_temp = 4000,
    .auto_mode = 0,
};

2. 冷暖光 PWM 控制

复制代码
void lamp_light_init(void)
{
    ledc_timer_config_t timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_1,
        .duty_resolution = LEDC_TIMER_12_BIT,
        .freq_hz = 2000,
        .clk_cfg = LEDC_AUTO_CLK,
    };
    ledc_timer_config(&timer);

    ledc_channel_config_t cold = {
        .gpio_num = PIN_LED_COLD,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_4,
        .timer_sel = LEDC_TIMER_1,
        .duty = 0,
        .hpoint = 0,
    };

    ledc_channel_config_t warm = {
        .gpio_num = PIN_LED_WARM,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_5,
        .timer_sel = LEDC_TIMER_1,
        .duty = 0,
        .hpoint = 0,
    };

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

3. 设置亮度和色温

复制代码
void lamp_set_brightness_color_temp(int brightness, int color_temp)
{
    if (brightness < 0) brightness = 0;
    if (brightness > 100) brightness = 100;

    if (color_temp < 2700) color_temp = 2700;
    if (color_temp > 6500) color_temp = 6500;

    /*
     * 2700K 主要暖光,6500K 主要冷光。
     */
    float ratio = (float)(color_temp - 2700) / (6500 - 2700);

    int cold_percent = brightness * ratio;
    int warm_percent = brightness * (1.0f - ratio);

    uint32_t cold_duty = cold_percent * 4095 / 100;
    uint32_t warm_duty = warm_percent * 4095 / 100;

    ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4, cold_duty);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4);

    ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5, warm_duty);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5);

    g_lamp.brightness = brightness;
    g_lamp.color_temp = color_temp;
}

4. 学习模式 / 阅读模式 / 休息模式

复制代码
void lamp_mode_study(void)
{
    lamp_set_brightness_color_temp(85, 4500);
    arm_point_to_book();
    lcd_ui_show_status("学习模式已开启");
}

void lamp_mode_reading(void)
{
    lamp_set_brightness_color_temp(70, 4000);
    arm_point_to_book();
    lcd_ui_show_status("阅读模式已开启");
}

void lamp_mode_rest(void)
{
    lamp_set_brightness_color_temp(25, 3000);
    arm_sleep_pose();
    lcd_ui_show_status("休息模式已开启");
}

十、AI 语音与 WebSocket 通信

推荐采用 WebSocket 长连接,实现低延迟语音交互、视觉任务下发、TTS 音频回传和 MCP 工具调用。

1. 设备上线消息

复制代码
{
  "type": "hello",
  "device_id": "doit_ai_arm_lamp_001",
  "product": "doit_ai_arm_lamp",
  "firmware": "1.0.0",
  "features": {
    "audio": true,
    "vision": true,
    "arm": true,
    "lamp": true,
    "study_assistant": true,
    "weather_view": true,
    "mcp": true,
    "ota": true
  }
}

2. AI 消息处理

复制代码
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, "tts_start") == 0) {
            audio_player_start();
            lcd_ui_show_status("AI正在回答");
        } else if (strcmp(type->valuestring, "tts_end") == 0) {
            audio_player_stop();
            lcd_ui_show_status("等待指令");
        } else if (strcmp(type->valuestring, "tool_call") == 0) {
            mcp_service_handle(root);
        } else if (strcmp(type->valuestring, "vision_result") == 0) {
            vision_handle_result(root);
        }
    }

    cJSON_Delete(root);
    free(buf);
}

十一、MCP 工具调用设计

用户可以直接说:

复制代码
看一下窗外天气
帮我把灯调亮一点
进入学习模式
把灯头转向书本
看一下桌面环境
提醒我学习 30 分钟后休息
打开客厅灯

AI 后端返回 MCP 工具调用:

复制代码
{
  "type": "tool_call",
  "tool": "lamp.set_mode",
  "arguments": {
    "mode": "study"
  }
}

1. MCP 工具定义

复制代码
typedef enum {
    MCP_TOOL_LAMP_SET_MODE = 0,
    MCP_TOOL_LAMP_SET_LIGHT,
    MCP_TOOL_ARM_MOVE,
    MCP_TOOL_VISION_CAPTURE,
    MCP_TOOL_STUDY_TIMER,
    MCP_TOOL_HOME_CONTROL,
    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[] = {
    {"lamp.set_mode",       MCP_TOOL_LAMP_SET_MODE},
    {"lamp.set_light",      MCP_TOOL_LAMP_SET_LIGHT},
    {"arm.move",            MCP_TOOL_ARM_MOVE},
    {"vision.capture",      MCP_TOOL_VISION_CAPTURE},
    {"study.timer",         MCP_TOOL_STUDY_TIMER},
    {"home.device.control", MCP_TOOL_HOME_CONTROL},
};

2. 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_LAMP_SET_MODE:
        mcp_handle_lamp_set_mode(args);
        break;

    case MCP_TOOL_LAMP_SET_LIGHT:
        mcp_handle_lamp_set_light(args);
        break;

    case MCP_TOOL_ARM_MOVE:
        mcp_handle_arm_move(args);
        break;

    case MCP_TOOL_VISION_CAPTURE:
        mcp_handle_vision_capture(args);
        break;

    case MCP_TOOL_STUDY_TIMER:
        mcp_handle_study_timer(args);
        break;

    case MCP_TOOL_HOME_CONTROL:
        mcp_handle_home_control(args);
        break;

    default:
        lcd_ui_show_status("未知工具调用");
        break;
    }
}

3. 灯光模式 MCP

复制代码
void mcp_handle_lamp_set_mode(cJSON *args)
{
    cJSON *mode = cJSON_GetObjectItem(args, "mode");

    if (!cJSON_IsString(mode)) {
        return;
    }

    if (strcmp(mode->valuestring, "study") == 0) {
        lamp_mode_study();
    } else if (strcmp(mode->valuestring, "reading") == 0) {
        lamp_mode_reading();
    } else if (strcmp(mode->valuestring, "rest") == 0) {
        lamp_mode_rest();
    }
}

4. 视觉任务 MCP

复制代码
void mcp_handle_vision_capture(cJSON *args)
{
    cJSON *task = cJSON_GetObjectItem(args, "task");

    if (!cJSON_IsString(task)) {
        return;
    }

    if (strcmp(task->valuestring, "weather") == 0) {
        arm_point_to_window();
        vision_run_task(VISION_TASK_WEATHER);
    } else if (strcmp(task->valuestring, "desk") == 0) {
        arm_point_to_book();
        vision_run_task(VISION_TASK_DESK_ENV);
    } else if (strcmp(task->valuestring, "study") == 0) {
        arm_point_to_book();
        vision_run_task(VISION_TASK_STUDY_HELP);
    }
}

十二、学习陪伴设计

学习陪伴不是简单聊天,而是要形成"灯光 + 语音 + 视觉 + 计时 + 提醒"的闭环。

学习场景流程

复制代码
用户:开始学习模式
   ↓
台灯自动转向桌面
   ↓
灯光调到 85% / 4500K
   ↓
摄像头检测桌面环境
   ↓
AI 开始学习陪伴
   ↓
每 30 分钟提醒休息
   ↓
发现环境过暗时自动补光

学习任务结构

复制代码
typedef struct {
    int active;
    int duration_min;
    int rest_interval_min;
    int elapsed_sec;
} study_session_t;

static study_session_t g_study = {
    .active = 0,
    .duration_min = 45,
    .rest_interval_min = 30,
    .elapsed_sec = 0,
};

学习模式启动

复制代码
void study_assistant_start(int duration_min)
{
    g_study.active = 1;
    g_study.duration_min = duration_min;
    g_study.elapsed_sec = 0;

    lamp_mode_study();
    arm_point_to_book();

    vision_run_task(VISION_TASK_DESK_ENV);

    audio_player_play_prompt("study_start.wav");
    lcd_ui_show_status("学习陪伴已开启");
}

学习提醒任务

复制代码
void study_assistant_task(void *arg)
{
    while (1) {
        if (g_study.active) {
            g_study.elapsed_sec++;

            if (g_study.elapsed_sec % (30 * 60) == 0) {
                audio_player_play_prompt("take_a_break.wav");
                lcd_ui_show_status("学习30分钟了,休息一下眼睛");
                lamp_set_brightness_color_temp(40, 3500);
            }

            if (g_study.elapsed_sec >= g_study.duration_min * 60) {
                g_study.active = 0;
                audio_player_play_prompt("study_finish.wav");
                lcd_ui_show_status("本次学习完成");
                lamp_mode_rest();
            }
        }

        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

十三、窗外天气识别逻辑

1. 本地初筛

本地可以先通过摄像头画面亮度做简单判断:

复制代码
typedef enum {
    WEATHER_UNKNOWN = 0,
    WEATHER_SUNNY,
    WEATHER_CLOUDY,
    WEATHER_RAINY,
    WEATHER_NIGHT
} visual_weather_t;

visual_weather_t vision_estimate_weather_local(uint8_t *gray, int width, int height)
{
    int64_t sum = 0;
    int pixels = width * height;

    for (int i = 0; i < pixels; i++) {
        sum += gray[i];
    }

    int avg = sum / pixels;

    if (avg < 40) {
        return WEATHER_NIGHT;
    } else if (avg > 160) {
        return WEATHER_SUNNY;
    } else if (avg > 80) {
        return WEATHER_CLOUDY;
    }

    return WEATHER_UNKNOWN;
}

2. 云端视觉结果处理

复制代码
void vision_handle_result(cJSON *root)
{
    cJSON *task = cJSON_GetObjectItem(root, "task");
    cJSON *result = cJSON_GetObjectItem(root, "result");

    if (!cJSON_IsString(task) || !cJSON_IsString(result)) {
        return;
    }

    if (strcmp(task->valuestring, "weather_view") == 0) {
        char text[128];

        snprintf(text, sizeof(text),
                 "窗外环境:%s",
                 result->valuestring);

        lcd_ui_show_status(text);
        audio_player_tts(text);
    }

    if (strcmp(task->valuestring, "desk_view") == 0) {
        if (strstr(result->valuestring, "过暗")) {
            lamp_set_brightness_color_temp(85, 4500);
            audio_player_tts("当前桌面偏暗,已为你调亮台灯。");
        }
    }
}

十四、OTA 与量产升级

四博 AI 开发宝典中包含 ESP-IDF 开发环境搭建、开源工程编译、烧录、配网、OTA、实时打断、自定义唤醒词等开发章节,适合客户进行二次开发和量产前验证。

OTA 版本文件

复制代码
{
  "project": "doit_ai_arm_lamp_s3",
  "version": "1.0.3",
  "chip": "esp32s3",
  "url": "https://ota.customer.com/arm_lamp_s3_v1.0.3.bin",
  "asset_url": "https://ota.customer.com/assets/arm_lamp_assets_v3.bin",
  "md5": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "force": false,
  "note": "新增视觉天气识别、学习陪伴和机械臂动作优化"
}

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/arm_lamp/latest.bin",
        .timeout_ms = 10000,
        .keep_alive_enable = true,
    };

    esp_https_ota_config_t ota_config = {
        .http_config = &http_config,
    };

    lcd_ui_show_status("正在升级,请勿断电");

    esp_err_t ret = esp_https_ota(&ota_config);

    if (ret == ESP_OK) {
        lcd_ui_show_status("升级成功,正在重启");
        esp_restart();
    } else {
        lcd_ui_show_status("升级失败");
    }
}

十五、方案核心价值

四博 AI 机械臂台灯智能音箱方案的价值在于,它把原本分散的能力整合成一个桌面 AI 终端:

复制代码
1. 视觉能力:能看窗外天气、桌面环境、学习状态
2. 语音能力:能对话、问答、提醒、陪伴
3. 照明能力:能调亮度、调色温、自动补光
4. 机械臂能力:能转向书本、窗户、用户位置
5. 学习陪伴:能做学习计时、休息提醒、知识讲解
6. 智能家居:能通过 MCP 控制灯具、窗帘、空调等设备
7. 二次开发:基于 ESP32-S3 和 ESP-IDF,方便客户定制
8. 量产升级:支持 OTA、素材更新、参数更新和客户系统接入

一句话总结:

复制代码
四博 AI 机械臂台灯不是普通台灯,
也不是普通 AI 音箱,
而是基于 ESP32-S3 打造的视觉感知、机械臂控制、
智能照明和学习陪伴一体化 AI 桌面终端。
相关推荐
qq_411262421 小时前
基于 ESP32-S3 + VB6824 的四博三模联网 AI 智能音箱方案设计
人工智能·智能音箱
qq_411262421 小时前
四博 AI 双目智能音箱技术方案
人工智能·智能音箱
甲维斯1 小时前
测一波MiMo 2.5 Pro,看看真实实力!
人工智能
qq_411262422 小时前
四博 AI 双目智能音箱技术拆解
人工智能·智能音箱
xwz小王子2 小时前
Science Robotics 让机器人学会“削果皮”:一种曲面物体操作任务转移的新方法
人工智能·机器人
qq_411262422 小时前
四博 AI 双目智能音箱方案:从“会说话”升级到“有感知、有表情、有反馈”的 AI 硬件平台
人工智能·智能音箱
xiaoduo AI2 小时前
客服机器人非工作时间能休眠?智能Agent开放平台定时唤醒,无人值守省资源?
大数据·人工智能·机器人
这张生成的图像能检测吗2 小时前
(论文速读)IMSE-IGA-CNN-Transformer
人工智能·深度学习·cnn·transformer·故障诊断·预测模型·时序模型
冬奇Lab2 小时前
RAG 系列(一):大模型为什么需要「外挂记忆」
人工智能·llm