戻る

ArduinoでI2Cスキャナー:バス上のすべてのデバイスを見つける

はじめに

新しいI2CセンサーやディスプレイをArduinoに接続したとき、「このデバイスのアドレスは何だろう?」と疑問に思ったことはありませんか?あなただけではありません!I2Cプロトコルは、たった2本のワイヤーで複数のデバイスと通信できる強力な方法ですが、すべてのデバイスには固有のアドレスがあり、そのアドレスがデータシートからすぐにわからないこともあります。そこで役立つのがI2Cスキャナーです。これは、可能なすべてのアドレスを調べ、応答があったアドレスを報告するシンプルなスケッチです。

このチュートリアルでは、Arduino UnoとSSD1306 OLEDディスプレイ(バス上の既知のデバイスとしても機能します)を使ってI2Cスキャナーを構築します。すべてをVelxioのブラウザ内シミュレーターで実行するため、ハードウェアは必要ありません。最後には、I2Cバスの仕組み、デバイスの配線方法、そしてそれらをスキャンするコードの書き方を理解できるでしょう。

さあ、始めましょう!

回路の解説

Velxioシミュレーターキャンバス上のi2c-scannerの回路図

この回路は驚くほどシンプルです。必要なコンポーネントはたった2つです:

配線の詳細

4本のワイヤーでOLEDをArduinoに接続します:

ArduinoピンOLEDピンワイヤーの色
A4 (SDA)DATA
A5 (SCL)CLK
GNDGND
5VVIN

注記: Arduino Unoでは、A4とA5が専用のI2Cピンです。他のボードでは異なるピンを使用する場合があります(例:ESP32のSDA/SCL)。

Velxioシミュレーターでは、コンポーネントピッカーからOLEDを追加し、ピンをクリックして配線できます。キャンバスツールバーは、接続を容易にするためのズームやパンに役立ちます。

シミュレーションビューポート上のVelxioキャンバスツールバー

コードの解説

Velxio Monacoエディター内のi2c-scannerのソースコード

それではコードを見てみましょう。Velxioでコードエディターを開きます(シンタックスハイライト付きのMonacoエディターが表示されます)。このスケッチはArduino C++で書かれており、組み込みのWireライブラリを使用しています。

ライブラリのインクルード

#include <Wire.h>

Wireライブラリは、すべての低レベルのI2C通信を処理します。Arduino IDEに含まれているため、追加のインストールは必要ありません。

セットアップ関数

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("===========================");
  Serial.println("  I2C Bus Scanner (TWI)");
  Serial.println("===========================");
  Serial.println("Scanning...");
  Serial.println();

  int devicesFound = 0;

  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    byte error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("  Device found at 0x");
      if (addr < 16) Serial.print("0");
      Serial.print(addr, HEX);

      // 既知のアドレスを識別
      switch (addr) {
        case 0x27: Serial.print("  (PCF8574 LCD backpack)"); break;
        case 0x3C: Serial.print("  (SSD1306 OLED)"); break;
        case 0x48: Serial.print("  (Temperature sensor)"); break;
        case 0x50: Serial.print("  (EEPROM)"); break;
        case 0x68: Serial.print("  (DS1307 RTC)"); break;
        case 0x76: Serial.print("  (BME280 sensor)"); break;
        case 0x77: Serial.print("  (BMP180/BMP280)"); break;
      }
      Serial.println();
      devicesFound++;
    }
  }

  Serial.println();
  Serial.print("Scan complete. ");
  Serial.print(devicesFound);
  Serial.println(" device(s) found.");

  if (devicesFound == 0) {
    Serial.println("No I2C devices found. Check connections.");
  }
}

