matlab-create-custom-arduino-library について
Arduino のセンサーや周辺機器向けに、MATLAB クラスと Arduino C++ コードをつなぐカスタムライブラリ作成ガイドです。標準対応と MathWorks の File Exchange 投稿を先に確認し、アドオンの作成と検証を案内します。
主な機能
- 01Arduino 標準ライブラリ対応の確認
- 02MathWorks 投稿アドオンの検索
- 03カスタムアドオンのテンプレート生成
- 04MATLAB クラスと C++ ヘッダーの作成
- 05ライブラリ登録と接続の検証
活用シーン
- 01MATLAB から未対応センサーを読み取る
- 02MATLAB 経由で周辺機器を制御する
- 03既存の Arduino C++ ライブラリを利用する
- 04独自ハードウェア用アドオンを作る
インストール
コマンドをコピーしてターミナルで実行します。
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 ライブラリの作成
MATLAB と Arduino C++ コードを橋渡しするカスタム Arduino ライブラリを作成して、MATLAB から Arduino のセンサーや周辺機器を操作できるようにします。
使用する場面
- ネイティブでサポートされていないセンサー(DHT11、DHT22、IMU、空気質センサーなど)を読み取りたい場合
- ネイティブでサポートされていない周辺機器(OLED ディスプレイ、モータードライバー、NeoPixels など)を制御したい場合
- 「MATLAB から Arduino で[センサー/アクチュエーター/周辺機器]を使う方法を教えて」と質問された場合
- 既存の Arduino C++ ライブラリを MATLAB から利用できるようにラップしたい場合
LibraryBase、arduinoioaddons、またはカスタムアドオンの作成について言及している場合
使用しない場面
- 周辺機器がすでにネイティブでサポートされている場合(
listArduinoLibrariesで確認してください) - Arduino ボードを検出または接続する必要がある場合(
matlab-connect-arduinoを参照してください) - 汎用的な I2C/SPI 通信を行いたい場合(組み込み機能を使用してください)
- MATLAB との接続なしで、単独の Arduino コードをデプロイしたい場合
- Simulink から Arduino にデプロイしたい場合(別のワークフローを使用してください)
- Arduino のハードウェア設定画面を修正したい場合
ワークフロー
必須ゲート — 省略せず、手早く実施してください:
カスタムアドオンを作成する前に、以下のステップ 0 と 1 を必ず実行してください。簡単な確認(MATLAB コマンド 1 つと File Exchange に関する検索 1 件)であり、詳しい調査は不要です。結果を 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 なし):ライブラリの zip ファイルを fullfile(arduinoio.CLIRoot, 'user', 'libraries', '<LibName>') に手動で展開します。
R2024a より前のバージョンの場合(CLIRoot なし):arduinoio.CLIRoot の代わりに arduinoio.IDERoot を使用します。
ステップ 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が空である理由) - 各パブリックメソッドの上に、その処理内容を説明する1行コメント
ステップ 6:C++ ヘッダーを作成する
生成された .h ファイルを更新します。下記の「C++ ヘッダー規則」を参照し、
テンプレートについては references/cpp-patterns.md を読んでください。
生成された .h ファイルに、ユーザーが理解しやすいよう最小限のコメントを追加します。
- アドオン名と対応する周辺機器を記述するファイルレベルのコメント
- 各コマンド ID
#defineの上に、コマンドを説明する1行コメント 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 のバスを介しません |
| 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/src/U8g2lib.h' ではなく 'U8g2/U8g2lib.h' と記述する必要があります。
C++ ヘッダー規則
テンプレートの全容については references/cpp-patterns.md を読んでください。重要な規則は次のとおりです。
setup()でハードウェアを初期化してはいけません — setup() 内で.begin()、Wire.begin()、SPI.begin()などを呼び出すと、「Internal error: The initialization of the server code is incorrect.」が発生します。単純な変数の代入(例: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 を初期化しているため安全です。
MATLAB がすでに初期化しているので、C++ コードから Wire.begin() を呼び出してはいけません。
よくある間違い
| 間違い | 問題となる理由 | 正しい方法 |
|---|---|---|
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++ ヘッダーを通常どおり設定します)。
失敗するコマンドを繰り返し再試行しないでください。手動作成に切り替えて続行します。
トラブルシューティング
デプロイまたは使用中にエラーが発生した場合は、該当するリファレンスを読んでください:
- コンパイルエラーまたは「source not found」エラー →
references/common-errors.mdを読む - 実行時エラー(「unable to receive data」、「server code incorrect」) →
references/common-errors.mdを読む - バスの競合(I2C/SPI/UART) →
references/bus-conflicts.mdを読む - C++ コードのパターン(遅延初期化、応答形式、インクルード) →
references/cpp-patterns.mdを読む
Copyright 2026 The MathWorks, Inc.