matlab-create-custom-arduino-library — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited matlab-create-custom-arduino-library (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Help the user interface with Arduino sensors or peripherals from MATLAB by creating a custom arduino library that bridges MATLAB and Arduino C++ code.
LibraryBase, arduinoioaddons, or custom addon creationlistArduinoLibraries to check)matlab-connect-arduino)MANDATORY GATE — do not skip, but keep it fast:
Before creating a custom addon, you MUST run Steps 0 and 1 below. These are quick checks (one MATLAB command + one sentence about File Exchange), not deep research. Report findings in 1-2 lines and move on. If native support or a community addon exists, stop. Otherwise proceed to Step 2 immediately.
listArduinoLibrariesIf the peripheral is in the list, tell the user and STOP. Do NOT proceed to Step 2 or beyond. Do NOT generate custom library code. Common built-in: I2C, SPI, Serial, Servo, RotaryEncoder, Ultrasonic, ShiftRegister
Search for existing add-ons contributed by the MathWorks MATLAB Hardware Team:
site:mathworks.com/matlabcentral/fileexchange Arduino <peripheral>+arduinoioaddons folder structureor "MathWorks". Do NOT recommend community contributions from unknown third parties.
If a MathWorks-contributed add-on is found, guide the user through installation:
addpath the folder containing +arduinoioaddonsarduinoio.customLibrary.downloadLibrarylistArduinoLibrariesSTOP here if a MathWorks add-on is found — do NOT proceed to Step 2 or beyond.
Before creating a custom library, the user MUST provide:
MyDHT22)DHT22, U8g2)Do NOT proceed to any further steps until all required inputs are provided. If any are missing, ask the user explicitly and wait for their response.
% 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")Verify installation:
dir(fullfile(arduinoio.CLIRoot, 'user', 'libraries'))For R2024a-R2024b (no downloadLibrary): manually extract the library zip into fullfile(arduinoio.CLIRoot, 'user', 'libraries', '<LibName>').
For pre-R2024a (no CLIRoot): use arduinoio.IDERoot instead of arduinoio.CLIRoot.
% R2025a+ — use createLibraryTemplate (preferred)
arduinoio.customLibrary.createLibraryTemplate("<CustomLibraryName>")This creates the folder structure in the current working directory (pwd) and adds the path automatically. After calling it, the generated files are at:
<pwd>/+arduinoioaddons/+<CustomLibraryName>Folder/<CustomLibraryName>.m
<pwd>/+arduinoioaddons/+<CustomLibraryName>Folder/src/<CustomLibraryName>.hDo NOT search other locations — the files are always in pwd.
Naming: createLibraryTemplate("X") creates +XFolder/X.m — it appends "Folder" to the package name automatically. The generated setup() has placeholder comments — clear the body (no .begin() calls). The generated loop() is unused and can be deleted.
For pre-R2025a: create the folder structure manually:
<targetDir>/+arduinoioaddons/+<FolderName>/<ClassName>.m
<targetDir>/+arduinoioaddons/+<FolderName>/src/<HeaderName>.hThen register:
addpath('<targetDir>');
savepath;Update the generated .m file. See "MATLAB Class Property Rules" below for exact values.
Add minimal comments to the generated .m file for user understanding:
DependentLibraries is empty)Update the generated .h file. See "C++ Header Rules" below and read references/cpp-patterns.md for templates.
Add minimal comments to the generated .h file for user understanding:
#define explaining the commandcommandHandler for each case describing what it doeslistArduinoLibraries % Must show your library name
a = arduino("<port>", "<board>", "Libraries", "<FolderName>/<ClassName>");
obj = addon(a, "<FolderName>/<ClassName>", <args>);| Property | Format | Example | Notes |
|---|---|---|---|
LibraryName | 'FolderName/ClassName' | 'Adafruit/DHT22' | Must match namespace |
DependentLibraries | Cell of MATLAB addon names | {} or {'I2C'} | See decision table below |
LibraryHeaderFiles | '<ArduinoLibFolder>/<header.h>' | 'DHT/DHT.h' | Folder name in CLIRoot + header filename |
CppHeaderFile | fullfile(arduinoio.FilePath(mfilename('fullpath')), 'src', '<Name>.h') | — | Always this pattern |
CppClassName | Must match C++ class name | 'DHT22Base' | Exact match required |
| Scenario | Value | Reason |
|---|---|---|
| GPIO-only peripheral (DHT, NeoPixel) | {} | No MATLAB bus dependency |
| I2C device using SW_I2C (displays, most sensors) | {} | Software I2C bypasses MATLAB's bus |
| I2C device delegating to MATLAB's I2C infrastructure | {'I2C'} | MATLAB manages Wire init and pins |
| SPI device | {} | MATLAB does not own SPI bus |
| Uses another custom addon | {'OtherAddon/Name'} | Chain dependency |
Format: '<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'}The Arduino build system automatically searches the src/ subdirectory within the library folder, so NEVER include `src/` in this path. This is the most common mistake — even though headers like U8g2lib.h physically reside in <LibFolder>/src/, you must write 'U8g2/U8g2lib.h' NOT 'U8g2/src/U8g2lib.h'.
Read references/cpp-patterns.md for full templates. Critical rules:
.begin(), Wire.begin(),SPI.begin() etc. in setup() causes "Internal error: The initialization of the server code is incorrect." Simple variable assignments (e.g., cursorRow = 0) are safe.
sendResponseMsg(cmdID, 0, 0) crashes ARM boards (UNO R4, ESP32)Your code must never contain this line. Third-party libraries may include it internally (that is fine — you don't control their code), but YOUR .h file must not.
#include <U8g2lib.h>references/bus-conflicts.mdMATLAB owns the hardware I2C bus (Wire). If your peripheral uses I2C:
U8G2_..._SW_I2C) with DependentLibraries = {}If the third-party library requires hardware I2C (e.g., SGP30, motor shields): set DependentLibraries = {'I2C'} and let MATLAB manage the bus. The third-party library may include Wire.h internally — this is safe because MATLAB has already initialized Wire. Your C++ code must NOT call Wire.begin() since MATLAB already did.
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
DependentLibraries = {'Wire'} | Wire is not in listArduinoLibraries | Use {} or {'I2C'} |
Third-party lib in +arduinoioaddons/src/ | Wrong location; build can't find it | arduinoio.CLIRoot/user/libraries/ |
LibraryHeaderFiles = {'U8g2lib.h'} | Missing folder prefix | {'U8g2/U8g2lib.h'} |
U8G2_..._HW_I2C constructor | Conflicts with MATLAB's Wire management | Use _SW_I2C constructor |
.begin() calls in setup() | Server handshake fails | Init hardware via command; variable assignments are OK |
sendResponseMsg(cmdID, 0, 0) | Crashes ARM boards (nullptr) | Send >= 1 byte always |
#include <Wire.h> in your addon header | Conflicts with MATLAB I2C server | Omit; use SW_I2C or DependentLibraries = {'I2C'} |
| Installing via Arduino IDE Library Manager | MATLAB uses its own CLIRoot path | Use downloadLibrary() |
Not calling addpath after creating addon | listArduinoLibraries won't find it | addpath + savepath |
downloadLibrary (R2025a+) or manual copy to CLIRoot for third-party libslistArduinoLibraries after registration.begin() or hardware init in setup() — use lazy init via dedicated commandsendResponseMsg<Wire.h> in your own code — use software I2C or depend on {'I2C'}+arduinoioaddonscreateLibraryTemplate (R2025a+) over manual folder creationIf listArduinoLibraries hangs, File Exchange search takes too long, downloadLibrary fails, or createLibraryTemplate fails — fall back to the pre-R2025a manual approach:
it into fullfile(arduinoio.CLIRoot, 'user', 'libraries', '<LibName>').
<targetDir>/+arduinoioaddons/+<FolderName>/<ClassName>.m
<targetDir>/+arduinoioaddons/+<FolderName>/src/<HeaderName>.haddpath('<targetDir>'); savepath;Do not retry failing commands repeatedly. Switch to manual creation and proceed.
When errors occur during deployment or usage, read the appropriate reference:
references/common-errors.mdreferences/common-errors.mdreferences/bus-conflicts.mdreferences/cpp-patterns.md----
Copyright 2026 The MathWorks, Inc.
----
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.