分解してみましょう:

  1. Wire.begin() – ArduinoをI2Cマスターとして初期化します。
  2. Serial.begin(9600) – シリアル通信を9600ボーで開始し、シリアルモニターで結果を確認できるようにします。
  3. ループはアドレス1から126(0x01から0x7E)を反復処理します。アドレス0は一般呼び出し用に、127は特別な目的用に予約されています。
  4. Wire.beginTransmission(addr) – 指定されたアドレスへの送信を開始します。
  5. Wire.endTransmission() – 送信を終了し、エラーコードを返します。エラーが0の場合、デバイスが応答(ACK)したことを意味します – デバイスが見つかりました!
  6. アドレスの表示 – 読みやすくするために先頭ゼロを付けて16進数形式で表示します。
  7. switch文 – 既知のアドレスに基づいて一般的なデバイスを識別します。これはオプションですが便利です。
  8. デバイスのカウント – ACKごとにdevicesFoundをインクリメントします。
  9. 最終レポート – 見つかったデバイスの総数を表示します。

ループ関数

void loop() {
  // 10秒ごとに再スキャン
  delay(10000);
  Serial.println("\nRescanning...");
  setup();
}

loop()関数は単に10秒待機し、その後setup()を再度呼び出して再スキャンします。これは、システムの実行中にデバイスを追加または削除する場合に便利です。

学生向けの重要な概念

I2Cとは?

I2C(Inter-Integrated Circuit)は、TWI(Two-Wire Interface)とも呼ばれ、同期シリアル通信プロトコルです。2本の双方向オープンドレインライン、SDA(データ)とSCL(クロック)を使用します。バス上の各デバイスには固有の7ビットアドレスがあります(10ビットアドレスも存在します)。マスター(Arduino)が通信を開始し、クロック信号を生成します。

スキャナーの仕組み

スキャナーは、スタートコンディションに続いてアドレスバイト(7ビットアドレス+読み取り/書き込みビット)を送信します。そのアドレスのデバイスが存在する場合、9番目のクロックパルス中にSDAをLowにすることでACK(応答)を返します。デバイスが応答しない場合はNACK(非応答)が受信され、endTransmission()はゼロ以外のエラーコードを返します。

なぜスキャナーを使うのか?

よくある落とし穴とデバッグのコツ

  1. 配線ミス – SDAとSCLが正しく接続されているか再確認してください。入れ替えると動作しません。
  2. プルアップ抵抗の欠落 – I2CラインにはVCCへのプルアップ抵抗(通常4.7kΩ)が必要です。多くのブレイクアウトボードには含まれていますが、ゼロから構築する場合は忘れないでください。
  3. アドレス競合 – 2つのデバイスが同じアドレスを共有している場合、どちらも確実に動作しません。スキャナーを使用して競合を検出してください。
  4. ボーレートの不一致 – スキャナーはデフォルトの100 kHz(標準モード)を使用します。一部のデバイスはより低速が必要な場合があります。高速モードにするにはWire.setClock(400000)で変更できます。
  5. シリアルモニターに出力が表示されない – シリアルモニターのボーレートが9600に一致していることを確認してください。

Velxioでは、エディターツールバーからシリアルモニターを開くことができます。出力が表示されない場合は、コードが正常にコンパイルされたか確認してください(コンソールのエラーを確認)。

コンパイルと実行コントロールがあるVelxioエディターツールバー

推奨される拡張機能

基本的なスキャナーが動作したら、次の拡張機能を試してみてください:

Velxioでライブラリを追加するには、ライブラリマネージャーを使用します。

インストール済みのArduinoライブラリを一覧表示するVelxioライブラリマネージャーモーダル

結論

これで、任意のArduino互換ボードで動作するユニバーサルI2Cスキャナーを構築しました。このツールは、新しいI2Cモジュールのデバッグや探索に非常に役立ちます。何より素晴らしいのは、ハードウェアなしでブラウザ上のVelxioで今すぐ実行できることです。

自分で試してみませんか?ライブの例を開いてスキャンを始めましょう:

👉 VelxioでI2Cスキャナーを起動

ハッピーハッキング!


共有:
David Montero

執筆者

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

関連記事


前の記事
VelxioでDS1307を使ったI2C RTC時計
次の記事
ArduinoによるシリアルLED制御:コマンド送信でLEDを点滅させる