I2Cバスを見える化

絶妙なプロトコルと思えるI2C

  • SCL クロック
  • SDA データ

 この2本でシリアル・データ通信を行います。クロックはいつも一定ではなくLow時間を引き延ばしたりできる柔軟な規格です。ArduinoではWireライブラリを使ってセンサやLCDと通信を行います。

スタートとストップがひとかたまり

 SDAとSCLの信号線は、電源へプルアップされています。したがって、常にHigh状態です。マスタ(Arduino)がI2Cの通信を始めようとすると、次の一連のやり取りをします。

  • SCLがHighのときにSDAをLowにする。スタート・コンディションと呼ぶ
  • マスタは、MSBから順に通信したいスレーブ・デバイスのアドレスを7ビットで送る(0x3e)。最後に1ビットWrite ('1')を付け加える
  • ずっと自分のアドレスが送られてくるのを待っているLCDが自分のアドレスだと認識し、ACK(Low)を1ビット出す
  • マスタは、スレーブが反応したので、最初の1バイト(0x00)を送る
  • スレーブのLCDはデータを受け取ったとACKを返す
  • マスタは、続いて1バイト(0x01)を送る
  • スレーブのLCDはデータを受け取ったとACKを返す
  • マスタは、必要な2バイトをLCDへ送ったので、SCLがHighのときにSDAをLowからHighにする。これがストップ・コンディションで、一連の通信が終わる

 上記の2バイトを送る動作を繰り返し、最終的に、下記のデータをLCDが受け取ります。下の段はASCIIコードに変換したデータです。

  00 01 40 54 40 65 40 6D 40 70 40 3D 40 31 40 36 40 27 40 43
                  T       e        m        p       =        1        6       '         C

 最初の00はLCDへのコマンド、01は画面クリアです。以降、40はデータを送るというコマンドです。

 上記はLCDとの通信でした。センサなどでは、次の手順が多いです。

①スリープしているのを起こしたり、デフォルトではないモードに切り替えたいために、1ビットもしくは2バイトのコマンドをスレーブに送る。送らなくてもよいデバイスもある。

②スレーブの温度などのデータの保存されているレジスタを1バイトもしくは2バイトで指定して、データを、1バイトもしくは2バイト、それ以上読み出す。