2015年3月14日土曜日

Physical Computing (特に Intel Edison) における I2C による通信について(その1)

 今回は少し趣きを変えたタイトルにしてみた。 なんか,お題目が大きいなぁ…。
ちなみに前回 Intel Edison の新しい統合型インストーラーを使ってみた からの続きである。

 なんでこんな事を書こうと思ったかというと,前回まで書いていた,Intel Edison 絡みである。 また,SparkFun Blocks for Intel Edison を重ねてみたにも書いた,SparkFun 社製の SparkFun Blocks for Intel Edison 絡みでもある。つまりは Physical Computing に絡んで少し勉強したので,せっかくだから書いておこう,と思ったのが動機である。

 そもそも physical computing って何かというと,それは Arduino に代表されるような,極小コンピュータ(Microcontroller と呼ばれたりする)を使って,センサーの情報を読み取ったり,場合によってはモーターなどを駆動して何かを動かす,みたいな事を言うらしい。これまで physical computing と言うと,Arduino がその火付け役として代表格のように言われてきたが,最近では Intel EdisonRaspberry Pi などかなり高性能のものも出始めている。

 かく言う私は,Intel Edison を買って遊んでいる。 まだ,Linux システムに振り回されているが,そろそろセンサーを使って遊んでみたいと思い,ちょこちょこといじっている段階である。 特に SparkFun Blocks for Intel Edison の9軸の加速度・地磁気・回転センサー LSM9DS0 が載った 9dof(9 Degrees of Freedom) Block を持っているので,それを試してみたのだが,その際に I2C 通信についてわからないことがあり,気になったのでいろいろ調べてみた。 それでこんなタイトルのエントリーを書こうと思ったのだった。

 ちなみに Arduino の場合は,Arduino IDE と呼ばれる統合環境の中に Wire library というのがあり,そのルーチンを用いることで I2C 通信を行える。しかし,ここでは Linux 上で C 言語や C++ でプログラミングを行う場合の I2C 通信についてみてみよう。


(1) physical computing での通信について
  まずは physical computing における通信について少し書こう。 具体的にイメージするために,Arduino Uno Pinmap (pdf) を見て欲しい。 この pdf は,Arduino UNO Pinout Diagram(@ Arduino Forum) のページから辿れる PighiXXX! というサイトからダウンロードできる。 PighiXXX! サイトの Pinouts ページに行き,さらにその中の Boards Pinouts に行き,2ページ目に行くと Arduino UNO Pinouts ページを表示させることができる。 その Arduino UNO Pinouts ページの左下にある「Download pdf」というボタンを押すと得られるものである。

 この Arduino Uno Pinmap pdf はかなり大きいので別ウィンドウか何かで見てもらうといいのだが,この図の水色で書かれた端子が通信用の端子となっている。 physical computing に使われる Microcontroller は,ATmega328 などがある。 これらは入出力の端子に限りがあるため,通信はシリアル通信が主体となる。 多くの場合にサポートされているシリアル通信は,UARTSPII2C などである。 Arduino でもこれらの3種類のシリアル通信がサポートされている。

これら3種類のシリアル通信の違いは,以下のようになる。
------------------------------------------------------------------------
  ・UART:2線式(Tx, Rx),1対1の通信(非同期あるいは調歩同期式)
  ・SPI:4線式 (3線+スレーブごとに1線),1対多数の通信
         ・SCK:Serial Clock (同期のためのクロックライン)
         ・MISO:Master In Slave Out (マスターへの入力ライン)
         ・MOSI:Master Out Slave In (マスターからの出力ライン)
         ・SS:Slave Select (スレーブの選択用ライン。スレーブごとに別のラインが必要。CS(Chip Select) とも言われる)
  ・I2C:2線式,多数対多数の通信が可能。I2C が正しい記載らしい。IIC とも書かれる。
         ・SDA:Serial DAta (データライン)
         ・SCL:Serial CLock (同期用クロックライン)
------------------------------------------------------------------------
 これを見ると,UART は1対1の通信しかできないため,多くのセンサー等の機器をつなげるには線が多数必要となる。 また,SPI では,クロックラインとデータラインで3本必要であり,さらに各センサー等のスレーブ機器を選択するためにスレーブごとに1本の線が必要となる。 それらに比べると,I2C2本線のみで済み,かつ,「多数」対「多数」の通信が可能となるため,physical computing にはもってこいの規格となっている。

