|
12| 0
|
[项目] 给小智AI装上“手脚”:掌控板语音控制灯带与电机实战 |
|
本帖最后由 云天 于 2026-3-2 21:52 编辑 让小智AI不仅能听会说,还能控制灯带和电机,打造真正的智能硬件终端 【项目缘起】 小智AI 是一款开源的端侧语音助手项目,基于 ESP32 实现,支持唤醒词、语音识别、大模型对话等功能。它的代码结构清晰,硬件抽象层完善,非常适合作为智能硬件的“大脑”。而掌控板作为国内创客教育常用的主控板,集成了 OLED 屏幕、按键、I2C 接口等资源,性价比极高。如果能将小智AI 移植到掌控板上,并扩展出控制灯带、电机的能力,就能打造出一个既能语音交互又能驱动外设的智能终端。 经过一段时间的折腾,我成功将小智AI v2.0.5 移植到了掌控板 1.0 和 2.0 上,并通过 MCP(Model Context Protocol)工具让 AI 可以直接控制 WS2812 灯带和直流电机。这篇文章将分享完整的改造过程,希望给同样想折腾的朋友一些启发。 【准备工作】 硬件清单 掌控板 2.0(或 1.0) ×1 WS2812 灯带(12/24 灯珠) ×1 行空板 K10 IO 扩展板(用于驱动灯带) ×1 micro:bit 掌控 IO 扩展板(用于驱动电机,兼容行空板 M10/K10) ×1 直流电机 ×2 杜邦线、面包板、5V 电源(电机供电) 软件环境 操作系统:Windows 10/11 ESP-IDF v5.5.1(官方推荐) 小智AI 开源代码(版本 2.0.5,从 [GitHub](https://github.com/78/xiaozhi-esp32) 克隆) Git等工具 【移植核心步骤】 适配掌控板引脚配置 小智AI 的板级文件位于 `main/boards/` 目录下,我们以 `bread-compact-esp32` 为模板,修改 `config.h` 中的引脚定义,匹配掌控板的硬件连接: 麦克风 I2S:使用 P8/P9/P13(对应 GPIO26/25/18) 扬声器 I2S:使用 P14/P15/P16(对应 GPIO19/21/5) OLED 屏幕(sh1106,128x64):I2C 引脚 SDA=GPIO23,SCL=GPIO22 按键:A 键=GPIO0(BOOT),B 键=GPIO2 WS2812 灯带:GPIO33 电机驱动 I2C:复用 OLED 的 I2C 总线(地址 0x10) 关键配置如下(已省略无关项): 禁用 4G 模块,默认 WiFi 原项目默认启用了 ML307 4G 模块,我们将其引脚设为 `GPIO_NUM_NC`,并在 `dual_network_board.h` 中将默认网络类型改为 WiFi(`default_net_type = 0`),避免程序启动时卡在检测 4G 模块。 板级文件修改 `esp32_bread_board.cc` 是掌控板的主板类,我们需要: 初始化 I2C 总线(用于 OLED 和电机驱动) 重写 `GetI2CBus()` 虚函数,供 MCP Server 获取总线句柄 注释掉原有的 `LampController`(本例未使用) 适配 SH1106 屏幕:掌控板的 OLED 控制器为 SH1106,与常见的 SSD1306 略有不同。因此,在显示初始化部分需要包含头文件 <esp_lcd_panel_sh1106.h>,并调用 esp_lcd_new_panel_sh1106() 而不是 esp_lcd_new_panel_ssd1306()。原代码中已正确修改。 关键代码: 添加 WS2812 灯带驱动与 MCP 工具 我们使用 `circular_strip.h` 封装好的灯带驱动,在 `mcp_server.cc` 的 `AddCommonTools()` 函数中创建静态对象并注册工具: 这样 AI 就能通过调用 `self.led_strip.set_all` 等工具控制灯带。 添加电机驱动与 MCP 工具 电机驱动板通过 I2C 控制(地址 0x10),原 DF的Arduino 库提供了 `IOBOX_Motor` 类,我们将其移植为 ESP-IDF 风格的 `IOBoxMotor` 类,使用 ESP-IDF 的 I2C 驱动。 "io_box_motor.h": "io_box_motor.cpp" 中实现 I2C 通信,发送三字节命令:`[cmd, dir, speed]`,其中 cmd 为 0x00(M1)或 0x02(M2)。 然后在 `mcp_server.cc` 中,通过 `board.GetI2CBus()` 获取总线,创建电机对象并注册工具: 修改 CMakeLists.txt和 board.h 在 `main/CMakeLists.txt` 中添加 `circular_strip.cpp` 和 `io_box_motor.cpp` 到源文件列表,并依赖 `driver` 和 `led_strip` 组件。 修改 `board.h`,添加虚函数 `virtual i2c_master_bus_handle_t GetI2CBus() const { return nullptr; }`,并包含 `<driver/i2c_master.h>`。 【实际演示】 场景一:语音控制灯带 硬件连接:将 WS2812 灯带的数据线接掌控板 GPIO33,电源和地接 5V 电源(共地)。使用行空板 K10 IO 扩展板接线。 ![]() ![]() ![]() 场景二:语音控制电机 硬件连接:将掌控板插在"micro:bit 掌控 IO 扩展板"上,电机接 M1+/M1- 和 M2+/M2-,另需给电机独立供电(如 5V 电池)。注意 I2C 地址必须为 0x10(扩展板默认)。 对小智说:“**M1 电机正转,速度 200**”,电机立即转动。说“**停止所有电机**”,电机停止。如果接上轮子,就可以语音控制小车前进后退。 ![]() ![]() 注意:电机驱动需要足够功率,供电不足会导致 I2C 通信失败(出现 NACK 错误)。我一开始就遇到了这个问题,给电机单独供电后解决。 【遇到的问题与解决】 ESP-IDF 版本过低:最新小智AI开源代码2.2.2要求 ESP-IDF≥5.5.2,我本地的 5.5.1 报错,所以我用的智AI开源代码是2.0.5后解决。 ML307 模块初始化卡死:将默认网络改为 WiFi,并禁用引脚。 全局静态对象导致崩溃:灯带对象如果在全局构造,会在驱动未初始化时访问硬件,导致 Guru Meditation 错误。改为函数内静态局部变量后正常。 I2C NACK 错误:起初电机驱动无响应,检查发现是供电不足。给电机驱动板单独供电后问题消失。 【总结与展望】 通过这次移植,我深刻体会到小智AI 框架的灵活性。它的 MCP 机制让添加新硬件变得异常简单——只需实现硬件驱动,然后在 MCP Server 中注册工具,AI 就能像调用函数一样控制外设。掌控板作为主控,性能足够、接口丰富,非常适合做语音交互的载体。 未来,我计划继续扩展更多传感器和执行器,比如舵机、温湿度传感器、摄像头等,让小智AI 能感知环境并做出更复杂的动作。也希望这篇文章能抛砖引玉,让更多人玩转小智AI,创造出有趣的智能硬件项目。 【项目附件】 修改后的核心代码文件(config.h、esp32_bread_board.cc、mcp_server.cc、io_box_motor.h/cpp、dual_network_board.h、board.h、CMakeLists.txt)已打包,可下载。 main.zip |
沪公网安备31011502402448© 2013-2026 Comsenz Inc. Powered by Discuz! X3.4 Licensed