今から始める電子工作 ⑰ I2Cバス その2-1 温湿度センサSHT45、Wireライブラリ
前回まで、温湿度センサSHT45を利用するのに、専用のライブラリをインストールしました。
Arduinoには、I2CバスをアクセスするためにWireライブラリが用意されていて、多くのI2Cデバイスの読み書きに利用できます。
●I2Cバスの様子ースタート・コンディションとストップ・コンディション
I2Cバスでは、SDAという信号線とSCLというクロックのペアで、データのやり取りをします。どちらもプルアップ抵抗でプルアップされているので、何もないときは、High(3.3Vもしくは5V)です。
マイコン側がマスタで、つながれたデバイスがスレーブという役割をします。
マスタは、スレーブと通信しようとするとき初めに、スタート・コンディションを作ります。具体的には、SCLはHighのまま変化させずに、SDAをLowにします。その後、SCLは必要なやり取りが続く限りクロックを出しつづけ、SDAは送るデータに合わせてHigh/Lowを繰り返します。やり取りが終わったら、SCLはHighのときに、SDAをLowからHighにします。これをストップ・コンディションと呼び、一連の通信が終了します。
この後、二つの信号はどちらもHighに戻っています。すると、もし別のマスタがいたら、バスが開いているので通信を始めようとします。そうすると、元のマスタにとって通信を継続したいのにバスをとられてしまって都合が悪いという状況が起こってしまうことが発生します。
それを避けるために、リピート(リピーテッド)スタート・コンディションが用意されています。ただ、デバイスの多くはこの処理を実装していなく、TI社の製品に多く見られます。
マスタは、スレーブ・アドレスをMSBから順に送り出します。スレーブは、このアドレスを監視していて、自分宛かどうかを確認しています。
●I2Cバスの様子ーアドレス
10ビットの場合も規定されています、ほとんど8ビットのデータを扱います。
スタート・コンディションの次は、必ずアドレスを送り出します。
- 1ビット目を8ビットのMSB(最上位ビット=b6)を送るよ
- 2ビット目のb5ビットを送るよ
- 3ビット目のb4ビットを送るよ
- 4ビット目のb3ビットを送るよ
- 5ビット目のb2ビットを送るよ
- 6ビット目のb1ビットを送るよ
- 7ビット目のb0ビットを送るよ
- 8ビット目のリード/ライト・ビットを送るよ
アドレスは7ビットです。SHT45は0x44で、0b1000100で、最後のビットはマスタがスレーブに対してデータを読み出したいという要求の場合、Read=Highにします。つまり、0b10001001=0x89になります。多くのデータシートでは7ビットのアドレスが書かれていますが、いくつかのデータシートでは、8ビットの値が書かれていることがあります。
マスタがスレーブに対して書き込みを行いたい場合は、0b10001000=0x88になります。
Wireライブラリでは、アドレスは7ビットで指定します。
SHT45のデータシートに書かれているI2Cの書き込みと読み出しの解説図です。
<書き込み>
- スタート・コンディションにする
- アドレスを送り、最後のビットはWrite=0にする
- スレーブはわかったとACK(acknowledgement)を返す
- マスタはコマンドの8ビットを送る
- スレーブはわかったとACK(acknowledgement)を返す
- ストップ・コンディションにして終了
<読み出し>
- スタート・コンディションにする
- アドレスを送り、最後のビットはRead=1にする
- スレーブはわかったとACK(acknowledgement)を返す
- スレーブはデータの8ビットを送る
- マスタはわかったとACK(acknowledgement)を返す
- データを必要な数、繰り返す
- 最後のデータを受けたマスタは転送の終了を伝えるNACK(Not Acknowledge)を返す
- ストップ・コンディションにして終了
データのSDAが出ている間、クロックのSCLも発生します。デフォルトでは100kHzです。スレーブ側でデータを用意するのに時間がかかる場合、SCLをLowのときにそのまま一定の時間Lowのままにしておくことができます。クロック・ストレッチと呼ばれ、SHT4xの前のモデルSHT3xには実装されていましたが、ほとんどのデバイでは使われないようです。
実際にオシロスコープで波形を見ます。
左側が書き込みで、アドレス0x44をマスタが送り、0xE0(low repeatability)のコマンドを送りました。
右側が読み出しで、アドレス0x44をマスタが送り、スレーブが、6バイトのデータを返送した様子です。
書き込みの部分を拡大します。
アドレス0x44の後ろの緑色は、読み出しのRead=0の1ビットです。その後ろの黄色の'0'はスレーブが返したACKで'0'の1ビットです。
読みだしの分を拡大します。
アドレス0x44の後ろの緑色は、読み出しのWrite=1の1ビットです。その後ろの黄色の'0'はスレーブが返したACKで'0'の1ビットです。6バイトのデータをスレーブが送り、最後の赤色はNACKで'1'の1ビットです。
上記は、SHT45の書き込みと読み出しです。OLEDグラフィック・ディスプレイの波形を見ます。
右側のブロックの先頭部分を拡大します。