Arduino 入門 番外編 06 【I2C通信 とは】

arduino-extra-edition-06-00 Arduino番外編
記事に広告(アフィリエイト広告)が含まれています。
スポンサーリンク

Arduino 入門
番外編 06
【I2C通信 とは】

こんにちはomoroyaです。

今回は、Arduino 入門 番外編 06 I2C通信 とはです。

arduino 入門 番外編はarduinoの基本的なことを書いていく方向性にしたいと考えています。

本日は、arduinoのI2C通信についてです。

 

その前に、arduinoの外観とピン配置を確認することをおすすめします。

 

arduino自身のことを少しづつ理解して行きましょう。

 

いやいや、arduinoを早速始めたいんだ!というかたは下記の入門編からお読みください。

 

Arduino入門編の解説にて使用しているArduinoは互換品です。

互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

正規品(Arduino UNO R3)の本体単品がほしい方はこちらとなります。

 

Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)

 

 

スポンサーリンク

Arduino I2C端子

番外編02のおさらいです。

Arduino UNO R3の外観図を下記に示します。

I2Cピンは外観図右上にあります。

I2C(SCL)、I2C(SDA)と書かれているところです。

左下のアナログ入力の4、5も利用可能です。

ただし、その場合アナログ入力として使えないため注意してください。

arduino_uno_R3-appearance

 

I2C通信について

I2C通信とは、IC間で通信することを目的に、フィリップス社が開発したシリアル通信方式です。

I2Cとは?

wikipedia I2C

I2C(アイ・スクエアド・シー、アイ・アイ・シー)はフィリップス社で開発されたシリアルバスである。低速な周辺機器をマザーボードへ接続したり、組み込みシステム、携帯電話などで使われている。

Inter-Integrated Circuit の略で、I-squared-C(アイ・スクエアド・シー)が正式な読みとされている。ただし、一般的な文字コード環境のプレーンテキスト上では上付き文字が使えないため、I2CあるいはIICと表記されることも多く、日本国内ではこれをもって「アイ・ツー・シー」と発声されたりカタカナ表記される[1]ことがある。

 

I2Cの特徴は、2本の線を繋げるだけでお互いのデータのやりとりができるようになっていることです。

・データをやり取りするために使用する「SDA」(シリアルデータ)
・IC間でのタイミングを合わせるために使用する「SCL」(シリアルクロック)

 

通信速度は以下となっています。

・標準モード 100kbps
・ファーストモード 400Kkbps
※bps:ビット・パー・セコンド 1kbps = 1000bit/s

 

実際には、電源も必要ですので「SCL」、「SDA」「電源」、「GND」の4本必要となります。

 

様々なセンサーに、I2Cの通信方式が使われています。

温度、湿度、圧力、光などなど。

例えばこちら。
※直接Amazonで見ていただけると接続などの画像もみることができます。

 

I2C通信は電子部品を制御する「マスター」と、「マスター」からの命令によって制御される「スレーブ」に分かれます。

Arduinoを使用する場合は
マスター:Arduino
スレーブ:制御する電子部品
となります。

 

また、I2C通信方式ではI2Cに対応した電子部品を複数接続することが可能です。

そのため、各電子部品には「I2Cアドレス」という番号が割り当てられています。

複数接続した場合はArduinoから電子部品に割り当てられているアドレスを指定することで対象の電子部品を制御することになります。

 

またI2C対応の電子部品には「レジスタ」と呼ばれるデータを格納しておく領域があります。

センサーなどの計測値を一時的に格納しておく領域です。

Arduinoからの命令によって、このデータをレジスタから取り出すことでセンサーの計測値を取得することが可能です。
※Arduinoからレジスタへ書き込むことも可能です。
例えば、ディスプレイに文字を表示させるといったことなどが可能です。

データの読み出し、書き込みはレジスタのアドレスを指定することで可能となります。

arduino-extra-edition-06-01

 

I2C通信について詳しく知りたい方は、下記が参考になります。

 

I2Cを使うためのWireライブラリ

ArduinoでI2C対応の電子部品を使うための方法はライブラリを使用するのが簡単です。

