关于 matlab-create-custom-arduino-library
这是一个帮助 MATLAB 用户为 Arduino 传感器或外设创建自定义库的技能指南,通过 MATLAB 类和 Arduino C++ 代码建立接口。指南先检查原生支持和 MathWorks File Exchange 资源,再说明库的搭建与验证流程。
主要功能
- 01检查 Arduino 原生库支持
- 02查找 MathWorks 贡献的扩展
- 03生成自定义扩展模板
- 04编写 MATLAB 类和 C++ 头文件
- 05验证库注册及设备连接
适用场景
- 01从 MATLAB 读取未原生支持的传感器
- 02通过 MATLAB 控制外接外设
- 03将现有 Arduino C++ 库接入 MATLAB
- 04为定制硬件创建 Arduino 扩展
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-create-custom-arduino-library安装后在 Claude Code 中输入/matlab-create-custom-arduino-library确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/bus-conflicts.mdcommon-errors.mdcpp-patterns.md详细介绍
创建自定义 Arduino 库
通过创建自定义 Arduino 库,在 MATLAB 与 Arduino C++ 代码之间搭建桥梁,帮助用户通过 MATLAB 使用 Arduino 传感器或外围设备。
适用场景
- 用户想要读取原生不支持的传感器(DHT11、DHT22、IMU、空气质量传感器)
- 用户想要控制原生不支持的外围设备(OLED 显示屏、电机驱动器、NeoPixels)
- 用户询问“如何通过 MATLAB 使用 Arduino 上的 [传感器/执行器/外围设备]?”
- 用户想要封装现有的 Arduino C++ 库,以便在 MATLAB 中使用
- 用户提到
LibraryBase、arduinoioaddons或创建自定义插件
不适用场景
- 外围设备已原生支持(使用
listArduinoLibraries检查) - 用户需要发现或连接 Arduino 板(请参阅
matlab-connect-arduino) - 用户需要通用 I2C/SPI 通信(内置支持)
- 用户想要部署独立运行的 Arduino 代码(不连接 MATLAB)
- 用户想要部署 Simulink Arduino 程序(工作流不同)
- 用户想要修复 Arduino 硬件设置界面
工作流
强制检查步骤 — 不可跳过,但应快速完成:
创建自定义插件之前,必须先执行以下第 0 步和第 1 步。这些检查很简单(运行一条 MATLAB 命令,并用一句话说明 File Exchange 的搜索结果),无需深入研究。用 1–2 行报告结果,然后继续。如果存在原生支持或社区插件,则停止;否则立即进入第 2 步。
第 0 步:检查原生支持(始终首先执行)
listArduinoLibraries
如果列表中有该外围设备,请告知用户并停止。不要继续执行第 2 步或后续步骤。不要生成自定义库代码。常见的内置支持包括:
I2C、SPI、Serial、Servo、RotaryEncoder、Ultrasonic、ShiftRegister
第 1 步:搜索 File Exchange(仅限 MathWorks 贡献内容)
搜索 MathWorks MATLAB Hardware Team 贡献的现有插件:
- 搜索:
site:mathworks.com/matlabcentral/fileexchange Arduino <peripheral> - 查找包含
+arduinoioaddons文件夹结构的软件包 - 仅使用由 MathWorks 编写的搜索结果——按作者“MathWorks Hardware Team”或“MathWorks”筛选。不要推荐来自未知第三方的社区贡献。
如果找到 MathWorks 贡献的插件,请指导用户完成安装:
- 下载并解压插件包
- 对包含
+arduinoioaddons的文件夹运行addpath - 使用
arduinoio.customLibrary.downloadLibrary安装第三方 Arduino 库 - 使用
listArduinoLibraries验证
如果找到 MathWorks 插件,请在此处停止——不要继续执行第 2 步或后续步骤。
第 2 步:收集所需输入
创建自定义库之前,用户必须提供:
- 自定义库名称(例如,
MyDHT22) - 第三方 Arduino 库名称(如果要封装现有库;例如,
DHT22、U8g2) - MATLAB 插件文件的目标输出目录
在提供所有必需输入之前,不要继续执行后续步骤。如果缺少任何一项,请明确询问用户并等待回复。
第 3 步:安装第三方 Arduino 库
% R2025a+ — use downloadLibrary (preferred)
arduinoio.customLibrary.downloadLibrary("<ArduinoLibraryName>")
% Accepts: library name, name@version, GitHub URL, or local .zip path
% Examples:
arduinoio.customLibrary.downloadLibrary("DHT22")
arduinoio.customLibrary.downloadLibrary("U8g2")
arduinoio.customLibrary.downloadLibrary("https://github.com/olikraus/u8g2")
验证安装:
dir(fullfile(arduinoio.CLIRoot, 'user', 'libraries'))
对于 R2024a–R2024b(没有 downloadLibrary):手动将库压缩包解压到
fullfile(arduinoio.CLIRoot, 'user', 'libraries', '<LibName>')。
对于 R2024a 之前的版本(没有 CLIRoot):使用 arduinoio.IDERoot 代替 arduinoio.CLIRoot。
第 4 步:搭建插件框架
% R2025a+ — use createLibraryTemplate (preferred)
arduinoio.customLibrary.createLibraryTemplate("<CustomLibraryName>")
这会在**当前工作目录(pwd)**中创建文件夹结构,并自动添加路径。调用后,生成的文件位于:
<pwd>/+arduinoioaddons/+<CustomLibraryName>Folder/<CustomLibraryName>.m
<pwd>/+arduinoioaddons/+<CustomLibraryName>Folder/src/<CustomLibraryName>.h
不要搜索其他位置——文件始终位于 pwd 中。
命名:createLibraryTemplate("X") 会创建 +XFolder/X.m——它会自动在包名称后追加“Folder”。生成的 setup() 中包含占位注释——请清空函数体(不要调用 .begin())。生成的 loop() 未使用,可以删除。
对于 R2025a 之前的版本:手动创建文件夹结构:
<targetDir>/+arduinoioaddons/+<FolderName>/<ClassName>.m
<targetDir>/+arduinoioaddons/+<FolderName>/src/<HeaderName>.h
然后注册:
addpath('<targetDir>');
savepath;
步骤 5:配置 MATLAB 类
更新生成的 .m 文件。具体取值请参阅下文的“MATLAB 类属性规则”。
在生成的 .m 文件中添加简要注释,方便用户理解:
- 文件级注释块,说明类的用途及其封装的外设
- 为不明显的属性值添加简短注释(例如,说明
DependentLibraries为空的原因) - 在每个公共方法上方添加一行注释,说明其作用
步骤 6:编写 C++ 头文件
更新生成的 .h 文件。请参阅下文的“C++ 头文件规则”,并阅读
references/cpp-patterns.md 中的模板。
在生成的 .h 文件中添加简要注释,方便用户理解:
- 文件级注释,说明插件名称及其支持的外设
- 在每个命令 ID
#define上方添加一行注释,说明该命令的作用 - 在
commandHandler中为每个case添加简短注释,说明其作用
步骤 7:验证
listArduinoLibraries % Must show your library name
a = arduino("<port>", "<board>", "Libraries", "<FolderName>/<ClassName>");
obj = addon(a, "<FolderName>/<ClassName>", <args>);
MATLAB 类属性规则
| 属性 | 格式 | 示例 | 备注 |
|---|---|---|---|
LibraryName | 'FolderName/ClassName' | 'Adafruit/DHT22' | 必须与命名空间匹配 |
DependentLibraries | MATLAB 插件名称组成的单元格数组 | {} 或 {'I2C'} | 请参阅下方的决策表 |
LibraryHeaderFiles | '<ArduinoLibFolder>/<header.h>' | 'DHT/DHT.h' | CLIRoot 中的文件夹名称 + 头文件名 |
CppHeaderFile | fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', '<Name>.h') | — | 始终使用此格式 |
CppClassName | 必须与 C++ 类名匹配 | 'DHT22Base' | 必须完全匹配 |
DependentLibraries 决策表
| 场景 | 值 | 原因 |
|---|---|---|
| 仅使用 GPIO 的外设(DHT、NeoPixel) | {} | 不依赖 MATLAB 总线 |
| 使用 SW_I2C 的 I2C 设备(显示屏、大多数传感器) | {} | 软件 I2C 绕过 MATLAB 总线 |
| 将 I2C 操作交由 MATLAB I2C 基础设施处理的 I2C 设备 | {'I2C'} | MATLAB 管理 Wire 初始化和引脚 |
| SPI 设备 | {} | MATLAB 不拥有 SPI 总线 |
| 使用另一个自定义插件 | {'OtherAddon/Name'} | 链式依赖 |
LibraryHeaderFiles 格式
格式:'<FolderNameInCLIRoot>/<HeaderFilename>'
% GOOD — folder name matches what's in CLIRoot/user/libraries/
LibraryHeaderFiles = {'DHT/DHT.h'}
LibraryHeaderFiles = {'U8g2/U8g2lib.h'}
LibraryHeaderFiles = {'Adafruit_Motor_Shield_V2_Library/Adafruit_MotorShield.h'}
% BAD — just filename without folder
LibraryHeaderFiles = {'DHT.h'}
% BAD — subdirectory path (NEVER include src/ even if the file physically lives there)
LibraryHeaderFiles = {'U8g2/src/U8g2lib.h'}
% BAD — Arduino library name (Wire is not in CLIRoot/user/libraries)
LibraryHeaderFiles = {'Wire/Wire.h'}
Arduino 构建系统会自动在库文件夹下的 src/ 子目录中查找,因此切勿在此路径中包含 src/。这是最常见的错误:尽管 U8g2lib.h 等头文件实际位于 <LibFolder>/src/ 中,但必须写成 'U8g2/U8g2lib.h',而不是 'U8g2/src/U8g2lib.h'。
C++ 头文件规则
完整模板请阅读 references/cpp-patterns.md。关键规则:
setup()绝不能初始化硬件——在 setup() 中调用.begin()、Wire.begin()、SPI.begin()等会导致“内部错误:服务器代码的初始化不正确。” 简单的变量赋值(例如cursorRow = 0)是安全的。- 使用延迟初始化——通过专用的 INIT 命令,在首次收到命令时初始化硬件
sendResponseMsg必须至少发送 1 个字节——sendResponseMsg(cmdID, 0, 0)会导致 ARM 开发板(UNO R4、ESP32)崩溃- 绝不能在插件头文件中
#include <Wire.h>——这会与 MATLAB 造成 I2C 总线冲突。 代码中绝不能出现这一行。第三方库可能在内部包含它(这没有问题,因为你无法控制其代码),但你的.h文件中绝不能包含它。 #include <SPI.h>是安全的——MATLAB 不拥有 SPI- 第三方头文件使用尖括号:
#include <U8g2lib.h> - 成员对象使用构造函数初始化列表,不要在类内初始化
I2C 总线冲突 — 阅读 references/bus-conflicts.md
MATLAB 拥有硬件 I2C 总线(Wire)。如果外设使用 I2C:
- **首选:**使用软件 I2C 构造函数(例如
U8G2_..._SW_I2C),并设置DependentLibraries = {} - 不要直接调用
Wire.begin() - 不要在自己的插件头文件中
#include <Wire.h>
如果第三方库需要硬件 I2C(例如 SGP30、电机扩展板):设置
DependentLibraries = {'I2C'},并让 MATLAB 管理总线。第三方库可能会在内部包含 Wire.h——这是安全的,因为 MATLAB 已经初始化了 Wire。
你的 C++ 代码不得调用 Wire.begin(),因为 MATLAB 已经完成了初始化。
常见错误
| 错误 | 错误原因 | 正确做法 |
|---|---|---|
DependentLibraries = {'Wire'} | Wire 不在 listArduinoLibraries 中 | 使用 {} 或 {'I2C'} |
将第三方库放入 +arduinoioaddons/src/ | 位置错误;构建时无法找到 | arduinoio.CLIRoot/user/libraries/ |
LibraryHeaderFiles = {'U8g2lib.h'} | 缺少文件夹前缀 | {'U8g2/U8g2lib.h'} |
U8G2_..._HW_I2C 构造函数 | 与 MATLAB 的 Wire 管理冲突 | 使用 _SW_I2C 构造函数 |
在 setup() 中调用 .begin() | 服务端握手失败 | 通过命令初始化硬件;变量赋值可以 |
sendResponseMsg(cmdID, 0, 0) | 会导致 ARM 开发板崩溃(nullptr) | 始终发送至少 1 个字节 |
在插件头文件中 #include <Wire.h> | 与 MATLAB I2C 服务冲突 | 省略;使用 SW_I2C 或 DependentLibraries = {'I2C'} |
| 通过 Arduino IDE 库管理器安装 | MATLAB 使用自己的 CLIRoot 路径 | 使用 downloadLibrary() |
创建插件后未调用 addpath | listArduinoLibraries 将无法找到它 | 使用 addpath + savepath |
约定
- 始终先检查原生支持,再检查 File Exchange,最后才自行创建
- 对第三方库,始终使用
downloadLibrary(R2025a+)或手动复制到 CLIRoot - 注册后始终使用
listArduinoLibraries验证 - 不要在
setup()中调用.begin()或初始化硬件——使用专用命令进行延迟初始化 - 在
sendResponseMsg中始终发送至少 1 个字节 - 不要在自己的代码中包含
<Wire.h>——使用软件 I2C 或依赖{'I2C'} - 不要将第三方 Arduino 库放入
+arduinoioaddons - 优先使用
createLibraryTemplate(R2025a+),而非手动创建文件夹
备用方案:自动步骤失败或耗时过长时
如果 listArduinoLibraries 挂起、File Exchange 搜索耗时过长、downloadLibrary
失败,或 createLibraryTemplate 失败——请改用 R2025a 之前的手动方法:
- **手动安装库:**下载第三方 Arduino 库的 .zip 文件,并将其解压到
fullfile(arduinoio.CLIRoot, 'user', 'libraries', '<LibName>')。 - 手动创建文件夹结构:
<targetDir>/+arduinoioaddons/+<FolderName>/<ClassName>.m <targetDir>/+arduinoioaddons/+<FolderName>/src/<HeaderName>.h - 手动注册:
addpath('<targetDir>'); savepath; - 从第 5 步继续(照常配置 MATLAB 类和 C++ 头文件)。
不要反复重试失败的命令。改为手动创建并继续。
故障排除
部署或使用期间发生错误时,请阅读相应的参考文档:
- 编译错误或“找不到源文件”错误 → 阅读
references/common-errors.md - 运行时错误(“无法接收数据”、“服务端代码不正确”) → 阅读
references/common-errors.md - 总线冲突(I2C/SPI/UART) → 阅读
references/bus-conflicts.md - C++ 代码模式(延迟初始化、响应格式、包含项) → 阅读
references/cpp-patterns.md
版权所有 2026 The MathWorks, Inc.