※当サイトではアフィリエイト広告を利用しています

電子工作

I2Cを使ってArduino2台で複数データの送受信を行う方法

  • Arduino2台でデータの送受信を行いたいけれども、どうすればよいのだろう?
  • CAN通信を使用すれば送受信ができるらしいけど、外部モジュールを買わないといけないし、プログラムも複雑そう
  • I2C通信なら追加で外部モジュールを買わなくても送受信ができるとのことなので、I2C通信のやり方を教えてほしい!

 今回はそんな疑問にお答えします。

 以前Arduino2台を使用したCAN通信でのデータ送受信方法を解説しましたが、CAN通信はまずMCP2515という外部モジュールの購入が必要でです。配線も6本近く繋ぐ必要があり、何よりもプログラムがそれなりに複雑なので、初心者にはいささかハードルの高い代物であります。

 その点I2C通信であれば外部モジュールの購入も不要であり、配線も通信線2本+GND1本の合計3本の接続で済んでしまうというシンプル仕様。CANに比べればデータ送受信の速度が遅いという欠点がありますが、初心者が行う電子工作ではそこまで大容量のデータを高速で送受信する必要はないかと思うので、I2Cで十分です。

 今回はサンプルプログラムを掲載しつつ、I2C通信について解説していきます。

関連記事
arduino-can-multidata_thumbnail
CANを使ってArduino2台で複数データの送受信を行う方法

Arduinoを使用したCAN通信で複数データの送受信はどうやって行うのだろう? 一度に複数のデータが送られてきたときに、受信側はどうやって受け取る? 単発データならまだしも、複数データだと取りこぼし ...

続きを見る

I2C通信の仕様について

  • データを送信するマスターと、受信するスレーブに分かれる
  • 複数機器を同時に接続することができるので、スレーブは "スレーブアドレス" を設定する必要がある
  • 設定できるスレーブアドレスの範囲は0x08~0x77
  • マスターはスレーブアドレスを指定してデータの送信を行う
  • 同じスレーブの機器が複数存在するとデータの送受信が正しく行えない
  • 一度に送受信できるデータは32byteまで
  • CANとは異なりIDの設定は必須ではない
  • intやlongのような2byte以上のデータも、1byte毎に分解して送信される

 

今回送信するデータ

ID(16進数) データ型 変数名
0x00 int intData 1234
0x01 float floatData 56.78
0x02 char charData 'A'

 前述の通り、I2C通信はCANとは異なりIDの設定が必須ではないため、こちら側で独自に設定をする必要があります。

 IDがないとどんなデータ型の値が送られてきたか分からないので、今回のサンプルプログラムでは先頭1byteをIDとして使用することにします。

 

配線方法

送信側(マスター) 受信側(スレーブ)
SDA SDA
SCL SCL
GND GND

 

I2C通信で使用する関数一覧(流し読みしてください)

1. 初期化関連

関数 用途 説明
Wire.begin() マスター初期化 Arduino をマスターとして I2C 通信を開始する
Wire.begin(address) スレーブ初期化 Arduino をスレーブとして初期化し、指定したアドレスで待ち受ける

2. マスター送信関連

関数 用途 説明
Wire.beginTransmission(address) 送信開始 指定したスレーブアドレスへの送信を開始する
Wire.write(value) データ送信 1バイトまたはバイト配列を送信する(Wire.write((byte*)&var, sizeof(var)) で複数バイト送信可能)
Wire.endTransmission() 送信終了 データ送信を終了し、スレーブに転送する(戻り値は送信結果コード)

3. マスター受信関連

関数 用途 説明
Wire.requestFrom(address, quantity) データ要求 指定スレーブから指定バイト数のデータを受信する
Wire.read() 受信データ読み出し 受信バッファから1バイトを読み出す
Wire.readBytes(buffer, length) バイト配列で受信 受信バッファから複数バイトをまとめて読み出す

4. スレーブ受信・送信関連

関数 用途 説明
Wire.onReceive(function) 受信イベント登録 スレーブとしてデータを受信したときに呼び出す関数を登録
Wire.onRequest(function) リクエストイベント登録 スレーブとしてマスターからデータ要求があったときに呼び出す関数を登録

5. その他ユーティリティ

関数 用途 説明
Wire.available() 受信データ数確認 受信バッファに残っているバイト数を取得
Wire.setClock(frequency) 通信速度設定 I2Cクロック周波数を設定(例:Wire.setClock(400000) で 400kHz)

 

送信側コード

 

受信側コード

 

 I2Cに関しては特に難しいロジックもなく、CANに比べればシンプルなコードになっていますね。

 もし電子工作で簡易的にデータの送受信が必要になった場合、ぜひI2C通信を使ってみてください!



-電子工作
-

© 2025 名古屋とエンジニアリング