ライブラリ名:「Wire」ライブラリ
※標準でIDE環境に実装されています。

このライブラリを使うことで、I2C制御用の各関数が使えるようになります。

#include <Wire.h>

ArduinoのIDE環境を立ち上げたら
「スケッチ」⇒「ライブラリをインクルード」⇒「Wire」
を選択すれば使えるようになります。

 

以下、Wireライブラリの関数について列挙します。

コマンド 内容
Wire.begin(address) Wireライブラリの初期処理。
I2Cバスに対してマスタ、スレーブとして接続。パラメータ
address:7ビットのスレーブアドレス
省略時は、マスタとしてバスに接続されます。
Wire.reuestFrom(address,count) 通信対象となるI2Cデバイスのアドレスおよびデータ量を指定。
他のデバイスに対してデータを要求。
そのデータはabailable(),receive()関数を使って取得できます。パラメータ
address:データを要求するデバイスのアドレス(7ビット)
quantity:要求するデータのバイト数
stop:
true ⇒ I2Cバスを開放。
false ⇒ バスを開放しない。
Wire.beginTransmission(address) 指定したI2Cデバイスとの送信を開始。
指定したaddressのI2Cスレーブに対して送信処理を開始。
送信処理実行後、write()関数でデータをキューへ送り、endTransmission()で送信を実行。パラメータ
address:送信対象のアドレス(7ビット)
Wire.endTransmission() I2Cデバイスとの送信を終了します。
スレーブデバイスに対する送信を完了します。パラメータ
stop:
true ⇒ I2Cバスを開放
false ⇒ コネクションを維持戻り値
0:成功
1:バッファサイズを超える
2:スレーブ・アドレスを送信、NACKを受信
3:データ・バイトを送信、NACKを受信
4:その他エラー
Wire.write(value)
Wire.write(string)
Wire.write(data,length)
I2Cデバイスにデータを書き込む。パラメータ
value:送信するデータ(1byte)
string:文字列(char)
data:配列(byte)
length:送信するバイト数(byte)
戻り値:送信したバイト数(byte)
Wire.available() 読み込み可能なデータ量を取得。
read()で読み取るバイト数を返します。戻り値
読み取り可能なバイト数
Wire.read() I2Cデバイスからのデータ読み取り。
戻り値
受信データ(byte)
Wire.onReceive(handler) マスターからデータが送られてきたときに呼び出す関数を指定。
パラメータ
handler:スレーブがデータを受信したときに呼ばれる関数名
Wire.onRequest(handler) マスターから割込みした際に呼び出す関数を指定。
パラメータ
handler:呼ばれる関数名

 

Wireライブラリ関数 使用例

ここからは、Wireライブラリの使用例を示します。

 

Wireライブラリの初期処理

I2C用の制御関数を使えるようにするために、setup()関数内で下記を記述します。

void setup(){
   Wire.begin();
}

 

I2Cデバイスのレジスタへの書き込み

I2Cデバイスにデータを送る手順は以下となります。

  1. Wire.beginTransmission()関数で対象のI2Cデバイスに接続。
  2. Wire.write()関数でレジスタのアドレスを送信。
  3. Wire.write()関数で所定のデータを送信。
  4. Wire.endTransmission()関数でI2Cデバイスとの送信終了。
Wire.beginTransmission( I2Cデバイスのアドレス );
Wire.write( レジスタアドレス );
Wire.write( 送信するデータ );
Wire.endTransmission();

 

I2Cデバイスのレジスタ値の読み取り

I2Cデバイスからデータを受信する手順は下記となります。

  1. Wire.beginTransmission()関数で対象のI2Cデバイスに接続。
  2. Wire.write()関数でレジスタのアドレスを送信。
  3. Wire.endTransmission()関数でI2Cデバイスとの送信終了。
  4. Wire.requestFrom()関数でI2Cデバイスのアドレスおよびデータ量を指定。
  5. Wire.read()関数でデータの読み取り。
Wire.beginTransmission( I2Cデバイスのアドレス ); 
Wire.write( レジスタのアドレス );
Wire.endTransmission();
Wire.reuestFrom( I2Cデバイスのアドレス,byte数 );
val = Wire.read();

 

