【ESP32接入国产豆包大模型控制灯和舵机】
-
- 前言
- 1. 豆包大模型
-
- 1.1 方舟定位
- 1. 极速体验
- 1.3 深度思考
- 2.1 环境配置
- 2.2 所需零件
- 3. 核心代码
-
- 3.1 源码分享
- 3.2 源码解析
- 4. 上传验证
-
- 4.1 platformio.ini
- 4.2 对话测试
- 4.3 错误码
- 5. 总结
前言
随着国产大语言模型的发展,我们不仅可以用它来回答问题、写代码,还可以让它直接控制硬件设备。这个是基于【ESP32接入国产大模型之豆包】升级的哦!😘😘😘💕💕💕
用 ESP32 接入“豆包”国产大模型,实现通过自然语言控制 LED 灯亮度和舵机角度!
首先声明没有恰饭广告,源代码已经匿名处理,制作细节非常完善,方便大家复刻才会提供快捷的相关链接跳转!!!😘😘😘
本文将重点介绍如何通过ESP32S3接入国产大模型之豆包升级版。
上一篇博客已经分享了: 【ESP32接入国产大模型之腾讯混元】 【ESP32接入国产大模型之豆包】 【ESP32接入国产大模型之星火】 【ESP32接入国产大模型之MiniMax】 【ESP32接入语言大模型之智谱清言】 【ESP32接入国产大模型之文心一言】 【ESP32接入语言大模型之通义千问】 【ESP32接入国产大模型之kimi】 【ESP32接入国产大模型之Deepseek】 【ESP32接入国产大模型之阿里Deepseek】 【ESP32接入国产大模型之豆包升级版】
下面是不标准测评,参考而已:
豆包 | 2s | 9分 | 50万 | https://www.volcengine.com/product/doubao |
讯飞星火 | 4s | 8分 | 1亿 | https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html |
MiniMax | 3s | 8分 | 500万 | https://www.minimaxi.com/ |
智谱清言 | 7s | 7分 | 300万 | https://open.bigmodel.cn/ |
文心一言 | 10s | 7分 | 500万 | https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu |
通义千问 | 8s | 7分 | 800万 | https://tongyi.aliyun.com/qianwen/ |
Kimi | 2s | 9分 | 50万 | https://platform.moonshot.cn/docs/guide/start-using-kimi-api |
混元 | 6s | 8分 | 50万 | https://cloud.tencent.com/document/product/1729/105701 |
Deepseek | 12s | 9分 | 50万 | https://api-docs.deepseek.com/ |
阿里Deepseek | 10s | 9分 | 50万 | https://help.aliyun.com/zh/model-studio/developer-reference/deepseek?spm=a2c4g.11186623.help-menu-search-2400256.d_1#2048aa1f92x46 |
这一次还是采用Platformio编程就会轻松许多开发。这样就可以把大模型装进口袋啦🤣🤣🤣
1. 豆包大模型
请大家点击豆包火山注册地址,不注册是不能完成下面的实验哦:https://t.vncps.com/5LOve 谢谢啦大家的支持💖💖💖
豆包与火山方舟、火山引擎之间的关系主要体现为技术同源、产品定位互补,三者均隶属于字节跳动旗下。具体联系如下:
🛠️ 1. 火山引擎:底层技术基座
定位:字节跳动推出的企业级云服务平台,提供云计算、大数据、AI 中台、容器服务等基础技术能力。 功能:为火山方舟提供算力支持(GPU 集群)、模型训练 / 推理框架、数据存储等基础设施。 关系:是豆包和火山方舟的技术底层支撑。
🤖 2. 豆包:AI 产品化终端应用
定位:面向公众的AI 对话助手(类似 ChatGPT),可提供问答、写作、编程等能力。 技术来源:依赖于火山引擎的算力资源及自研大模型(如 Skywork 天工、Cloud 系列模型)。 产品形态:直接向用户提供服务的 C 端应用(网页 / App),如 doubao.com。
🔧 3. 火山方舟:AI 模型开发与服务平台
定位:聚焦于企业级 AI 模型的开发、部署与管理平台(类似百度文心千帆)。 核心功能: 模型接入:支持集成第三方大模型(如百川、MiniMax)。 工具链:提供模型精调(Fine-tuning)、评测、API 部署等工具。 场景方案:针对企业需求定制客服、营销等 AI 解决方案。 与豆包的联系: 技术同源:共用火山引擎的 AI 训练框架和推理加速技术。 能力互补:企业可通过火山方舟训练模型,再以 SDK/API 形式接入自身产品(如集成类似豆包的聊天功能)。 模型共享:豆包的底层模型可能通过火山方舟向企业客户开放定制。
产品简介:https://www.volcengine.com/docs/82379/1099455
1.1 方舟定位
为您提供大模型服务的开发平台,提供功能丰富、安全以及具备价格竞争力的模型调用服务,同时提供模型数据、精调、推理、评测等端到端功能,全方位保障您的 AI 应用开发落地。
1. 极速体验
您可以访问火山方舟大模型体验中心,免登录极速体验模型能力。 点击页面中心的模型切换按钮,可以切换体验Doubao或DeepSeek系列模型能力。 未登录状态下可以体验部分模型。如果您需要体验所有模型能力,建议您登录火山引擎账号,选择并开通模型。
点击开启MCP服务器,可以连接使用更多火山云产品与三方工具。 您也可以尝试选择下方的图片理解任务进行尝试。
1.3 深度思考
官方文档:https://www.volcengine.com/docs/82379/1449737 您可以使用具备深度思考能力的模型,如 deepseek r1、doubao thinking 系列模型,来提升最终答案的准确性。模型在回答问题前,会对问题进行分析和拆解,并基于对问题的拆解回答问题,回答会更加全面和深入。当您向模型提问时,方舟返回模型回答问题前的问题思考逻辑(思维链内容),基于此可观察模型推导过程并使用这部分信息。
2.1 环境配置
2.2 所需零件
要学习本教程,您需要1个 ESP32 开发板或者ESP32C3,建议使用后者,笔者发现同样的代码后者可以轻松调用,ESP32不行(可能板子坏了)。
目前这是我使用的ESP32S3官方硬件👍👍👍(小小的身材有大大的力量)只需要35元加摄像头麦克风79元,后期我会整理相关专栏进行Arduino系统学习😘😘😘。有需要可以购买xiao开发板💕💕💕
SeeedXIAO ESP32S3 Sense硬件购买地址:https://s.click.taobao.com/lekazrt
ESP32-S3-CAM 核心开发板 N16R8 wifi蓝牙模块 OV2640摄像头硬件购买地址:https://s.click.taobao.com/1PTagos


