PR

【コード付き】I2Cの Master / Slave 間の通信をESP32を2個使って試す

本記事では、I2Cのマスタとスレーブのそれぞれの役目、ArduinoAPIでの通信概要。サンプルコードを用いた実装例を解説します。

I2Cとは

I2C(アイ・スクエアード・シー。通称アイツーシー)は一言で言えばシリアル通信の一種です。

I2Cの概要や、一般的な接続方法、ESP32をマスターとしてLED表示器を繋ぐサンプルを下記記事に記載しましたので、ご参照ください。

記事内の一部に広告を含みます。

I2C のマスタ・スレーブ機器それぞれの役目

I2Cバスインターフェース上には、複数のマスタ、スレーブ機器を配置することができます。
マスタの役目、スレーブの役目は主に下記のようになります。

マスタの役目

  • 転送の開始と終了を行う。転送時のクロック信号を出力する。
  • スレーブ機器に情報を送信する
  • スレーブ機器に情報の送信を指示する

スレーブの役目

  • マスタ機器からの情報を受信する(例:LCD表示器)
  • 依頼されたマスタ機器に情報を送信する(例:各種センサ・SRAM)

arduino-esp32 LibでのMaster / Slave の動き

arduino-esp32でのI2CのAPIは基本的にArduinoのWireライブラリを継承してます。
ArduinoのWireライブラリのリファレンスは下記を参照ください。

以下で、基本的なマスタ、スレーブの動きをArduinoのAPIに従って記載します。

I2Cマスタ・スレーブの初期化と接続

マスタ・スレーブともI2Cのバスに接続し、マスタ・スレーブとして動作するための初期化を行います。

マスタスレーブ
begin()begin()

スレーブの場合は、Wire.bigin()命令を実行する前に、Wire.onRecieve()、Wire.onRequest()された時の動作を先に書いておきます。また、スレーブの場合はbigin()命令のパラメタで自身のアドレスを指定しておきます。

マスタがスレーブ機器に情報を送信する場合

マスタはWire.beginTransmission()命令を実行することでI2C通信を開始します。Wire.beginTransmission()のパラメタには通信先のスレーブのアドレスを入れます。

マスタ
beginTransmission()

たとえば、LCD表示器に表示内容を指示する、などの場合、下記の流れになります。

マスタスレーブ
① write()② onReceive()
③ available()
④ read()

マスタ側は① Wire.write()で通信内容を送付します。
スレーブは② Wire.onReveive()の割り込み処理の中で未受領のデータがあるか確認(③ Wire.available())し、データがあれば④ Wire.read()する流れになります。

マスタがスレーブ機器に情報の送信を指示する場合

温度計や湿度計などのセンサからの情報を受け取る場合、下記の挙動となります。

マスタスレーブ
① requestFrom()② onRequest()
③ write()
④ read()

マスタは① Wire.requestFrom()でスレーブアドレスを指定してデータの送信を指示します。
スレーブは② Wire.onRequest()割り込みの中で③ Wire.write()を使ってデータを送信します。
なお、WireクラスはStreamクラスを経てPrintクラスを継承しているので、 Wire.printf()といった記載も可能です。
マスタは④ Wire.read()などでスレーブからのデータを受領します。

ESP32を使ったI2Cの Master / Slave 通信のサンプルコード

ESP32を使ったI2C通信の例をマスター、スレーブとも紹介します。

マスタ・スレーブとも「マスタがスレーブ機器に情報を送信する場合」「マスタがスレーブ機器に情報の送信を指示する場合」の双方のコードが1ファイルに記載されているので、若干読みずらいところもあります。上記記載と合わせて読んでみてください。

コードは例によって、下記より取得できます。

マスタ

https://github.com/espressif/arduino-esp32/blob/master/libraries/Wire/examples/WireMaster/WireMaster.ino

スレーブ

https://github.com/espressif/arduino-esp32/blob/master/libraries/Wire/examples/WireSlave/WireSlave.ino

実際に試す場合の接続方法は写真のとおりです。
電源、GND、IOの21/22(デフォルトの場合)を接続すれば動作します。
UART出力をする場合、双方のESP32にUSBケーブルを接続すればOKです。

まとめ

以上、I2Cのマスタとスレーブのそれぞれの役目、ArduinoAPIでの通信概要。サンプルコードを用いた実装例を解説しました。

実際に動作させながら、見比べながら試してみると理解が進むと思います。

なお、ESP32を2台同時に使ってそれぞれUARTでシリアル通信する方法は下記に記載してありますので、実験の時にお使いください。

その他のESP32でのI2Cの利用方法について、下記にまとめました。合わせてご参照ください

以上、ご参考になれば幸いです。