デバイスとセンサー間を、2線シリアルインターフェイスバスで通信します。
はじめに
配線を複雑にしないで、プロジェクトに複雑な機能を追加するいい方法は、I2C(Inter-Integrated Circuit)を利用することです。全てのArduinoボードでI2Cプロトコルはサポートされています。数本の配線だけで、センサーやディスプレイ、モータードライバ―など、複数の周辺デバイスを接続することができます。大量に配線せずに、柔軟性が増し、プロトタイピングの速度が向上します。どのように動作するかや、異なる標準にどのように実装されたか、自分自身のI2Cデバイスを構築するためのWireライブラリの使い方を紹介します。
I2Cとは何か?
I2Cプロトコルは、2本の信号線を使いデータを送受信します。一つはシリアルクロックピン(Serial Clock Pin: SCL)で、Arduinoコントローラーボードが定期的にパルスを送信します。もう一つは、シリアルデータピン(Serial Data Pin: SDA)で、2つのデバイス間でデータを送信します。
I2Cでは、コントローラーデバイスが一つあり、一つ以上のペリフェラルデバイスが、コントローラーのSCLとSDAに接続されます。
クロックラインがLOWからHIGHに変わると(クロックパルスの立ち上がり)、1ビットの情報が、SDA線を通じ、ボードからI2Cデバイスに送信されます。クロックラインがパルスを送信し続けると、7ビットか8ビットのアドレスとコマンドやデータが形成されるまで、データが送信されます。この情報がビットごとに送信されると、呼び出されたデバイスは要求を実行し、必要に応じ、コントローラによってSCL上に継続して生成されているクロックを使い、同じデータ線を通じて、データをボードに返します。
I2Cバスに接続されている各デバイスは、コントローラーから独立していますが、コントローラーから要求されると、情報を返信します。
I2Cプロトコルでは、有効なデバイスが個別のアドレスを持ち、コントローラーとペリフェラルデバイスの双方が、一本の信号線で順に通信するので、マイクロコントローラーのたった2本のピンを使うだけで、Arduinoボードは、多くのデバイスや他のボードと(順に)通信することができます。
低位のビットレベルのI2Cメッセージは以下のようになっています。

I2Cメッセージ
- コントローラーは、データピン(SDA)上のI2Cバスを通じて命令を送信します。命令にはアドレスが付与されているので、正しいデバイスだけが受信します。
- コントローラーが受信したいのか、送信したいのかを区別するビットが付与されています。
- 想定外の結果を引き起こさないように、各メッセージは応答が必要です。受信側が前の情報を確認すると、コントローラーに知らせ、次のビットの組に進むことができます。
- 8ビットのデータ
- 別の確認ビット
- 8ビットのデータ
- 別の確認ビット
ところで、コントローラーとペリフェラルはどのようにして、アドレスやメッセージなどがどこから始まり、どこで終わるかを知るのでしょうか? そのために、SCL線があります。これはコントローラーのクロックをデバイスに同期させ、同時に次の命令に進むことを保証します。
しかし、実際には上記のことを考える必要はほとんどありません。Arduinoエコシステムには、全てを取り扱うWireライブラリがあるからです。
ArduinoのI2cピン
以下の表では、異なるボードフォームファクタとI2C用のピンを示します。
| Form factor | SDA | SCL | SDA1 | SCL1 | SDA2 | SCL2 |
|---|---|---|---|---|---|---|
| UNO | SDA/A4 | SCL/A5 | ||||
| Nano | A4 | A5 | ||||
| MKR | D11 | D12 | ||||
| GIGA | D20 | D21 | D102 | D101 | D9 | D8 |
| Mega & Due | D20 | D21 |
I2Cの配線
以下にI2Cブレイクアウトモジュールを配線するいくつかの方法を示します。どれが最適なのかは、モジュールや要件に依存します。
ブレイクアウトボード
ブレッドボード上で電線を直接配線するブレイクアウトモジュールがあります。このようなモジュールをArduinoボードに接続するには、以下のように配線します。
- VCC* - 5V/3V3ピン(ブレイクアウトモジュールに依存)
- GND* - GND
- SDA - SDA
- SCL - SCL
*ピンの名前はモジュールに依存します。VCCは"VIN"や"+“などです。GNDは、”-“の場合もあります。
センサーをUNO R4 WiFiに接続する例です。

UNO R4 WiFiのI2C配線
QwiicとSTEMMA QT
ブレイクアウトモジュールやセンサーの市場を調査すると、I2Cプロトコルに関刷る標準が確立された、完全なエコシステムが存在することがわかります。このような標準の例には、Sparkfunが開発したQwiicや、Adafruitが開発したSTEMMA QTがあります。QwiicとSTEMMAは双方とも、I2Cデバイス用に、4ピンのJST SHコネクターを使い、サードパーティが互換性を持ったハードウェアを設計するのを容易にしています。標準コネクターがあることで、デバイスにQwiicやSTEMMA QTの文言があるとUNO R4 WiFiのようにQwiicやSTEMMA QTコネクタを持つArduinoボードで動作することがわかります。
QwiicとSTEMMAは双方とも、SDAとSDLに加え、電源とアース用の電線も一つにまとめた完全なキットです。

