PICK UP

【ZUGYUUUN! 】I2C通信に対応開始!

INFORMATION

小柴篤史

こんにちは!Bunnyhop学生アルバイトの小柴です。夏も終わりに近づき、涼しくなってきましたね!

今回のアップデート内容(I2C通信対応)について

今回の記事は、弊社サービスの「ZUGYUUUN!」アップデートのお知らせです。 今回のアップデートによって、「I2C通信用ZUGYUUUN!API」が追加されました。 これにより、これまでのバージョンでは未対応だったI2C通信が可能になりました!
…とはいったものの、 「I2C」という言葉、Raspberry PiやArduinoなどのデバイスをいじっていると良く出てきますが、そもそもどのようなものか、いまいち理解できていない方も多いのではないでしょうか。他にもSPIやUARTといった通信規格がありますが、これらの通信規格はどのような違いがあるのでしょうか?

ということで、本記事ではZUGYUUUN!のアップデート内容と合わせて、これらの通信規格の違いについても簡単に解説していきたいと思います!

各シリアル通信規格の違いとは?

そもそも、デバイス間のシリアル通信はかなり複雑です。例えば、一つのマイコンやRaspberry Piで複数のセンサ(温度センサ、湿度センサ、気圧センサ、…)を制御したい場合を考えます。 そのとき、ただマイコンとセンサを銅線でつないで電気を流しただけで、データを送れるわけではありません。 デバイス間で様々な決まりごとを決め、それをデバイス間でお互いに確認しつつ通信を行う必要があるのです。例えば、以下のような点に気をつける必要があります。

  • [通信対象の指定]… データ通信を行いたい相手(センサ、デバイス)はどれか
  • [通信の開始/終了の判定]… データ通信はいつ始まり、いつ終わるのか
  • [送受信の要求の判定]… データを送りたいのか、受け取りたいのか
  • [通信の正常動作の確認]… 正しくデータ通信を行えているのか

このような複雑な制御を正しく行うシリアル通信の方式を一から考えるのはとても大変ですし、せっかく通信方式を作っても、一般に出回っている他のデバイスに対しても使えなければ、一回限りの無駄なものになってしまいます。
そこで、様々な種類のデバイスを共通の規格で制御できるように定めたものがシリアル通信規格です。 その中でも、各種センサ・デバイスの制御に特に多く採用されている通信規格が、I2CやSPIなのです!

Raspberry PiのGPIOは、デバイス制御やデバイス間のためのデータ通信規格として、I2C、SPI、UARTの3種類のシリアル通信をサポートしております。 今回は、この3種類の通信規格に絞って解説していきたいと思います。

I2C(アイ・ツー・シー)とは

I2CはInter-Integrated Circuitの略称で、正しくはI2C(アイ・スクエアド・シー)と表記します。一部の環境では上付き文字の表示ができないことを考慮して、I2Cと表記されるようになりました。
I2Cは、わずか2本の信号線によって複数のデバイスとのデータ送受信が可能な点が特長です。
I2Cと後述のSPIでは、一台の親デバイス(マスターデバイス)が、複数の子デバイス(スレーブデバイス)を制御する、マスター・スレーブモデルを採用しています。 マスター・スレーブモデルでは、マスターが常に通信の主導権を持っており、スレーブから通信要求を送ることはできません。常にマスターからスレーブへの一方的な通信制御となります。
マスター・スレーブの関係が成り立つ身近な例としては、パソコンで編集した書類をプリンタを使って印刷するときなどが挙げられます。この場合はパソコンがマスター、プリンタがスレーブとなります。 マスターデバイスは複数のスレーブデバイスを管理下に置き、それらの制御を行う役割を担います。これにより、1台で複数のデバイスを制御することができます。

I2C通信の説明のため、Raspberry Piにセンサ類をつなぎ、Raspberry PiがI2Cを用いてセンサを制御する場合を考えたいと思います。この場合は、Raspberry Piがマスター、センサ類がスレーブ、という関係になります。 このときのデバイス間の配線および通信の簡単な手順を以下の図に示します。

i2c

I2C通信では、SCLとSDAという2本の信号線を用いますが、実際にデータの送受信はSDA一本のみを介して行われます。SCLには一定の周波数のクロックが流れており、このクロックのHIGH/LOWが切り替わるタイミングに合わせてデータを区切ることで、通信のタイミングをデバイス間で同期させます。

I2C通信では個々のスレーブデバイスが固有の識別番号(スレーブアドレス)を持っており、マスターデバイスはデータ通信時にこのアドレスを最初に送信することで、通信対象のスレーブデバイスを指定します。データ通信中は、データが正しく送信できていることを確認するため、スレーブデバイスが定期的にAcknowledge信号(ACK)を返します。これにより、2本の配線だけで複数のスレーブデバイスと通信を行うことができます。 しかし、これらの複雑な同期処理のためにデータの転送速度が遅くなってしまうことが欠点です。それでも、少ない配線で通信が可能なI2Cは、デバイスの製造コストの低減などの大きなメリットを持ち、多くのデバイスに採用されています。

SPI(エス・ピー・アイ)とは

SPI(Serial Peripheral Interfaceの略)はI2Cと同様にメジャーな通信規格で、I2Cと同じマスター・スレーブモデルを採用しています。I2Cと比べて通信速度が速い点が特長です。SPI通信におけるデバイス間の配線および通信の簡単な手順を以下の図に示します。

