ArduinoやESP32でI²Cセンサーを使っていると、「SDAとSCLに複数のセンサーを接続しても大丈夫?」と疑問に思うことがあります。
結論からいうと、I²Cは複数のデバイスで同じSDA・SCLを共有できる通信方式です。
例えば、温湿度センサー、照度センサー、加速度センサーを同じSDA・SCLへ接続し、ArduinoやESP32からそれぞれ個別にデータを取得できます。
ただし、複数のI²Cデバイスを接続するときには、I²Cアドレスの重複、プルアップ抵抗、電源電圧などに注意する必要があります。
この記事では、Arduino・ESP32で複数のI²Cセンサーを接続する仕組みから、アドレスが重複した場合の対処方法まで解説します。
I²Cは複数のセンサーを同時に接続できる
I²Cでは、主に次の2本の信号線を使って通信します。
- SDA:データ信号
- SCL:クロック信号
特徴的なのは、複数のI²Cデバイスで同じSDA・SCLを共有できることです。
例えばESP32へ3種類のセンサーを接続する場合、イメージとしては次のようになります。
ESP32
│
├─ SDA ──┬── SHT40
│ ├── BH1750
│ └── MSA3S02
│
└─ SCL ──┬── SHT40
├── BH1750
└── MSA3S02
SDAやSCLをセンサーごとに用意する必要はありません。
同じI²Cバスへ並列に接続できます。
I²C通信そのものについては、以下の記事で詳しく解説しています。
同じSDA・SCLなのに、どうやってセンサーを区別する?
複数のセンサーが同じSDA・SCLへ接続されていると、「どのセンサーと通信しているのか分からなくならないの?」と思うかもしれません。
そこで使われるのがI²Cアドレスです。
I²Cデバイスには、それぞれ通信相手を識別するためのアドレスがあります。
例えばKUMITATE-SENSORに搭載している3種類のセンサーでは、次のアドレスを使用しています。
| センサー | 測定内容 | I²Cアドレス |
|---|---|---|
| BH1750 | 照度 | 0x23 |
| SHT40-A | 温度・湿度 | 0x44 |
| MSA3S02 | 3軸加速度 | 0x62 |
3種類とも同じSDA・SCLへ接続されていますが、アドレスが異なるため、マイコンは通信相手を区別できます。
イメージとしては、
0x23 → BH1750と通信
0x44 → SHT40-Aと通信
0x62 → MSA3S02と通信
という仕組みです。
まずI²Cスキャナで確認してみる
複数のI²Cセンサーを接続したら、最初にI²Cスキャナを実行してみると便利です。
I²Cスキャナを使うと、現在I²Cバス上で応答しているデバイスのアドレスを確認できます。
KUMITATE-SENSORを接続した場合、正常に通信できていれば次のように表示されます。
Scanning...
I2C device found at address 0x23
I2C device found at address 0x44
I2C device found at address 0x62
3 device(s) found
これで、BH1750、SHT40-A、MSA3S02の3つが同じI²Cバス上で認識されていることを確認できます。
I²Cスキャナのプログラムや使い方については、以下の記事で詳しく解説しています。
ESP32で3種類のI²Cセンサーを同時に使う
では実際に、複数のI²Cセンサーを同じプログラムから使用してみましょう。
KUMITATE-C3では、I²Cに次のGPIOを使用します。
| 信号 | GPIO |
|---|---|
| SDA | GPIO8 |
| SCL | GPIO9 |
ESP32では、次のようにSDA・SCLを指定できます。
Wire.begin(8, 9);
重要なのは、センサーごとにWire.begin()する必要はないということです。
I²Cバスを初期化したあと、それぞれのアドレスを指定して通信します。
複数のI²Cアドレスをプログラムで指定する
例えば3種類のセンサーを使用する場合、それぞれのアドレスを次のように定義できます。
#include <Wire.h>
#define BH1750_ADDR 0x23
#define SHT40_ADDR 0x44
#define MSA3S02_ADDR 0x62
#define SDA_PIN 8
#define SCL_PIN 9
void setup()
{
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
Serial.println("I2C start");
}
void loop()
{
// 0x23へアクセス → BH1750
// 0x44へアクセス → SHT40
// 0x62へアクセス → MSA3S02
delay(1000);
}
SDAとSCLは共通ですが、通信するときに指定するアドレスが異なります。
そのため、1つのプログラムから複数のI²Cセンサーを順番に制御できます。
同じI²Cアドレスのデバイスを接続するとどうなる?
複数のI²Cデバイスを使うときに問題になりやすいのが、I²Cアドレスの重複です。
例えば、同じI²Cアドレスを持つセンサーを2個、同じI²Cバスへ接続したとします。
ESP32
│
├─ SDA/SCL ── センサーA 0x23
│
└─ SDA/SCL ── センサーB 0x23
マイコンから見ると、どちらも同じ0x23です。
この状態では、通常のアドレス指定だけで「センサーAだけ」「センサーBだけ」と個別に選択して通信することができません。
そこで、同じアドレスのI²Cデバイスを複数使用する場合には対策が必要になります。
方法1:I²Cアドレスを変更する
最も簡単なのは、センサー側のI²Cアドレスを変更する方法です。
I²Cデバイスによっては、ADDRやAD0などの端子を使ってアドレスを変更できます。
例えばBH1750では、ADDR端子の状態によって次の2種類のI²Cアドレスを使用できます。
| ADDR | I²Cアドレス |
|---|---|
| Low | 0x23 |
| High | 0x5C |
そのためBH1750を2個使用する場合、
BH1750 #1 → 0x23
BH1750 #2 → 0x5C
と設定すれば、同じSDA・SCLへ接続しても個別に通信できます。
BH1750のI²Cアドレスや使い方については、こちらの記事で詳しく解説しています。
BH1750とは?Arduino・ESP32で照度(lux)を測定する方法を解説
方法2:別のI²Cバスを使う
マイコンによっては、複数のI²Cコントローラを利用できます。
その場合、同じアドレスのデバイスを別々のI²Cバスへ接続する方法があります。
I2C BUS 0
└── Sensor A 0x23
I2C BUS 1
└── Sensor B 0x23
同じアドレスでも物理的に別のI²Cバスへ分離されているため、個別に通信できます。
ただし、利用できるI²CコントローラやGPIOの割り当て方法はマイコンやArduinoコアによって異なるため、使用するボードの仕様を確認してください。
方法3:I²Cマルチプレクサを使う
アドレスを変更できず、別のI²Cバスを用意するのも難しい場合は、I²Cマルチプレクサを使用する方法があります。
代表的なICとしてTCA9548Aがあります。
TCA9548Aでは、1つのI²Cバスを複数のチャンネルへ切り替えて使用できます。
ESP32
│
└── TCA9548A
│
├── CH0 ── Sensor A 0x23
│
├── CH1 ── Sensor B 0x23
│
└── CH2 ── Sensor C 0x23
各センサーは別のチャンネルへ接続されるため、同じI²Cアドレスを持つデバイスでも切り替えて使用できます。
同じ種類のI²Cセンサーを多数接続したい場合などに利用できる方法です。
複数接続するときはプルアップ抵抗にも注意
I²CではSDAとSCLをプルアップして使用します。
ここで注意したいのが、市販のI²Cセンサーモジュールを複数接続する場合です。
センサーモジュールによっては、それぞれの基板にSDA・SCL用のプルアップ抵抗が実装されています。
例えば3枚のモジュールすべてに4.7kΩのプルアップ抵抗が実装されている場合、それらはI²Cバス上で並列接続されます。
4.7kΩ
4.7kΩ
4.7kΩ
↓
すべて並列接続
同じ抵抗値が3本並列になった場合、合成抵抗は約1.57kΩになります。
プルアップ抵抗が小さくなりすぎると、I²C信号がLowになったときに流れる電流が増えます。
一方で抵抗値が大きすぎると、SDA・SCLの立ち上がりが遅くなり、高速通信や配線容量が大きい環境で問題になる場合があります。
そのため、「センサーモジュールを追加するたびにプルアップ抵抗も追加すればよい」というわけではありません。
I²Cデバイスは何個まで接続できる?
「I²Cセンサーは最大何個まで接続できるの?」という疑問もあります。
I²Cではアドレスを使ってデバイスを区別しますが、実際に接続できる数はアドレスの数だけで単純に決まるわけではありません。
実際の回路では、次のような条件も影響します。
- I²Cアドレスの重複
- 各デバイスの入力容量
- 基板やケーブルによる配線容量
- プルアップ抵抗
- I²Cクロック周波数
- 配線距離
- 電源電圧
特にデバイス数や配線が増えるほどバス容量も大きくなるため、「アドレスが空いているから何個でも接続できる」と考えるのではなく、回路全体として確認する必要があります。
複数のI²Cセンサーが動かないときの確認ポイント
1個では動作するのに、2個以上接続すると動かなくなる場合は、次のポイントを確認します。
- I²Cアドレスが重複していないか
- SDA・SCLが正しく共通接続されているか
- GNDが共通になっているか
- 各デバイスの電源電圧が適切か
- プルアップ抵抗が強くなりすぎていないか
- 配線が長くなりすぎていないか
- I²Cスキャナですべてのデバイスが認識されているか
特に便利なのがI²Cスキャナです。
例えば3個接続しているのに2個しか表示されなければ、認識されていないデバイスを絞り込めます。
KUMITATE-SENSORは3種類のI²Cセンサーを同時に使用している
複数のI²Cセンサーを実際に動かして仕組みを確認したい場合は、KUMITATE-SENSORを利用できます。
KUMITATE-SENSORには、次の3種類のセンサーを搭載しています。
| センサー | 測定内容 | I²Cアドレス |
|---|---|---|
| SHT40-A | 温度・湿度 | 0x44 |
| BH1750 | 照度 | 0x23 |
| MSA3S02 | 3軸加速度 | 0x62 |
3種類とも同じSDA・SCLを共有しています。
SDA ──┬── SHT40-A 0x44
├── BH1750 0x23
└── MSA3S02 0x62
SCL ──┬── SHT40-A 0x44
├── BH1750 0x23
└── MSA3S02 0x62
それぞれI²Cアドレスが異なるため、1組のSDA・SCLで3種類のセンサーを個別に制御できます。
KUMITATE-C3だけでなく、3.3V系I²Cに対応した各種マイコンから利用できます。
また、HY2.0-4Pコネクタを搭載しているため、対応するI²Cセンサーを同じI²Cバスへ追加して拡張することもできます。
3種類のセンサーをまとめて動作確認できるサンプルプログラムもGitHubで公開しています。
GitHubでKUMITATE-SENSORのサンプルを見る
SHT40・BH1750・MSA3S02の使い方
KUMITATE-SENSORに搭載している各センサーについては、それぞれ個別の記事でも詳しく解説しています。
温度・湿度を測定するSHT40はこちらです。
SHT40とは?Arduino・ESP32で温度・湿度を測定する方法を解説
照度を測定するBH1750はこちらです。
BH1750とは?Arduino・ESP32で照度(lux)を測定する方法を解説
3軸加速度を測定するMSA3S02はこちらです。
MSA3S02とは?Arduino・ESP32で3軸加速度を測定する方法を解説
まとめ
I²Cでは、複数のセンサーを同じSDA・SCLへ接続できます。
マイコンはI²Cアドレスを使って通信相手を区別するため、アドレスが異なっていれば複数のデバイスを同じI²Cバス上で個別に制御できます。
- I²Cでは複数のデバイスでSDA・SCLを共有できる
- 各デバイスはI²Cアドレスで区別する
- I²Cスキャナを使うと接続されているアドレスを確認できる
- 同じアドレスのデバイスは、そのままでは個別に選択できない
- ADDR端子などでアドレスを変更できる場合がある
- 別のI²Cバスへ分ける方法もある
- TCA9548AなどのI²Cマルチプレクサを使う方法もある
- 複数のモジュールを接続するときはプルアップ抵抗にも注意する
まずはアドレスの異なる2~3種類のI²Cセンサーを同じSDA・SCLへ接続し、I²Cスキャナでそれぞれのアドレスが表示されることを確認すると、I²Cの仕組みを理解しやすくなります。
KUMITATE-SENSORではSHT40-A、BH1750、MSA3S02の3種類を同じI²Cバスへ接続しているため、複数I²Cデバイスの制御を実機で確認できます。

