I2C において、接続されたデバイスはそれぞれ異なるアドレスを持っていて、それらのアドレスを指定して通信することで、一つのシリアル バス上に複数のデバイスを同時接続できるようになっています。I2C デバイスでは、基盤上のジャンパ線などの設定に応じて、このアドレスを事前に用意された幾つかの中から選べるものが一般的ですが、これら用意されたアドレスの個数以上に、更に多くのデバイスを複数使用したい場合には何らかの工夫が必要になります。
そこで、アナログ スイッチを併用することで、RaspberryPi に複数のセンサ モジュールを同時接続できないか実験してみました。
初めに、基本的な例として、気温・湿度・気圧センサ モジュール BME280、加速度・角速度センサ モジュール GY-521、電子コンパス センサ モジュール HMC5883L の 3 つの異なるセンサを同時接続する場合を考えます。これらのセンサ モジュールは、それぞれ異なるアドレスを持っているので、I2C バスの SCL と SDA (と電源と GND)にそれぞれ並列に接続するだけで使うことができます(Fig.1 の上図)。
この時、i2cdetect
コマンドで接続されているデバイスを一覧すると次のような出力を得ます。
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- 77
0x1e が電子コンパス、0x68 が加速度・角速度センサ、0x77 が気温・湿度・気圧センサのアドレスです。I2C では、このアドレスを指定して目的のデバイスと正しく通信することができます。
次に、気温・湿度・気圧センサ モジュール BME280 を 2 個使用して、室内と室外の温度・湿度をそれぞれ計測するような、I2C バス上に同じデバイスが複数個、接続されるような場合を見てみます。
多くの I2C デバイスでは、基盤上のジャンパ線などの設定によって、デバイスのアドレスを事前に用意された幾つかの中から選べるものが一般的です*1。BME280 においても、基盤上のジャンパを設定するか、SDO 端子を GND に接続することで、アドレスを 0x77 または 0x76 からいずれか一方を選択できるようになっています(Fig.1 の下図)。つまり、一つのバス上に、BME280 を最大 2 つまで接続することができます。
この時、i2cdetect
コマンドで接続されているデバイスを一覧すると次のような出力を得ます。
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 77
0x76 が右側の BME280 で、0x77 が左側の BME280 になります。このように、同一デバイスを同じバス上に接続した場合であっても、異なるアドレスが設定されているため、目的のデバイスと正しく通信することができます。
更に、もっとたくさんの気温・湿度・気圧センサ モジュール BME280 を使用して、例えば、数ある部屋ごとの温度・湿度をそれぞれ計測するような場合を考えます*2。しかし、BME280 では、デバイス アドレスの設定が 2 つしか選択できないので、一つの I2C バス上には 2 つまでしか接続することができません。そこで、アナログ スイッチを利用して、同時接続できる数を増やす方法が考えられます*3。
74HC4052 は、4 チャンネルの Analog Multiplexer/Demultiplexer を 2 系統持ったロジック IC で、指先でトグル レバーを倒して回路を切り替える機械式のスイッチと異なり、電気信号を利用して回路の開閉を制御できます。これを利用すれば、I2C バスを見た目上、4 つに増やすことができますので、一つの I2C バスに最大 2 つまで接続できる BME280 を、2×4=8 つまで制御することもできるというわけです。
この回路において、2 つの BME280 は、どちらも同じアドレス 0x77 を持っていますが、マスタ(Raspberry Pi)から見えるのは、74HC4052 の働きによってどちらか一方の BME280 のみです。ここで、GPIO を 0 とすれば、74HC4052 によって X⇔X0, Y⇔Y0
と接続されるので、左側の BME280 と通信することができます。また、GPIO を 1 とすれば、今度は X⇔X1, Y⇔Y1
と接続されるので、右側の BME280 と通信することができます。この回路図では使用していませんが、74HC4052 の B 端子を使用すれば、更に X2~X3 と Y2~Y3 も切り替えることができるので、更に多くのデバイスを接続できます。
A | B | X⇔ | Y⇔ |
---|---|---|---|
0 | 0 | X0 | Y0 |
0 | 1 | X1 | Y1 |
1 | 0 | X2 | Y2 |
1 | 1 | X3 | Y3 |
INH
端子と GPIO を利用して、更に倍々で増やせるかもしれない。