I2C通信¶
I2C とは¶
I2C(Inter-Integrated Circuit)は、マイコンと複数の周辺機器(センサー、メモリ、ディスプレイなど)の間でシンプルに通信する同期通信方式です。
「アイツーシー」または「アイスクエアシー」と読みます。
SPIと同じく同期通信ですが、ケーブルが少なくて済むのが大きな特徴です。
「バス型通信」とは何か¶
I2Cは「バス型通信」です。これは:
- 複数のスレーブデバイスを1本の通信線に全て接続できる
- スレーブのアドレスで区別して通信する
- SPIのように複数のCS線が不要
- ケーブル本数が少ないため配線がシンプル
通信方式の比較¶
| 項目 | I2C(バス) | SPI(ポイント) | UART(ペア) |
|---|---|---|---|
| ケーブル本数 | 2本(SCL/SDA) | 3本以上 | 2本(TX/RX) |
| クロック線 | 必要 | 必要 | 不要 |
| 複数スレーブ対応 | アドレスで区別 | CS線で区別 | サポートなし |
| 通信速度 | 低速(kHz) | 高速(MHz) | 低速(kHz) |
| 配線の複雑さ | シンプル | 複雑 | 中程度 |
I2C の仕組み¶
2本の信号線¶
I2Cにはたった2本の信号線があります:
| ピン | 意味 | 機能 | 特徴 |
|---|---|---|---|
| SCL | Serial Clock Line | クロック信号 | マスターが生成 |
| SDA | Serial Data Line | データ信号 | 双方向通信 |
重要: I2Cの両線は「オープンドレイン」で、プルアップ抵抗(通常4.7kΩ)で高レベルに保たれています。
マスター(ESP32)
┌─── SCL ────────┐
│ │
│ プルアップ抵抗
│ │
└─── SDA ────────┐
│ │
スレーブ1 スレーブ2
(アドレスA0) (アドレスA1)
スレーブアドレス¶
I2Cでは各スレーブに7ビット or 10ビットのアドレスを割り当てます。
| 項目 | 説明 |
|---|---|
| 7ビット | よく使用される標準アドレス(0x00~0x7F) |
| 10ビット | より多くのデバイス接続時に使用 |
Kurikintons の例:
BME280センサー:0x76(7ビットアドレス)
通信速度¶
I2Cの通信速度は「クロック周波数」で指定します:
| モード | 周波数 | 用途 |
|---|---|---|
| Standard | 100kHz | 標準的なI2C |
| Fast | 400kHz | より高速な通信 |
| Fast Plus | 1MHz | 高速通信(対応デバイス少ない) |
Kurikintons での使用¶
概要¶
Kurikintons では、I2C通信を使用してBME280 環境センサーから温度・湿度・気圧を読み取ります。
- 制御対象: BME280 環境センサー
- スレーブアドレス: 0x76
- 通信速度: 100kHz(Standard モード)
- 実装: src/bme280_sensor.cpp
初期化例¶
// I2C(Wire)の初期化
Wire.begin(); // デフォルト:SDA=GPIO21, SCL=GPIO22
// BME280 の初期化
bme280_init();
// センサー値の読み取り
float temp = bme280_read_temperature();
ピン接続¶
ESP32 のI2C標準ピン:
| ピン | I2C信号 | 用途 |
|---|---|---|
| GPIO21 | SDA | データ線 |
| GPIO22 | SCL | クロック線 |
注意: I2Cはオープンドレイン形式のため、プルアップ抵抗が必須です(通常は基板に内蔵)
通信の流れ¶
- マスター(ESP32)がスタート条件を送信
- スレーブアドレス + 読み込み/書き込みビットを送信
- スレーブが応答(ACK信号)
- データの送受信
- ストップ条件を送信
トラブルシューティング¶
センサーが認識されない¶
- I2Cアドレスを確認
Wire.beginTransmission(0x76)で正しいアドレスか確認-
別のスキャンツール(I2C Scanner)で探索
-
配線を確認
- SDA(GPIO21)と SCL(GPIO22)の接続確認
-
プルアップ抵抗が接続されているか確認(通常は基板内蔵)
-
複数デバイスの干渉
- 同じI2Cバスに複数デバイスがある場合、アドレスが重複していないか確認
通信エラー(ACK なし)¶
- センサーの電源供給を確認
- I2C通信速度が高すぎる可能性 → Standard(100kHz)で試す
- ケーブル長が長い場合、ノイズ対策が必要
データが異常な値を返す¶
- センサーが完全に初期化されているか確認
- 複数のセンサーが同じアドレスを使用していないか確認
- I2Cライブラリの初期化順序を確認