注意I2C は2本の線しかいらないと書いたが,それは信号線の事であって,センサー等の機器を動かすためには電源ラインも必要となる。そのため,通常は I2C では,SDASCL,電源+,Ground の4本の線が必要となる。 他のシリアル通信でも,上記の記述以外に電源用の2本の線が必要なので,注意が必要である。


(2) I2C におけるデータのやりとり
 それでは I2C ではどのように多数対多数の通信を行うかと言うと,各スレーブ(センサー等)にアドレスをもたせている。 そして,I2C 通信開始後,最初に機器選択のためのアドレスを送信し,対応するスレーブ(センサー等)が応答するとデータのやりとりが行われる。 アドレスは,基本が 7 bit であり,その直後の 1 bit がゼロなら書込み(マスターからみて書込み),1なら読込み(マスターから見て読込み),を表す。 そのため,アドレスを無理やり 8 bit と考えると,書込み用のアドレスに対して,読込み用アドレスは +1 したアドレス,とも考えられる。 そのため,I2C による通信を記載する際に,読込みと書込みでアドレスが違う,と表現される事がある。

 この 7 bit アドレスには,拡張等のための予約済アドレスがある。 それを使って 10 bit による拡張型のアドレスも使って良いことになっている。 しかし,physical computing で使われる場合には,ほとんどの場合,7 bit アドレスのみが使われているみたいである。

 また,スレーブ(センサー等)によっては,内部レジスタを持っているものがある。 内部レジスタにデータを書き込む場合は,「スレーブアドレス指定」の後に送り込むデータの先頭で内部レジスタ番号(内部用コマンドと言ってもいいかも)を指定し,その後にデータを送信している。 内部レジスタからデータを読み込む場合は「スレーブアドレス(7bit)+書込指定(1bit)+内部レジスタ指定(8bit)」直後に,スレーブとの通信状態を保持したまま「スレーブアドレス(7bit)+読込指定(1bit)+データの読込み」とすればいいみたい。

 この「スレーブとの通信状態を保持したまま」について少し細かく言うと,I2C 通信の最初には START 状態にして通信を開始し,終了時には STOP bit で通信を終わるのが通常のパターンらしい。 それに対して「通信状態を保持したまま」というのは,書込み処理の後に STOP ではなく ReSTART の信号を送り,引き続き読込み処理を行うらしい。 言い換えると,ReSTART bit は,最初の書込み処理は終わったけど,まだ続きがあるよ,という意味らしい。

 それを行うには,Arduino の場合は,Wire library の中の Wire.endTransmission() において,
   endTransmission(false);
とすると,通信状態を保持したまま次の命令を実行できるらしい。
 Linux の場合は後述しよう。

 I2C についての詳細は,最初に提唱したフィリップス社から引き継いだ NXP Semiconductors 社による UM10204  I2C-bus specification and user manual を読んでみて欲しい…英語だけど。


(3) SMBub による通信
  I2C という規格は (2) で書いたとおりなのだが,physical computing で実際に使われている通信は(Linux や Windows 等の普通のコンピュータでもそうみみたいだが…)SMBus という手段を使っているらしい。 この SMBus というのは,Intel が考えたものであり,基本は I2C と同じである。 WiKipedia(英語版) では SMBusI2C の範疇に入り,その一部のみを使っているみたい。つまりは SMBusI2C のサブセットらしい。
 SMBus についての詳細は System Management Bus (SMBus) Specification (Version 2.0, August 3, 2000) を読んでみて欲しい。読んでもいまいち理解できなかったが…。ちなみに,こちらも英語です。探せば日本の文章もあるはず…。

 I2C との違いとしては,マスターは1台のみであり,他はすべてスレーブとなる点や, 通信プロトコル(手順)に SMBus 専用のものがあり,それらは I2C の手順とは微妙に異なっている。 なので,Microcontroller 等で I2C と書かれているものは,実際には SMBus によるシリアル通信と言うのが正しいみたい。 英語だが Comparing the I²C Bus to the SMBus に電気的な違いについてのレポートがあるので参考になるかもしれない。

 また,同じく英語だが SMBus Compatibility With an I2C Device にプロトコルの違いについてのレポートがある。 ただ,このレポートに書いてあるプロトコルの違いが,NXP Semiconductors 社による UM10204  I2C-bus specification and user manual の記載といまいち矛盾するような気がする…。 よくわからない…。誰か教えてください~!

Physical Computing (特に Intel Edison) における I2C による通信について(その2)に続く)

0 件のコメント: