I²CセンサーをArduinoやESP32へ接続したものの、「センサーが認識されない」「I²Cアドレスが分からない」ということはありませんか?
そんなときに便利なのがI²Cスキャナ(I2C Scanner)です。
I²Cスキャナを実行すると、SDA・SCLに接続されているI²Cデバイスを順番に探索し、応答があったI²Cアドレスをシリアルモニターへ表示できます。
例えばKUMITATE-SENSORを接続してI²Cスキャナを実行すると、搭載されているSHT40、BH1750、MSA3S02をそれぞれ異なるI²Cアドレスとして確認できます。
この記事では、Arduino・ESP32で使用できるI²Cスキャナのサンプルプログラムと、検出されたアドレスの見方、デバイスが見つからない場合の確認方法まで解説します。
I²Cスキャナとは?
I²Cスキャナは、I²Cバス上に存在するデバイスを探索するためのプログラムです。
I²Cでは、マイコンとセンサーなどのデバイスを主に次の2本の信号線で接続します。
- SDA:データ信号
- SCL:クロック信号
I²Cでは複数のデバイスが同じSDA・SCLを共有できます。
では、マイコンはどのデバイスと通信するのかをどうやって区別しているのでしょうか。
そこで使われるのがI²Cアドレスです。
例えば、I²Cデバイスには次のようなアドレスがあります。
| デバイス | I²Cアドレス例 |
|---|---|
| BH1750 | 0x23 |
| SHT40-A | 0x44 |
| MSA3S02 | 0x62 |
マイコンはこのアドレスを指定することで、同じSDA・SCL上に接続されている複数のデバイスから通信相手を選択できます。
I²C通信そのものについては、以下の記事で詳しく解説しています。
I²Cスキャナで何が分かる?
I²Cスキャナを使うと、マイコンから応答を確認できるI²Cアドレスを調べられます。
例えば、BH1750を接続している状態でI²Cスキャナを実行して、
I2C device found at address 0x23
と表示された場合、アドレス0x23のI²Cデバイスから応答があったことが分かります。
逆に何も検出されなければ、SDA・SCLの配線や電源、GPIO設定などを確認するきっかけになります。
そのためI²Cデバイスを初めて接続したときは、いきなりセンサー制御プログラムを書くのではなく、最初にI²Cスキャナを実行して通信できているか確認するとトラブルを切り分けやすくなります。
Arduino・ESP32で使えるI²Cスキャナ
Arduino環境では、標準のWireライブラリを使ってI²Cスキャナを作れます。
まずは基本的なサンプルプログラムです。
#include <Wire.h>
void setup()
{
Serial.begin(115200);
Wire.begin();
delay(1000);
Serial.println("I2C Scanner");
}
void loop()
{
byte error;
byte address;
int deviceCount = 0;
Serial.println("Scanning...");
for (address = 1; address < 127; address++)
{
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
{
Serial.print("0");
}
Serial.println(address, HEX);
deviceCount++;
}
}
if (deviceCount == 0)
{
Serial.println("No I2C devices found");
}
else
{
Serial.print(deviceCount);
Serial.println(" device(s) found");
}
Serial.println();
delay(5000);
}
プログラムを書き込んだら、シリアルモニターを115200bpsで開きます。
I²Cデバイスが接続されていれば、検出されたアドレスが表示されます。
I²Cスキャナはどうやってデバイスを探している?
I²Cスキャナの仕組みは意外とシンプルです。
先ほどのプログラムでは、次の部分でアドレスを順番に変更しています。
for (address = 1; address < 127; address++)
そして、
Wire.beginTransmission(address);
error = Wire.endTransmission();
によって、そのアドレスに対して通信を開始し、デバイスから応答があるか確認します。
Wire.endTransmission()の戻り値が0なら、正常に応答が得られたことを表します。
if (error == 0)
{
// I2Cデバイスを発見
}
つまり、I²Cスキャナはアドレスを順番に変えながら、「このアドレスに誰かいますか?」と確認しているようなものです。
ESP32ではSDA・SCLのGPIOを指定できる
ESP32では、使用するボードに合わせてSDA・SCLのGPIO番号を指定できます。
例えば、
Wire.begin(8, 9);
とすると、
- SDA:GPIO8
- SCL:GPIO9
としてI²Cを使用します。
KUMITATE-C3ではSDAにGPIO8、SCLにGPIO9を使用しているため、I²Cスキャナでは次のようにします。
#include <Wire.h>
#define SDA_PIN 8
#define SCL_PIN 9
void setup()
{
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
delay(1000);
Serial.println("I2C Scanner");
}
void loop()
{
byte error;
byte address;
int deviceCount = 0;
Serial.println("Scanning...");
for (address = 1; address < 127; address++)
{
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
{
Serial.print("0");
}
Serial.println(address, HEX);
deviceCount++;
}
}
if (deviceCount == 0)
{
Serial.println("No I2C devices found");
}
else
{
Serial.print(deviceCount);
Serial.println(" device(s) found");
}
Serial.println();
delay(5000);
}
KUMITATE-SENSORを実際にスキャンしてみる
実際に複数のI²Cデバイスを接続した場合、I²Cスキャナではどのように見えるのでしょうか。
KUMITATE-SENSORには、次の3種類のI²Cセンサーを搭載しています。
| センサー | 測定内容 | I²Cアドレス |
|---|---|---|
| BH1750 | 照度 | 0x23 |
| SHT40-A | 温度・湿度 | 0x44 |
| MSA3S02 | 3軸加速度 | 0x62 |
KUMITATE-C3にKUMITATE-SENSORを接続してI²Cスキャナを実行すると、正常に接続されていれば次のように3つのアドレスを確認できます。
Scanning...
I2C device found at address 0x23
I2C device found at address 0x44
I2C device found at address 0x62
3 device(s) found
この結果から、同じSDA・SCLに接続されている3種類のI²Cデバイスが、それぞれ異なるアドレスで認識されていることが分かります。
このようにI²Cスキャナは、複数のI²Cデバイスが正しく認識されているか確認する用途にも便利です。
I²Cアドレスが分かればセンサーを制御できる
I²Cスキャナでアドレスが分かったら、プログラムからそのアドレスを指定して通信します。
例えばBH1750が0x23で検出された場合は、
#define BH1750_ADDR 0x23
のようにアドレスを指定できます。
SHT40-Aなら、
#define SHT40_ADDR 0x44
MSA3S02なら、
#define MSA3S02_ADDR 0x62
というように、それぞれのアドレスを指定して通信します。
同じセンサーでもI²Cアドレスが違うことがある
I²Cスキャナが便利なのは、データシートやWebサイトに書かれているアドレスと、実際に使用しているデバイスのアドレスが異なる場合にも確認できることです。
例えばBH1750では、ADDR端子の状態によって0x23または0x5Cを使用できます。
そのため、「BH1750だから0x23のはず」と決めつけるより、実際にI²Cスキャナで確認すると確実です。
BH1750の使い方やI²Cアドレスについてはこちらの記事で詳しく解説しています。
BH1750とは?Arduino・ESP32で照度(lux)を測定する方法を解説
SHT40についても製品バリエーションによってI²Cアドレスが異なります。
SHT40とは?Arduino・ESP32で温度・湿度を測定する方法を解説
I²Cデバイスが見つからない場合
I²Cスキャナを実行しても、
No I2C devices found
と表示される場合があります。
この場合は、プログラムだけでなく配線や電源も確認します。
SDAとSCLを確認する
まず確認したいのがSDAとSCLです。
SDAとSCLを逆に接続していないか、使用しているマイコンのGPIO番号とWire.begin()の設定が一致しているか確認してください。
電源とGNDを確認する
センサーへ正しい電圧が供給されているか確認します。
また、マイコンとセンサーのGNDが正しく接続されていることも確認してください。
プルアップ抵抗を確認する
I²CのSDA・SCLは、基本的にプルアップ抵抗が必要です。
市販のセンサーモジュールでは基板上にプルアップ抵抗が実装されていることもありますが、ICを直接実装した基板では回路設計を確認してください。
I²Cアドレスを決めつけない
同じ種類のセンサーでも、端子設定や製品バリエーションによってアドレスが異なる場合があります。
「データシートでは0x23だから必ず0x23」と考えるのではなく、実際にI²Cスキャナで確認してみると原因を見つけやすくなります。
複数のI²Cデバイスが表示されても正常?
複数のアドレスが表示されても異常ではありません。
I²Cは、同じSDA・SCLへ複数のデバイスを接続できるように設計された通信方式です。
例えばKUMITATE-SENSORでは、SHT40、BH1750、MSA3S02の3種類が同じI²Cバスへ接続されています。
0x23 → BH1750
0x44 → SHT40-A
0x62 → MSA3S02
アドレスが重複していなければ、マイコンはアドレスを指定してそれぞれのデバイスと個別に通信できます。
複数のI²Cセンサーを同時に接続する方法については、以下の記事で詳しく解説します。
Arduino・ESP32で複数のI²Cデバイスを接続する方法
KUMITATE-SENSORなら複数のI²Cデバイスを試せる
I²Cスキャナや複数デバイスの制御を実際に試したい場合は、KUMITATE-SENSORを利用できます。
KUMITATE-SENSORには、温度・湿度センサーのSHT40、照度センサーのBH1750、3軸加速度センサーのMSA3S02を搭載しています。
3種類ともI²Cデバイスなので、1組のSDA・SCLを使って複数デバイスの探索や制御を試すことができます。
KUMITATE-C3だけでなく、3.3V系I²Cに対応した各種マイコンから使用できます。
サンプルプログラムとREADMEもGitHubで公開しています。
GitHubでKUMITATE-SENSORのサンプルを見る
まとめ
I²Cスキャナを使うと、ArduinoやESP32に接続されているI²Cデバイスのアドレスを簡単に確認できます。
特に、I²Cセンサーを接続したのに動作しない場合には、いきなりセンサー制御プログラムを修正するのではなく、まずI²Cスキャナを実行すると原因を切り分けやすくなります。
- I²Cスキャナで接続されているデバイスを探索できる
- 応答したI²Cアドレスを確認できる
- ArduinoではWireライブラリを利用できる
- ESP32ではSDA・SCLのGPIOを指定できる
- デバイスが見つからなければ配線・電源・GPIO・プルアップ抵抗を確認する
- 複数のI²Cデバイスも同時に検出できる
I²Cセンサーを新しく接続したら、まずI²Cスキャナを実行する習慣をつけておくと、I²C通信のデバッグがかなり楽になります。