spi

I2C通信では、通信の同期のためのクロック信号線(SCK: I2CのSCLとほぼ同じ)、データの送受信用の2本の信号線(MISO, MOSI)を用います。更に、デバイスの指定用の信号線(SS)を、各スレーブデバイスごとに1本使います。図中では二つのスレーブデバイスを接続しているので、この場合は2本必要です。図ではこれらの信号線の名前を仮にSS0, SS1としていますが、出力信号のHIGH/LOWを切り替えることのできる信号線(Raspberry PiではGPIO)であれば、どれでもSSとして利用することができます。

SPIはI2Cと比較してデータ通信を高速に行うことができますが、複数のスレーブデバイスをつなげる場合は工夫が必要です。SPI通信では識別用の信号線(SS)をスレーブデバイスごとに1本用いて、通信対象のデバイスと接続しているSSのみ有効にすることでデバイスを指定します。図ではSS0とSS1の2本だけですが、スレーブデバイスを三つ、四つと増やしていくと、SS2, SS3, …と、接続したデバイスの数だけSS信号線が必要となります。N個のデバイスを繋ぐと必要な信号線の数はN本増えるため、スレーブデバイスが増えると必要な信号線の数がどんどん増えていき、配線や制御が複雑になってしまいます。SPIの図を見ると、先ほどのI2Cの図と比べて配線数がかなり多くなっていることが分かります。

UART(ユーアート)とは

UARTは、これまでに紹介した2つの通信規格とは少し用途が異なります。 I2CやSPIのようなマスター・スレーブモデルとは異なり、UARTは双方向通信を行うことができます。 その仕組みを下記の図に示します。

uart

UARTは1対1のデータ通信を前提としているため、デバイス選択の処理は行いません。データを送信したいデバイスは、送信データをデータの始まりを表すstart bitと、データの終わりを表すstop bitで囲み、これをひとかたまりとして信号線(TX)にデータを送信します。送信元と受信元のデバイスでUARTの設定(データの転送速度やデータサイズ)が一致していれば、送信したデータを相手が受け取ることができます。このように、UARTはマスター/スレーブの区別がないため、二つのデバイスは任意のタイミングで双方向のデータ通信が可能です。

UARTは、主にPC間やマイコン間のコンソール制御に利用されています。1対Nの通信には使えないため、IoTシステムで1台のデバイス(Raspberry Piなど)で複数のセンサを制御したい場合は、マスター・スレーブモデルのI2CやSPIが適していると言えます。

シリアル通信規格のまとめ

今まで解説しました通信規格の特徴をまとめると、以下の表のようになります。

通信形式 I2C SPI UART
通信速度 遅い
(数100K〜数Mbps)
最も速い
(100Mbps以上)
2番目に速い
(数10Mbps)
通信可能なデバイスの数
(マスター対スレーブ)
1対N 1対N 1対1
データ転送に必要な信号線の数 2本(SCL, SDA) 3+N本(SCK, MISO, MOSI, SS(1), SS(2), … , SS(N)) 2本(TX, RX)
通信規格の特徴 2本の信号線のみで複数のデバイスを制御できる。しかしその分デバイス間の同期処理が複雑になり、通信速度は遅い。 通信速度が速く、複数デバイスの制御も可能。しかし、デバイスの数だけ必要な信号線が増えるため、デバイスが増えると配線や制御が煩雑になる。 双方向通信が可能だが、二つのデバイス間での通信を前提としており、複数デバイスの制御はできない。
主な用途 各種デバイスの制御(温湿度センサ、気圧センサ、照度センサ、LCDなど) 各種デバイスの制御(温湿度センサ、加速度センサなど) PCやマイコンのコンソール制御など

このように、各種シリアル通信は様々な規格がありますが、どの通信規格が使えるのかはデバイス側の都合によって既に決まっています。 また、通信速度についても、ほとんどの場合でデバイス側で最大通信速度が決められており、一概にSPIが速い、I2Cが遅いとも言えません。電子工作において通信規格を理解することも重要ですが、通信性能はデバイス自身の性能に依存するため、個人的には各デバイスのデータシートをしっかり読むことも大切だと思います。

簡単ですが、以上で通信規格の解説を終わります。より詳しく知りたい方は、この機会にwebサイトを探してみたり、図書館に行ってみるとよいかもしれませんね!

ZUGYUUUN!のI2C通信APIについて

さて、本題に戻りますが、旧バージョンのZUGYUUUN!では、SPI通信しかサポートしておりませんでした。 今回のバージョンアップによってI2C通信APIを使うことで、I2C通信に対応したセンサやデバイスをZUGYUUUN!を用いてwebブラウザから遠隔操作することができます!

今回追加したAPIの使い方はZUGYUUUN!ホームページReferenceに、実際にAPIを使ったサンプルプログラムはExamplesにそれぞれ載せております。 また、ここで取り上げているサンプルプログラムは、githubからcloneして使うことができます。 詳しい実装内容を知りたい方、自分の環境でも動かしてみたいという方はぜひご覧ください!

おわりに

今回のI2C対応により、ZUGYUUUN!で開発可能なシステムの種類の幅がぐっと広がりました。この機会にぜひZUGYUUUN!を使って見てください!

blog_banner