I2Cデバイスのアドレスについて

I2Cは複数の電子部品(デバイス)を接続することが可能です。

そのため、制御する電子部品のアドレスを指定する必要があります。

指定するアドレスは16進数表記で「0x03」~「0x77」までの「117個」のアドレスが利用可能です。
※0xは16進数を意味しています。0bの場合2進数を合わしています。

 

アドレスの確認は電子部品のデータシートに記載されているはずです。

I2Cデバイスのアドレスがわからない場合は、アドレスを取得するためのコードを使って調べることもできます。

github.comで提供されているコードをArduinoに書き込み「シリアルモニタ」で確認することが可能です。

 

コードの入手先は下記となります。

GitHub - asukiaaa/I2CScanner
Contribute to asukiaaa/I2CScanner development by creating an account on GitHub.…

arduino-extra-edition-06-02

 

使用手順は下記となります。

  1. 上記から「I2CScanner-master.zip」をダウンロードします。
  2. ダウンロードした「I2CScanner-master.zip」を展開(解凍)します。
  3. 展開(解凍)したフォルダ内にある「I2CScanner.ino」をIDEで開きます
  4. Arduinoにコードを転送します。
  5. 「シリアルモニタ」を開きます。
  6. シリアルモニタの右下の通信速度を「115200bps」に設定します。
  7. I2Cデバイスのアドレスが表示されるようになっています。

 

まとめ

今回は、I2C通信について簡単に説明しました。

演習では実際にI2C通信に対応した電子部品を使って制御してみたいと考えます。

 

Arduino 入門のLesson編にてI2C対応の電子部品を使った実践の解説を記事にする予定です。

Lesson編の記事を更新しだい、ここにもリンクを貼りますのでしばらくお待ちください。

 

次回の番外編 07は【SPI通信】です。

Arduino 入門 番外編 07 【SPI通信 とは】
今回は、「Arduino 入門 番外編 07 SPI通信 とは」です。arduino 入門 番外編はarduino自身の基本的な内容を記事にする予定です。今回は、arduinoの「SPI通信」について解説していきます。…

 

最後に

疑問点、質問などありましたら気軽にコメントください。

この電子部品の解説をしてほしい!などなどなんでもOKです。

リンク切れ、間違いなどあればコメントいただけると助かります。

 

Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。

 

Arduino入門編Arduino入門編2で使用しているUNOはAmazonにて購入可能です。

Arduino入門編では互換品を使用。

Arduinoはオープンソース。

複製して販売するのもライセンス的に問題なし。

 

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

学習用、遊び用、お試し用には安価な互換品がおすすめです。

 

上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。

 

Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)

 

Amazonでお得に買う方法

Amazonでお得に購入するならAmazon MastercardAmazonギフト券がおすすめです。

時期により異なりますが、様々なキャンペーンを実施しています。

\Amazonギフト券/
Amazonギフトカード キャンペーン

Amazon Mastercard お申込み
Amazon Mastercard 申し込み 

 

いずれの場合もプライム会員である方がお得!!

\Amazon Prime 30日間の無料会員を試す/
無料会員登録 

 

 

コメント

  1. オダジマ ジョー より:

    こんにちは
    複数のI2Cデバイスを接続した場合、最後のデバイスで終端抵抗のプルアップが必要だと思うのですが?

    • omoroya omoroya より:

      コメントありがとうございます。
      通常、I2C通信する場合はプルアップ抵抗が必要です。
      Arduino使用時はWireライブラリにて内部でプルアップが行われるため、外部にプルアップ抵抗を設ける必要がありません。(建前上)
      動作が不安定になる場合は適切なプルアップ抵抗になるように調整が必要です。
      というか、外付けで調整した方が良いと思います。

      下記で内部プルアップを止めて外付けのみでの調整も可能と思います。
      Wire.begin();
      pinMode(SDA, INPUT);
      pinMode(SCL, INPUT);

      フォーラムで議論されていますのでご参考までに。
      https://forum.arduino.cc/index.php?topic=369003.0

タイトルとURLをコピーしました