8.5
【写在前面】
就在昨天,完成了FireBeetle 2 Board ESP32-S3的编译环境配置,并进行了用arduino ide的xiaozhi-MCP插件进行了小智控制esp32点亮板载led灯,小智通过MCP点亮DFrobot FireBeetle 2 Board ESP32-S3 板载LED灯- Makelog(造物记),基础的代码跑通后,就可以变化出其它的花样了。
在今天,尝试简单的任务,闪烁的红绿灯,它们外接在FireBeetle 2 Board ESP32-S3的引脚上,将通过小智来控制它们。

在视频中发声没有出镜的蓬头小智。

材料清单
- 小智AI X1
- DF FireBeetle 2 Board ESP32-S3 X1
- 红绿黄LED灯 X1
- 面包板+杜邦线 X若干
步骤1 准备接线
前期编译环境的准备工作已经完成。
红绿灯模块准备接线。
(图片很重要,接线要用到。)

选择三个引脚A0----红,A1----黄,A2----绿。

步骤2 编写FireBeetle 2 Board ESP32 S3程序
主要功能:
通过颜色名称控制不同LED,支持语音指令"点亮红灯"、"绿灯闪烁"、"熄灭黄灯"等。
(因为是小白,折腾了好久,完成下面代码,其中不会的地方请求了DS帮助。)
#include <WiFi.h>
#include <WebSocketMCP.h>
#define LED_BUILTIN 21
#define RED_LED 4 // A0引脚 (GPIO4)
#define GREEN_LED 6 // A2引脚 (GPIO6)
#define YELLOW_LED 5 // A1引脚 (GPIO5)
// WiFi配置
const char* ssid = "CMCC-QuYY";
const char* password = "qmsjyff2025";
// MCP服务器配置
const char* mcpEndpoint = "ws://api.xiaozhi.me/mcp/?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIxNjQzNywiYWdlbnRJZCI6NTEzODI0LCJlbmRwb2ludElkIjoiYWdlbnRfNTEzODI0IiwicHVycG9zZSI6Im1jcC1lbmRwb2ludCIsImlhdCI6MTc1NDM2NDAxOH0.VdYOE7VEiXBsNz9YhS99lIPk2RAGtHILyU6x2HSHj12fDnw4NjWQWqwkeNluK8zIxDv5CGAj89JCn0U-fRNOcQ";
// 创建WebSocketMCP实例
WebSocketMCP mcpClient;
// 连接状态回调函数
void onConnectionStatus(bool connected) {
if (connected) {
Serial.println("[MCP] 已连接到服务器");
// 连接成功后注册工具
registerMcpTools();
} else {
Serial.println("[MCP] 与服务器断开连接");
}
}
// 注册MCP工具
void registerMcpTools() {
// 注册红色LED控制工具
mcpClient.registerTool(
"red_led",
"控制ESP32 GPIO4引脚上的RED_LED",
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
[](const String& args) {
DynamicJsonDocument doc(256);
deserializeJson(doc, args);
String state = doc["state"].as<String>();
if (state == "on") {
digitalWrite(RED_LED, HIGH);
} else if (state == "off") {
digitalWrite(RED_LED, LOW);
} else if (state == "blink") {
for (int i = 0; i < 5; i++) {
digitalWrite(RED_LED, HIGH);
delay(200);
digitalWrite(RED_LED, LOW);
delay(200);
}
}
return WebSocketMCP::ToolResponse("{\"success\":true,\"state\":\"" + state + "\"}");
}
);
// 注册绿色LED控制工具
mcpClient.registerTool(
"green_led", // 修正:修改为正确的工具名
"控制ESP32 GPIO6引脚上的GREEN_LED", // 修正引脚描述
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
[](const String& args) {
DynamicJsonDocument doc(256);
deserializeJson(doc, args);
String state = doc["state"].as<String>();
if (state == "on") {
digitalWrite(GREEN_LED, HIGH);
} else if (state == "off") {
digitalWrite(GREEN_LED, LOW);
} else if (state == "blink") {
for (int i = 0; i < 5; i++) {
digitalWrite(GREEN_LED, HIGH);
delay(200);
digitalWrite(GREEN_LED, LOW);
delay(200);
}
}
return WebSocketMCP::ToolResponse("{\"success\":true,\"state\":\"" + state + "\"}"); // 添加返回值
}
);
// 注册黄色LED控制工具
mcpClient.registerTool(
"yellow_led",
"控制ESP32 GPIO5引脚上的YELLOW_LED",
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
[](const String& args) {
DynamicJsonDocument doc(256);
deserializeJson(doc, args);
String state = doc["state"].as<String>();
if (state == "on") {
digitalWrite(YELLOW_LED, HIGH);
} else if (state == "off") {
digitalWrite(YELLOW_LED, LOW);
} else if (state == "blink") {
for (int i = 0; i < 5; i++) {
digitalWrite(YELLOW_LED, HIGH);
delay(200);
digitalWrite(YELLOW_LED, LOW);
delay(200);
}
}
return WebSocketMCP::ToolResponse("{\"success\":true,\"state\":\"" + state + "\"}");
}
);
Serial.println("[MCP] LED控制工具已注册");
}
void setup() {
Serial.begin(115200);
// 初始化LED引脚
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
// 初始化板载LED(上电点亮)
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, HIGH);
// 连接WiFi
Serial.print("连接到WiFi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi已连接");
Serial.println("IP地址: " + WiFi.localIP().toString());
// 初始化MCP客户端
mcpClient.begin(mcpEndpoint, onConnectionStatus);
}
void loop() {
// 处理MCP客户端事件
mcpClient.loop();
// 其他代码...
delay(10);
}
上面的代码交给DS,它嫌我太啰嗦,修改如下:
#include <WiFi.h>
#include <WebSocketMCP.h>
#define LED_BUILTIN 21
#define RED_LED 4 // A0引脚 (GPIO4)
#define GREEN_LED 6 // A2引脚 (GPIO6)
#define YELLOW_LED 5 // A1引脚 (GPIO5)
// WiFi配置
const char* ssid = "CMCC-QuYY";
const char* password = "qmsjyff2025";
// MCP服务器配置
const char* mcpEndpoint = "ws://api.xiaozhi.me/mcp/?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIxNjQzNywiYWdlbnRJZCI6NTEzODI0LCJlbmRwb2ludElkIjoiYWdlbnRfNTEzODI0IiwicHVycG9zZSI6Im1jcC1lbmRwb2ludCIsImlhdCI6MTc1NDM2NDAxOH0.VdYOE7VEiXBsNz9YhS99lIPk2RAGtHILyU6x2HSHj12fDnw4NjWQWqwkeNluK8zIxDv5CGAj89JCn0U-fRNOcQ";
// 创建WebSocketMCP实例
WebSocketMCP mcpClient;
// 连接状态回调函数
void onConnectionStatus(bool connected) {
if (connected) {
Serial.println("[MCP] 已连接到服务器");
// 连接成功后注册工具
registerMcpTools();
} else {
Serial.println("[MCP] 与服务器断开连接");
}
}
// 通用LED控制函数
auto createLedControlTool(const String& toolName, const String& description, int ledPin, const String& ledColor) {
return [ledPin, ledColor](const String& args) {
DynamicJsonDocument doc(256);
deserializeJson(doc, args);
String state = doc["state"].as<String>();
if (state == "on") {
digitalWrite(ledPin, HIGH);
} else if (state == "off") {
digitalWrite(ledPin, LOW);
} else if (state == "blink") {
for (int i = 0; i < 5; i++) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
}
return WebSocketMCP::ToolResponse(
"{\"success\":true,\"led_color\":\"" + ledColor + "\",\"state\":\"" + state + "\"}"
);
};
}
// 注册MCP工具
void registerMcpTools() {
// 注册红灯控制工具
mcpClient.registerTool(
"red_led_control",
"控制红色LED灯 (GPIO4)",
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
createLedControlTool("red_led_control", "红色LED控制", RED_LED, "red")
);
// 注册绿灯控制工具
mcpClient.registerTool(
"green_led_control",
"控制绿色LED灯 (GPIO6)",
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
createLedControlTool("green_led_control", "绿色LED控制", GREEN_LED, "green")
);
// 注册黄灯控制工具
mcpClient.registerTool(
"yellow_led_control",
"控制黄色LED灯 (GPIO5)",
"{\"type\":\"object\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"on\",\"off\",\"blink\"]}},\"required\":[\"state\"]}",
createLedControlTool("yellow_led_control", "黄色LED控制", YELLOW_LED, "yellow")
);
Serial.println("[MCP] 三色LED控制工具已注册");
}
void setup() {
Serial.begin(115200);
// 初始化所有LED引脚
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
// 初始状态全关
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
// 初始化板载LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// 连接WiFi
Serial.print("连接到WiFi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi已连接");
Serial.println("IP地址: " + WiFi.localIP().toString());
// 初始化MCP客户端
mcpClient.begin(mcpEndpoint, onConnectionStatus);
}
void loop() {
// 处理MCP客户端事件
mcpClient.loop();
// 其他代码...
delay(10);
}
编译上传运行。
预期功能都可以实现,当然可以通过小智进行简单的灯光组合效果。

小结:
这个帖子记录了从例程控制板载led灯代码开始修改,完成外接的三个led点亮、熄灭、闪烁控制。同时发现小智MCP的连接非常稳定。
评论