UNO R4 WiFiのQwiic/STEMMA QTコネクタでのI2C
両者の違いは?
QwiicとSTEMMAは双方ともI2Cを使っていますが、両方の標準を使うモジュールを詳しく調べても、両者の違いを示すのは難しいかもしれません。しかし違いはあります。この違いは、それらをどのように使うのか、何のために使うのかに関して影響があります。
Qwiicは、コントローラー(ペリフェラルにはありません)に、レベルシフトと電圧調整機能があります。Qwiicは3.3Vロジックのみです。これにより使い方が簡単になり、利用者にとっては、設計や回路を組み立てるときの間違いが一つ減ります。
一方、STEMMA QTにはこれがありません。3.3Vと5Vの両方のロジックをモジュールは使います。これは、回路を組み立てるときに考えることが一つ増えますが、電源やロジックに対する要件に柔軟性をもたらします。
STEMMA QTのピンの順序は、Qwiicのピンの順序と同じです。これにより、2つの標準間で互換性が生じます。
Grove
Groveはもう一つのコネクタの標準で、seeed studioが開発しました。Groveコネクタを持つモジュールは多くありますが、その一部だけがI2Cに対応しています。Groveコネクタを内蔵するArduinoボードはありませんが、ArduinoボードとGroveセンサーを接続するのに、MKR connector carrierやNano Grove Shield、Arduino Sensor Kitのベースシールドといった製品を使うことができます。
Wireライブラリ
I2Cデバイスとの通信にArduinoが使うのがWireライブラリです。全てのボードパッケージに含まれているので、利用するのに手動インストールは不要です。
Wireライブラリの全てのAPIは、ドキュメントページを参照してください。
begin(): I2Cバスを初期化するend(): I2Cバスを閉じるrequestFrom(): ペリフェラルデバイスにバイトを要求するbeginTransmission(): 送信のキューイングを開始するendTransmission(): キューイングされたバイトを送信し、送信を終了するwrite(): ペリフェラルからコントローラー、あるいはその逆に、データを書き込むavailable(): 取得可能なバイト数を返却するread(): ペリフェラルからコントローラーに送信されたバイトを読むsetClock(): クロック周波数を変更するonReceive(): ペリフェラルが送信データを受信したときに呼び出す関数を登録するonRequest(): コントローラーがデータを要求したときに呼び出す関数を登録するsetTimeout(): コントローラーモードでの送信タイムアウトを設定するclearWireTimeoutFlag(): タイムアウトフラグをクリアするgetWireTimeoutFlag(): 最後にフラグがクリアされてから、タイムアウトが発生したか確認する
派生ライブラリ
I2Cプロトコルを利用する、基本的にはすべてのブレイクアウトモジュールを購入したとき、そのセンサーを利用するのを助けるライブラリが付属します。これらのライブラリはWireライブラリ上に構築されていて、内部で利用しています。例えば、温度を容易に取得するために、機能を追加しています。
Adafruit MCP9808モジュールを使うとき、Adafruit_MCP9808ライブラリを、IDEのライブラリマネージャからダウンロードします。これにより、Wireコードを自分で書く代わりに、正しいアドレスに温度データを要求し、センサーの温度データを読み、1行で情報を読むことができるtempsensor.readTempC()のような関数を利用できるようになります。
ライブラリのインストール方法を学ぶには、ライブラリのインストールを参照してください。
スケッチ例
この記事の残りは、I2Cを使い始めるためのスケッチ例を集めたものです。
コントローラリーダー

I2C接続されたArduinoボード
状況によっては、2つ(以上)のArduinoボードが、互いに情報を共有するように設定することが有効なことがあります。この例では、I2Cシリアル同期プロトコルを通じ、コントローラリーダー/ペリフェラルセンダー構成で、互いに通信するようにプログラムしています。これを実現するため、ArduinoのWireライブラリのいくつかの関数を使います。Arduino1(コントローラ)は、要求を出した後、固有のアドレス持つペリフェラルArduinoから、6バイトのデータを受信するようにプログラムされています。そのメッセージを受信すると、Arduinoソフトウェア(IDE)のシリアルモニタウインドウで、見ることができます。
コントローラリーダーのスケッチ
|
|
ペリフェラルセンダーのスケッチ
|
|
コントローラライター

I2C接続されたArduinoボード
状況によっては、2つ(以上)のArduinoボードが、互いに情報を共有するように設定することが有効なことがあります。この例では、I2Cシリアル同期プロトコルを通じ、コントローラライター/ペリフェラルレシーバー構成で、互いに通信するようにプログラムしています。これを実現するため、ArduinoのWireライブラリのいくつかの関数を使います。Arduino1(コントローラ)は、0.5秒ごとに、固有のアドレス持つペリフェラルArduinoに、6バイトのデータを送信するようにプログラムされています。そのメッセージを受信すると、Arduinoソフトウェア(IDE)を実行しているUSB接続したPCで開いた、ペリフェラルボードのシリアルモニタウインドウで見ることができます。
コントローラーライターのスケッチ
|
|
ペリフェラルレシーバーのスケッチ
|
|
加速度センサー

Grove IMU over I2C
このコードは、seeed arduino LSM6DS3 libraryを使い、Grove 6-Axis Accelerometer moduleから加速度データを読みます。
|
|
I2C BMP280

Qwiic BMP280モジュール
このコードは、AdafruitのBMP280ブレイクアウトモジュールからI2C経由で、温度を読み取ります。
|
|
I2C OLED

Grove OLED over I2C
このコードは、128x64 I2C Grove OLEDにArduinoロゴの一つのバージョンを表示します。
|
|
オリジナルのページ
https://docs.arduino.cc/learn/communication/wire/
最終更新日
August 2, 2026