8.8
【写在前面】
这个帖子其实是复习课,用小智语音控制ESP32 S3-DevKitC-1开发板(N16R8)板载灯后,把代码改改,变成控制外接LED灯,可以是控制一颗、二颗、三颗或者更多,建议最少两颗吧,能达到对小智MCP语音控制过程的更好理解。

材料清单
- K10小智AI X1
- ESP32 S3-DevKitC-1开发板(N16R8) X1
- 红绿黄LED X1
步骤1 开发板连接Ardino IDE
步骤2 从库管理中找到xiaozhi-mcp,打开示例BasicExample,修改代码
连接电路,红--IO4,黄--IO5,绿--IO6。
代码中指定三个LED的引脚。

红框内是一个完整的控制工具,由原来的代码修改得到。

复制红框内的红色LED控制工具,修改成黄灯和绿灯的。


初始化引脚,并将三个灯初始化为关(低电平)

完整代码如下:
#include <WiFi.h>
#include <WebSocketMCP.h>
#define RED_LED 4 // 引脚 (GPIO4)
#define GREEN_LED 6 // 引脚 (GPIO6)
#define YELLOW_LED 5 // 引脚 (GPIO5)
// WiFi配置
const char* ssid = "*****";
const char* password = "******";
// MCP服务器配置
const char* mcpEndpoint = "ws://api.xiaozhi.me/mcp/?token=******";
// 创建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(
"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 + "\"}");
}
);
// 注册绿色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 + "\"}"); // 添加返回值
}
);
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);
// 连接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);
}
填入配网信息和小智MCP接入点地址。
点击上传,等待编译烧录完成。(如果有报错,要根据日志提示修改代码,当然小白简单粗暴的懒人方法是交给DS处理。)

打开串口监视器,波特率115200,重启ESP32 S3开发板,可以看到连接服务器非常迅速哦。

我的K10小智控制台:

AI一键优化后

MCP接入点

步骤3 代码优化
上面代码可以运行,然后放给DS,它帮助给出了优化,学习一下,也是有很多收获的啊。
主要优化处在:
用了一个通用LED控制函数,合并了三个灯的开、关、闪烁功能。

然后控制工具就省去很多行代码了。

哈哈,DS果然强大。
#include <WiFi.h>
#include <WebSocketMCP.h>
#define RED_LED 4 // A0引脚 (GPIO4)
#define GREEN_LED 6 // A2引脚 (GPIO6)
#define YELLOW_LED 5 // A1引脚 (GPIO5)
// WiFi配置
const char* ssid = "*****";
const char* password = "*****";
// MCP服务器配置
const char* mcpEndpoint = "ws://api.xiaozhi.me/mcp/?token=*******";
// 创建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);
// 连接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);
}
测试通过了哈。
没有视频。
评论