はい、いつもお世話になっております。
今回は素朴な疑問からつまずいたことの備忘録です。
タイトルの通り、「M5StackをI2Cのスレーブ通信をしてみる」というものです。
I2C通信についてはここで触れるほどではないので記載しません。
M5StackをI2Cのスレーブするだって?!
そもそもなんでそんな事するの?っていう事になりますが、ほら、あるじゃないですか、なんとなくI2C通信するコード書いたものの、それがちゃんとデータ送信できているかセンドバックみたいに確認したいとき。
例え話とかじゃなくて、実際そういう事になってやってみようとした結果です。
結論から言います
M5Stack(ESP32シリーズコアのマイコン)をArduinoベースでコード書く場合、I2Cスレーブに使うのは標準ライブラリ(M5Stack.hなど)ではサポートされていないので、基本的に非対応。
(一応非公式の ESP32のWireSlave.hというものはあるが・・・)
ESP32のスレーブライブラリ
です。
では、高額なI2C通信変換ボードを買うしかないかというと、そうでもありません。
(最近はそれほど高額でもないですが)
ESP32が非対応なだけで、Arduinoは対応しているので、普通にArduino UNOとか使えば、公式のサンプルコードまであります。
スケッチ例>(Arduino uno用とか)Wire>slave_receiver
試みると
#include <Wire.h> // I2Cのライブラリ
#define I2C_ADDRESS 0x02 // 今回はスレーブアドレスを0x02にしました
void requestEvent(){
// 自分のIDが呼ばれたときに実行する内容
}
void receiveEvent(int howMany){
// 自分のIDの通信を読み込んだ時に実行する内容
// 引数はコード上使わなくてもINTで宣言しておかないとエラーが出るマイコンもあります(UNOは出ない)
while(1 < Wire.available()){ // 受信していたらTRUE
char c= Wire.read(); // 1byte分受信 複数あるならその回数繰り返し
Serial.print(c); // とりあえず受信した内容を確認したいからPCのシリアル通信へ送信
}
}
void setup(){
...関係ないところは省略...
Wire.begin(I2C_ADDRESS); // このボードのスレーブIDを決める
Wire.onReceive(receiveEvent); // 自分のID向けの通信を受信したときに呼ぶ関数
void loop(){
...関係ないところは省略...
// 割り込み処理にしたからここは記載なし
と、これだけ。
M5StackのLCDに表示させようと悪戦苦闘したものの、結局諦めてArduino unoつかったらこれで終わりでした。
M5Stackのクラスでできるか試してみたものの、そもそもスレーブアドレス指定なんてないですねぇ
M5Stack I2Cクラス
(もしかすると他に手段があるのかな?)
結論は書いたものの
アンオフィシャルとは言うものの、ライブラリがあるっちゃあるので、たぶんできると思います。
そのうち試してみて、何か注意点などまとめて記載する予定
(ライブラリをインストールして、サンプルコード書いてみたけど上手く動かなかった。。。)
ライブラリのインストールは、Arduino IDEのツール>ライブラリ管理で
ESP32 I2C Slave
を検索すれば、「ESP32 I2C Slave」が出てくるので。
それではまた。
Mahalo