上面硬件丝选一,我是第四款硬件
舵机选择,sg90舵机小型航模大扭力舵机伺服控制模块MG90S微型经典舵机云台 【下单链接】https://s.click.taobao.com/gbAzFmq
LED 引脚接 ESP32 的 GPIO2(可改),这个第四块开发板自带管脚2的LED
舵机信号线接 GPIO3(可改)
GND 公共接地
舵机电源建议单独供电(防止电流过大重启)
3. 核心代码
对话参考案例:https://www.volcengine.com/docs/82379/1449737 请求数据
curl https://ark.cn-beijing.volces.com/api/v3/chat/completions \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer $ARK_API_KEY" \\
-d '{
"model": "doubao-seed-1-6-250615",
"messages": [
{
"role": "user",
"content": "我要研究深度思考模型与非深度思考模型区别的课题,怎么体现我的专业性"
}
]
}'
3.1 源码分享
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <driver/ledc.h>
#include <esp_task_wdt.h> // 看门狗
#include <ESP32Servo.h>
#define LED_PIN 2
#define SERVO_PIN 3
Servo myservo;
const char *ssid = "IQOO";
const char *password = "12345678";
String apiKey = "Bearer 211f9e11-cd39-4a68-b625-b7964a605";
String apiUrl = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
String pre_Text = "如果用户需要控制灯或者舵机,请参考以下格式回复硬件控制指令:1. LED控制(device:led,value:0-255);2. 舵机控制(device:servo,value:0-180);3. 其他回答:直接返回文本内容";
QueueHandle_t xCommandQueue;
struct Command {
String device;
int value;
};
void initPWM() {
ledcSetup(1, 50, 14);
ledcAttachPin(SERVO_PIN, 1);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, 100);
}
void controlTask(void *pvParameters) {
Command cmd;
while (1) {
if (xQueueReceive(xCommandQueue, &cmd, portMAX_DELAY)) {
if (cmd.device == "led") {
analogWrite(LED_PIN, cmd.value);
Serial.printf("[执行] LED亮度: %d\\n", cmd.value);
} else if (cmd.device == "servo") {
int pulseWidth = map(cmd.value, 0, 180, 1000, 5000);
ledcWrite(1, pulseWidth * 8192 / 20000);
Serial.printf("[执行] 舵机角度: %d°\\n", cmd.value);
}
}
esp_task_wdt_reset();
}
}
void parseAndQueue(String response) {
Serial.println("[原始回答]: " + response);
if (response.indexOf("device:") != –1 && response.indexOf("value:") != –1) {
int deviceStart = response.indexOf("device:") + 7;
int deviceEnd = response.indexOf(",", deviceStart);
String device = response.substring(deviceStart, deviceEnd);
int valueStart = response.indexOf("value:") + 6;
int valueEnd = response.indexOf(")", valueStart);
int value = response.substring(valueStart, valueEnd).toInt();
if (device == "led") value = constrain(value, 0, 255);
if (device == "servo") value = constrain(value, 0, 180);
Command cmd = {device, value};
xQueueSend(xCommandQueue, &cmd, 0);
return;
}
Serial.println("[AI回答]: " + response);
}
String getGPTAnswer(String inputText) {
HTTPClient http;
http.setTimeout(10000);
http.setReuse(false);
http.begin(apiUrl);
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", apiKey);
String payload = "{\\"model\\":\\"doubao-seed-1-6-250615\\",\\"messages\\":[{\\"role\\": \\"system\\",\\"content\\": \\"" + pre_Text + "\\"},{\\"role\\": \\"user\\",\\"content\\": \\"" + inputText + "\\"}]}";
int httpResponseCode = http.POST(payload);
if (httpResponseCode == 200) {
String response = http.getString();
http.end();
return response;
} else {
http.end();
Serial.printf("Error %i \\n", httpResponseCode);
return "<error>";
}
}
void httpTask(void *pvParameters) {
while (1) {
if (Serial.available()) {
String userInput = Serial.readStringUntil('\\n');
userInput.trim();
String response = getGPTAnswer(userInput);
parseAndQueue(response);
}
esp_task_wdt_reset();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
initPWM();
xCommandQueue = xQueueCreate(5, sizeof(Command));
esp_task_wdt_init(10, true);
esp_task_wdt_add(NULL);
xTaskCreatePinnedToCore(controlTask, "Control", 4096, NULL, 2, NULL, 0);
xTaskCreatePinnedToCore(httpTask, "HTTP", 8192, NULL, 1, NULL, 1);
Serial.println("系统初始化完成,输入指令开始控制硬件!");
}
void loop() {
esp_task_wdt_reset();
delay(1000);
}
3.2 源码解析
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char *ssid = "IQOO";
const char *password = "12345678";
const char* apiKey = "211f9e11-cd39-4a68-b625-b7964a605";
4. 上传验证
下面给出下载配置,请严格配置
4.1 platformio.ini
[env:freenove_esp32_s3_wroom]
platform = espressif32
board = freenove_esp32_s3_wroom
framework = arduino
lib_deps =
bblanchon/ArduinoJson@^7.4.2
madhephaestus/ESP32Servo@^3.0.8
4.2 对话测试
打开串口监视器,注意右下角选择回车符,选择115200波特率,输入你想问的问题,它就可以回答你。
把舵机转到45度
AI 响应:
(device:servo,value:45)
控制任务输出:
[执行] 舵机角度: 45°
LED 灯控制同理,例如:
灯亮度调成一半
会解析为:
(device:led,value:128)
—- 已发送 utf8 编码消息: "把舵机转到45度\\n" —-
[原始回答]: {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"舵机控制(device:servo,value:45)","reasoning_content":"\\n用户的需求是把舵机转��45度,根据提供的格式,舵机控制的指令应该是(device:servo,value:0-180),这里value需要是45,所以直��按照格式生成指令即可。","role":"assistant"}}],"created":1754834733,"id":"02175483473136881cc4b220e2c57abddebb2bf8b39604062e56c","model":"doubao-seed-1-6-250615","service_tier":"default","object":"chat.completion","usage":{"completion_tokens":66,"prompt_tokens":156,"total_tokens":222,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":54}}}
[执行] 舵机角度设置为: 45°
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xf (BROWNOUT_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x4bc
load:0x403c9700,len:0xbd8
load:0x403cc700,len:0x2a0c
entry 0x403c98d0
Connecting to WiFi ...192.168.3.168
系统初始化完成,输入问题开始控制���件!
—- 已发送 utf8 编码消息: "灯亮度调成一半\\n" —-
[原始回答]: {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"1. LED控制(device:led,value:127);","reasoning_content":"\\n用户需要将灯亮度调成��半,首先明确这是LED控制。根据格式要求,LED控制的device是led,value范围是0-255。亮度一半的话,255的一半是127.5,通常取整数127或128,这里一般��127比较常见,所以value设为127。按照格式回复即���。","role":"assistant"}}],"created":1754834748,"id":"02175483474322406c34bbe28664ccbcf41b403b5de5e3d24eeb0","model":"doubao-seed-1-6-250615","service_tier":"default","object":"chat.completion","usage":{"completion_tokens":101,"prompt_tokens":153,"total_tokens":254,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":87}}}
[执行] LED亮��设置为: 127
—- 已发送 utf8 编码消息: "关闭灯\\n" —-
[原始回答]: {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"1. LED控制(device:led,value:0);","reasoning_content":"\\n用户需要关闭灯,根据提���的格式,LED控制的value是0-255,关闭灯应该设置value为0。所以按照格式回复LED控制指令,device是led,value是0。","role":"assistant"}}],"created":1754834764,"id":"021754834762165727172d4b0156b3bd207c1a99dc67750d0684a","model":"doubao-seed-1-6-250615","service_tier":"default","object":"chat.completion","usage":{"completion_tokens":59,"prompt_tokens":151,"total_tokens":210,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":47}}}
[执行] LED亮度设置为: 0
—- 已发送 utf8 编码消息: "把舵机转到0度\\n" —-
[原始回答]: {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"舵机控制(device:servo,value:0)","reasoning_content":"\\n我现在需要处理用户的请求“把舵机转到0度”。首先,根据系统提示,如果用户需要控制灯或舵机,应该使用特定的硬件���制指令格式。用户的请求明确是舵机控制,目��角度是0度。\\n\\n系统提示中给出的舵机控制格式���:舵机控制(device:servo,value:0-180)。这里value的范���是0到180,用户要求的0度在这个范围内,所以直接套用格式即可。不需要其他额外的文本内容,���需按照指定格式生成指令。\\n\\n确认没有其他需���补充的信息,用户的需求非常明确,就是控制��机到0度。因此,最终的回复应该是“舵机控制(device:servo,value:0)”。","role":"assistant"}}],"created":1754834785,"id":"0217548347813611a81ab383eaa134d2a70c626b8ffda8439ec62","model":"doubao-seed-1-6-250615","service_tier":"default","object":"chat.completion","usage":{"completion_tokens":178,"prompt_tokens":155,"total_tokens":333,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":167}}}
[执行] 舵机角度设置为: 0°
—- 已发送 utf8 编码消息: "把舵机转到45度\\n" —-
[原始回答]: {"choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"2. 舵机控制(device:servo,value:45);","reasoning_content":"\\n用户的需求是把舵机���到45度,根据系统提示,舵机控制的格式是(device:servo,value:0-180)。这里value需要是0到180之间的数��,用户要求的45度在这个范围内,所以直接按照���式生成指令即可。","role":"assistant"}}],"created":1754834794,"id":"02175483479177071349a582c393a7766c3954399cf7bc97ee631","model":"doubao-seed-1-6-250615","service_tier":"default","object":"chat.completion","usage":{"completion_tokens":83,"prompt_tokens":156,"total_tokens":239,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":68}}}
[执行] 舵机角度设置为: 45°
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xf (BROWNOUT_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x4bc
load:0x403c9700,len:0xbd8
存在舵机峰值电流过大导致重启,可额外供电。有时候会因为网络无法控制,导致指令失败,建议换一个好一点的2.4G网络,本项目演示了ESP32 + 国产大模型 + 自然语言控制硬件的完整流程,适合智能家居、机器人等场景。 后续可以优化:
- 增加更多外设(风扇、电机、继电器等)
- 用 WebSocket 代替 HTTP 提升响应速度
- 在 ESP32 上做离线指令解析以减少网络依赖
有了这个基础,你的 ESP32 就能听懂人话啦!
4.3 错误码
如果执行报错,请参见错误信息进行解决。
5. 总结
现在,本项目演示了ESP32 + 国产大模型 + 自然语言控制硬件的完整流程,适合智能家居、机器人等场景。从而实现对外部世界的感知,充分认识这个有机与无机的环境,后期会持续分享ESP32跑FreeRTOS实用案例,为人类社会发展贡献一点微薄之力。🙌🙌🙌
如果你有任何问题,可以通过Q Group(945348278)加入鹏鹏小分队,期待与你思维的碰撞! 😘😘😘
评论前必须登录!
注册