小智AI二次开发:用MCP协议让AI语音助手控制GPIO外设

小智AI二次开发:用MCP协议让AI语音助手控制GPIO外设
上一篇《环境搭建与烧录实操》把小智AI完整跑起来了,喊"你好小智"已经能对话。本篇进入二次开发:让小智AI真正"动手"——用 MCP 协议控制 GPIO,接一个 LED、一个舵机,说一句话就能开关。所有代码均来自小智AI开源固件(MIT协议),可在 xiaozhi-esp32 仓库对应文件逐行找到。
一、MCP 是什么:AI 控制硬件的"通用接口"

MCP(Model Context Protocol)是连接 AI 大模型与外部能力的开放协议,小智AI 采用它作为设备控制协议。简单说:后台大模型通过 MCP 发现设备有什么功能、并能调用这些功能。
完整控制链路:
你说话 → 小智AI 后台(LLM 决策)→ MCP 协议(WebSocket)→ ESP32 设备端 MCP Server → 工具回调 → GPIO 电平变化 → 外设动作
为什么选 MCP 而不是给每块板子写死接口:
- 工具自描述:设备注册"工具"(名称 + 描述 + 参数),大模型自动学会什么时候调用
- 标准协议:基于 JSON-RPC 2.0,后台不用为每个设备定制接口
- 跨设备通用:换开发板、换外设,后台侧零改动
二、动手前准备
| 项目 | 要求 | 说明 |
|---|---|---|
| 固件 | 小智AI v2.x(ESP-IDF 5.4+) | 05 篇装好的环境直接用 |
| 开发板 | ESP32-S3(面包板 WiFi 版) | 或任何已跑通小智AI 的板子 |
| 外设 | LED + 限流电阻,或舵机 | 官方演示灯位是 GPIO18 |
| 接线 | LED 正极→GPIO18,负极串电阻→GND | 面包板方案 LAMP_GPIO = GPIO18 |
| 控制面板 | xiaozhi.me 已绑定设备 | 05 篇配网激活已完成 |
三、设备端:注册你的第一个 GPIO 工具
小智AI 面包板固件自带一个现成的灯控示例(LampController),注册了三个工具:self.lamp.get_state、self.lamp.turn_on、self.lamp.turn_off。完整代码在 boards/common/lamp_controller.h:
class LampController {
private:
bool power_ = false;
gpio_num_t gpio_num_;
public:
LampController(gpio_num_t gpio_num) : gpio_num_(gpio_num) {
// 1. 把 GPIO 配置成输出模式
gpio_config_t config = {
.pin_bit_mask = (1ULL << gpio_num_),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
ESP_ERROR_CHECK(gpio_config(&config));
gpio_set_level(gpio_num_, 0);
// 2. 注册 MCP 工具:查询灯状态
mcp_server.AddTool("self.lamp.get_state", "Get the power state of the lamp",
PropertyList(),
[this](const PropertyList& properties) -> ReturnValue {
return power_ ? "{\"power\": true}" : "{\"power\": false}";
});
// 3. 注册 MCP 工具:开灯
mcp_server.AddTool("self.lamp.turn_on", "Turn on the lamp",
PropertyList(),
[this](const PropertyList& properties) -> ReturnValue {
power_ = true;
gpio_set_level(gpio_num_, 1);
return true;
});
}
};
拆解要点:
- GPIO 配置:
gpio_config把引脚设为推挽输出,gpio_set_level(引脚, 1/0)拉高/拉低电平——这就是"控制外设"的全部本质 - AddTool 签名:工具名(
self.lamp.turn_on)+ 描述(写给大模型看的说明书)+ 参数列表 + 回调函数 - 命名规范:用"模块.动作"分层命名,后台大模型靠名字和描述决定何时调用
注册一个带参数的工具(控制亮度 0~100):
mcp_server.AddTool("self.lamp.set_brightness", "Set the brightness of the lamp (0-100)",
PropertyList({ Property("brightness", kPropertyTypeInteger, 0, 100) }),
[this](const PropertyList& properties) -> ReturnValue {
int brightness = properties["brightness"].value<int>();
// 你的 PWM 控制代码
return true;
});
参数支持三种类型:kPropertyTypeBoolean(布尔)、kPropertyTypeInteger(整数,可设 min/max)、kPropertyTypeString(字符串)。
最后在板级初始化里注册(面包板 WiFi 版 compact_wifi_board.cc 的 InitializeTools):
void InitializeTools() {
static LampController lamp(LAMP_GPIO); // LAMP_GPIO = GPIO18
}
四、后台侧:工具是怎么被发现和调用的
设备连上后台后,后台通过三条 JSON-RPC 消息完成"认识设备 → 调用能力":
- initialize:握手,设备返回协议版本和设备信息
- tools/list:后台拉取设备支持的全部工具清单(名称 + 描述 + 参数 schema)
- tools/call:后台调用某个工具,传入参数,设备执行并返回结果
后台调用"开灯"的消息(后台 → 设备):
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "self.lamp.turn_on",
"arguments": {}
},
"id": 3
}
设备执行 gpio_set_level(18, 1) 后返回:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [ { "type": "text", "text": "true" } ],
"isError": false
}
}
五、完整链路:对小智说"开灯"发生了什么
- 你说:"小智,把灯打开"
- 音频经麦克风上传到小智AI 后台
- 后台大模型看到工具清单里有
self.lamp.turn_on(描述"Turn on the lamp"),判定该调用它 - 后台通过 WebSocket 发
tools/call到设备 - ESP32 设备端 MCP Server 找到工具回调,执行
gpio_set_level(GPIO18, 1) - 灯亮,设备返回
true→ 后台回复你"灯已经打开了"
整个链路的关键:大模型不需要知道 GPIO18 是什么,它只需要根据工具名和描述决定"该调用哪个工具"。这就是 MCP 让 AI 控制硬件的精髓——硬件能力被描述成大模型能理解的"工具"。
六、避坑清单
- 工具描述要写人话:描述是大模型决定何时调用的依据,"Turn on the lamp" 比 "Set GPIO high" 好——大模型不懂引脚,懂灯
- 工具名用"模块.动作":
self.lamp.turn_on这种命名让大模型一眼看懂归属 - GPIO 别接错:面包板方案的演示灯在 GPIO18,换引脚要改
LAMP_GPIO宏 - 整数参数记得限范围:用 min/max 约束(如 0~100),防止大模型传越界值
- 回调返回要明确:返回 true/false 或 JSON,后台靠它判断"到底执行成功没有"
- 带电流的外设加驱动:LED 串限流电阻;舵机、电机别直接怼 GPIO,要用驱动板(GPIO 只能输出毫安级电流)
- 改完代码重新烧录:
idf.py build && idf.py flash,重新配网激活(05 篇完整流程)
七、写在最后
从选型、接线、烧录到今天的 MCP 控制 GPIO,小智AI 已经从"能聊天"变成了"能动手"。下一篇预告:小智AI 控制舵机做实物(机械臂/小车方向)——把 MCP 工具接到舵机控制上,语音指挥实体设备动起来。
你在小智AI 上接了什么外设?GPIO 控制踩过什么坑?评论区聊聊。
本文代码与流程基于小智AI开源固件(MIT协议)与乐鑫 ESP-IDF 官方文档整理。本人嵌入式工程师(蓝牙音频/STM32/ESP32方向,3年原厂量产经验),本系列为个人技术记录,后续将陆续更新小智AI 二次开发系列教程。
更多推荐



所有评论(0)