MATLABなら超簡単! I2Cデバイスの動作確認ーroller485を例にー

# はじめに
新しいI2Cデバイスを購入、arduinoに接続して使用する場合の一般的な動作確認として下記の手順を踏む必要があります。

①arduinoとI2Cデバイスを物理的に接続
②arduinoライブラリで該当のI2Cデバイス用ライブラリを探してインストール
③ライブラリからサンプルコードを選択、もしくネットで調べてコピペ
④ビルド
⑤シリアルモニタ or シリアルプロッタでデータモニタ

上記動作確認の方法には、①で接続ミスがあった場合やI2Cデバイス自体が故障していた場合でも⑤でモニタするまで分からないという問題点があります。さらには②で既存のライブラリが無かった場合、プログラミングしてみないと接続ミスおよび故障に気づけない…ということで非常にめんどくさいです。

本記事では、単にデバイスとの接続にミスがないか、およびデバイスそのものが故障していないかを確認する方法として、[MATLAB Support Package for Arduino Hardware](https://jp.mathworks.com/matlabcentral/fileexchange/47522-matlab-support-package-for-arduino-hardware)　を用いた動作確認の方法について説明します。

＜備考＞
MATLAB Home購入でおおよそ１万円ほどするかと思うので、I2Cデバイスの動作目的だけでMATLAB購入する人はいないと思います…なので上記はあくまで建前としての説明であって、どちらかというと自分用メモとしての記事というのが正直なところです。

# 1. arduinoとI2Cデバイスとの接続
MATLABだからといって特殊な接続をする必要はありません。
今回はarduino Dueが手元にあったので、I2C用のピンである20(SDA),21(SCL)および5V、GNDとI2Cデバイスを接続しています。下記写真は今回の例であるm5stack roller485と接続した例です。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/c38b9e15-55b8-488b-a022-2fb0cb5faae7.png)

arduino UNO R3ならA4（SDA）・A5（SCL）ピン、arduino UNO R4 Wifiもおそらく同様と思いますが手元にいずれも無く確証がちょっと取れません…


# 2. I2Cデバイスとの接続確認
なにげに便利な関数、`scanI2CBus`。arduinoと接続されているI2CデバイスのIDを認識することが出来ます。
```matlab
a = arduino('COM5', 'Due', 'Libraries', 'I2C');
scanI2CBus(a)
```
roller485なら`0x64`が検出されるはずですが、I2Cデバイスとしてarduinoと正しく接続されていれば通り想定通りの結果が得られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/9b57c0ca-1c59-4fd8-a7d4-be5c2aec6ee2.png)

I2Cデバイスと正しく接続できていれば、`device`関数にて該当デバイスとの接続環境を構築できます。

```matlab
dev = device(a, 'I2CAddress', '0x64');
```


# 3. arduino→I2Cデバイスへのデータ送信
データ送信関数は`write`関数と`writeRegister`関数がありますが、後述するデータ受信関数`readRegister`との組み合わせの都合上、`writeRegister`が使いやすいです。

所定のアドレスに１個だけデータ送る場合
```matlab
writeRegister(dev, hex2dec('00'), 1, 'uint8');
```
所定のアドレスに複数データを送る場合
```matlab
writeRegister(dev,hex2dec('40'),[0 10 0 0], 'uint8');
```

なお、[m5stack roller485の仕様](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/unit/Unit-Roller485/Unit-Roller485-I2C-Protocol-EN.pdf) では、各アドレスの割り付けは下記になります。

・アドレス`00`：モータ制御のON/OFF切り替え設定用 1byteデータ
・アドレス`40`：速度制御モードにおける速度設定用 4byteデータ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/b1596d7d-8bef-406d-afa7-1102af992e23.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/a2174d8c-ab0b-4588-9f8c-732870950c26.png)

このため、上記コマンドを送信することでモータが所定回転数で回りはじめます。

# 4. I2Cデバイス→arduinoへのデータ受信
データ受信は、データ読み込みアドレスを`write`してからデータを`read`する方法と、１関数でデータ受信を行う`readRegister` を用いる方法の２通りがありますが、どう考えても後者のほうが便利です。

上記でデータ書き込みを行ったアドレス`00`、アドレス`40`ともにRead/Write両対応アドレスのため、今度はアドレスデータを読み込んで設定が正しく出来ているかを確認してみましょう。

所定のアドレスから１個のデータを受信する場合
```matlab
dataAdress00 = readRegister(dev, hex2dec('00'))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/86aa476d-ff9c-4704-920a-6ca6776b34a6.png)

所定のアドレスから複数のデータを受信する場合
```matlab
dataAdress40 = readRegister(dev, hex2dec('40'), 4)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302506/835d13d9-f360-430c-bab4-eba88bb1fb3e.png)

書き込んだデータが正しく設定できていることが確認できました。

# おまけ roller485を回転数制御するためのMATLABコマンド
上記2,3を一つのコードにまとめただけですが。

```matlab
a = arduino('COM5', 'Due', 'Libraries', 'I2C');
dev = device(a, 'I2CAddress', '0x64');
writeRegister(dev,hex2dec('00'),1, 'uint8');
writeRegister(dev,hex2dec('40'),[0, 10, 0, 0], 'uint8');
```

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">roller485 ソフト書き換え前の状態でI2C通信でのモータ回転出来ました。（ソフト書き換え前にハードの異常が無いか確認する目的）なお、I2CはMATLABから送ってます。 <a href="https://t.co/FjwwTMHh97">pic.twitter.com/FjwwTMHh97</a></p>&mdash; モータ制御マン (@motorcontrolman) <a href="https://twitter.com/motorcontrolman/status/1887512396471935273?ref_src=twsrc%5Etfw">February 6, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

お後がよろしいようで。