I2C通信の使い方をサンプルプログラムで詳しく紹介(Arduinoコマンド)

I2C通信の使い方 ArduinoコマンドArduinoコマンド

Arduinoコマンドを使用したI2C通信の使い方を詳しく紹介します。

例として温度と湿度の測定できるセンサー(ENV Ⅲ)を使用して、ライブラリを使用せずにI2C通信でデータを取得して液晶表示器付きのマイコンボード「M5StickC Plus(M5Stack社)」に表示します。

I2C通信の使い方の紹介のため、サンプルプログラムではライブラリは使用しませんが最後にライブラリを使用したプログラムについても紹介しています。

「M5StickC Plus」については以下のリンクで詳しく紹介しています。

M5StickC Plusの使い方、初期設定、サンプルプログラム、M5StickCとの違い等を詳しく紹介
M5StickC PlusをArduino IDEやPlatformIOで使うための初期設定やサンプルプログラムでの動作確認の方法です。ビジュアルプログラミングのUiFlowの初期設定についても紹介します。

他の「Arduinoコマンド」の使い方については以下のリンクで詳しく紹介しています。

Arduinoコマンドの使い方一覧
Arduinoコマンドを使用したプログラミングの記事一覧です。まずはコピペで書き込み、動作確認しながら少しづつ理解を深めましょう♪C言語の理解にもつながるのでお勧めです!
スポンサーリンク

1.使用するセンサ(ENV Ⅲ)について

今回使用するセンサは「温度、湿度、気圧」のデータを測定することができる「M5Stack社」製、温湿度気圧センサユニット 「ENV Ⅲ」です。(下写真)
「Groveコネクタ」付きで「M5StickC Plus」とは付属のケーブルで接続するだけで使用できます。

ENV3でI2C通信の使い方
ENV3でI2C通信の使い方
ENV3でI2C通信の使い方
ENV3でI2C通信の使い方

内部に温度と湿度を測定するセンサ「SHT30」と、気圧を測定するセンサ「QMP6988」を内蔵しており、それぞれのセンサからI2C通信で測定データを取得することができます。

今回はI2C通信の確認のため、サンプルプログラムではライブラリを使用せずに温度と湿度のデータのみ取得する方法を紹介します。


センサ本体(デバイス)内の温湿度センサ「SHT30」のI2C通信アドレスは「0x44」です。

測定した温度と湿度のデータは以下表のような条件でレジスタアドレスを指定して受信します。
サンプルプログラムではこの中から赤文字のように指定してデータを取得しています。

ENV Ⅲ I2C通信レジスタアドレス
本体デバイスのI2C通信アドレスは比較的簡単にわかりますが、データ送受信用のレジスタアドレスは各デバイスのデータシートで確認する必要があります。
センサから送られてくるデータは以下のように連続した6byteのデータになります。
・[温度MSB],[温度LSB],[温度CRC],
 [湿度MSB],[湿度LSB],[湿度CRC]
※「MSB」は測定データの上位8bit、「LSB」は下位8bit、「CRC」はエラーチェック用データです。
 クロックストレッチとはスレーブ側が受信データを処理している間にマスタ側の送信を停止させる制御です。これでスレーブ側がデータを確実に処理してから受信することができます。
スポンサーリンク

2.I2C通信とは

I2C通信とは「アイスクエアドシー」と読み、通称「アイ・ツー・シー」と呼ばれます。
フィリップス社によって開発されたシリアル通信方法で、同じ基板内などの近距離デバイス同士の通信を目的に開発されたものです。

通信速度はスタンダードモードで最大100kbps、ファストモードで最大400kbps、さらに高速な通信モードもありますがArduinoコマンドを使用する場合は標準でスタンダードモードとなります。

通信はマスターとスレーブ間で行われ、スレーブとしてデバイスアドレスが違うものであれば1つのマスターからの指示で複数のスレーブデバイスを制御することができます。

通信には以下の2本の信号線を使用します。
・SDA:データ送受信用
・SCL:クロック(通信タイミング)信号用
マスター側から送信したクロック信号のタイミングでスレーブ側と通信するため、同期通信と呼ばれます。(通信デバイス同士で0Vは共通にしておく必要があります。)

3.プログラム例(ライブラリ未使用)の書き込み

サンプルプログラムは以下になります。「コピペ」して書き込んでください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。

#include <M5StickCPlus.h> // ヘッダーファイル

#define SHT3X_ADDR 0x44 // SHT3X(温度、湿度センサ)I2C通信アドレス
// 変数宣言
unsigned int data[6]; // SHT3X 温度、湿度データ格納用
float tmp = 0.0;      // 温度換算データ格納用
float hum = 0.0;      // 湿度換算データ格納用
// 初期設定 ***************************************************************************
void setup() {
  M5.begin();         // 本体初期化
  Wire.begin(32, 33); // I2C通信端子指定(SDA, SCL)
  // 液晶表示初期設定
  M5.Lcd.fillScreen(BLACK); // 背景色
  M5.Lcd.setRotation(3);    // 画面向き設定(USB位置基準 0:下/ 1:右/ 2:上/ 3:左)
  M5.Lcd.setTextFont(4);    // フォント 1(8px), 2(16px), 4(26px)
                                    // 6(36px数字-.:apm), 7(7セグ-.:), 8(75px数字-.:)
  M5.Lcd.setTextColor(WHITE, BLACK);                       // (文字色, 背景)
  M5.Lcd.drawCentreString("ENVIII Unit Test", 120, 7, 4);  // (文字表示(中央揃え), x, y, フォント)
  M5.Lcd.drawFastHLine(0, 33, 240, WHITE);                 // 水平線(x, y, 長さ)
}
// メイン *****************************************************************************
void loop() {
  // I2C通信設定(温度、湿度それぞれ MSB,LSB,CRCの順で計6byteの受信設定)
  Wire.beginTransmission(SHT3X_ADDR); // I2C通信開始
  Wire.write(0x2C);                   // MSB、クロックストレッチ有り指定 書き込み
  Wire.write(0x06);                   // LSB繰り返し精度指定(高)書き込み
  Wire.endTransmission(true);         // 書き込み完了
  // データ受信(6byte)
  Wire.requestFrom(SHT3X_ADDR, 6);    // 受信データリクエスト(6byte)
  for (int i = 0; i < 6; i++) {       // 6byte分繰り返し
      data[i] = Wire.read();          // データ受信、格納
  }
  // 受信データを表示データに換算
  tmp = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45; // 温度(℃)
  hum = ((((data[3] * 256.0) + data[4]) * 100) / 65535.0);      // 湿度(%)
  // 液晶表示
  M5.lcd.setCursor(5, 50);                  // 表示座標指定
  M5.Lcd.printf("Temp : %2.1f'C  ", tmp);   // 温度表示
  M5.lcd.setCursor(5, 80);                  // 表示座標指定
  M5.Lcd.printf("Humi : %2.0f%%  ", hum);  // 湿度表示
  delay(1000);  // 遅延時間
}

4.プログラム例の動作確認

「M5StackC Plus」に温湿度気圧センサユニット 「ENV Ⅲ」を接続して、サンプルプログラムを書き込んで実行したものは下画像のようになります。

ENV3でI2C通信の使い方

温度と湿度だけであれば数行のプログラムで表示することができます。

今回はI2C通信の使い方の確認のため、気圧の表示は省略しています。
気圧も表示させたい場合は「6.ライブラリ使用プログラムの紹介」を確認してみてください。

5.I2C通信を行うArduinoコマンドについて

サンプルプログラムでは初期設定や液晶表示のプログラムが半分ほどありますが、I2C通信を行うための初期設定とデータの送受信方法は以下の数行だけです。

・初期設定

I2C通信の初期設定は通信端子番号を指定して以下のように行います。

// 初期設定
void setup() {
  Wire.begin(32, 33); // I2C通信端子指定(SDA, SCL)
}

・データの受信(読み取り)方法

I2C通信でのデータ受信は以下のような手順で行います。

// I2C通信データ受信(読み取り)
Wire.beginTransmission(I2C_ADDR); // デバイスアドレスを指定して通信開始
Wire.write(REG_ADDR1);            // 読み取りレジスタアドレス指定して書き込み
Wire.write(REG_ADDR2);            // 読み取りレジスタが複数ある時は続けてアドレス指定して書き込み
Wire.endTransmission(true);       // 書き込み完了

// データ受信(読み取り)
Wire.requestFrom(I2C_ADDR, byte); // 受信データリクエスト(I2Cアドレスと受信バイト数指定)
data = Wire.read();               // データを受信し変数(複数バイトは配列)に格納

①「Wire.beginTransmission」でデータを受信したい対象デバイスのアドレス(I2C_ADDR)を指定して通信を開始します。
②「Wire.write」で対象データのレジスタアドレス(REG_ADDR)を指定(書き込み)します。
③レジスタの指定が完了したら「Wire.endTransmission(true)」で一度通信を終了します。
④スレーブ側から指定したレジスタのデータが送信されてくるので、データを受信するために再度「Wire.requestFrom」で対象デバイスのアドレス(I2C_ADDR)と受信バイト数(byte)を数値で指定して通信を開始します。
⑤送信されてきたデータを「Wire.read()」で受信(読み取り)し変数に格納して使用します。
 データが複数の場合は「for文」等で配列に格納して使用します。


・データの送信(書き込み)方法

I2C通信でのデータ送信(書き込み)は受信(読み込み)の時のレジスタアドレスの指定(書き込み)と同様の方法で以下のような手順で行います。

// I2C通信データ送信(書き込み)※受信の時と同じ手順
Wire.beginTransmission(I2C_ADDR); // デバイスアドレスを指定して通信開始
Wire.write(REG_ADDR);             // 書き込みレジスタアドレス指定して書き込み
Wire.write(data1);                // データ書き込み(複数の場合はfor文等で連続指定)
Wire.endTransmission(true);       // 書き込み完了

①受信の時と同様に「Wire.beginTransmission」でデータを送信したい対象デバイスのアドレス(I2C_ADDR)を指定して通信を開始します。
②先に「Wire.write」で書き込み先のレジスタアドレス(REG_ADDR)を指定して書き込みます。
③続けて「Wire.write」で送信(書き込み)したいデータ(data1)を指定して書き込みます。
 データが複数の場合は「for文」等で「Wire.write」を連続で実行して配列のデータを送信します。
④全てのデータを送信したら「Wire.endTransmission(true)」で送信(書き込み)完了です。

6.ライブラリ使用プログラムの紹介

ライブラリを使用した温湿度気圧センサ「ENV Ⅲ」の使用方法も紹介しておきます。

「ENV Ⅲ」を制御するためのライブラリは「M5Unit-ENV」です。
「ArduinoIDE」や「PlatformIO」のライブラリで検索してインストールしてください。


プログラムは以下の「Git Hub」のリンク先で公開されています。

M5Unit-ENV/Unit_ENVIII_M5StickCPlus.ino at master · m5stack/M5Unit-ENV
Contains M5Stack-UNIT ENV series related case programs.ENV is an environmental sensor with integrated SHT30 and QMP6988 internally to detect temperature, humidi...

ライブラリをインストールして「Git Hub」のプログラムを書き込んだものは下画像のようになります。

ENV3でI2C通信、ライブラリの使い方

温度と湿度だけでなく気圧も表示されます。
表示の文字はすごく小さいですw 測定データ部を「M5.Lcd.setTextFont(4);」で指定して表示させると良い感じになります。

気圧の単位はパスカル[Pa]が使用されています。
天気予報でよく聞かれるヘクトパスカルは[hPa]で、「ヘクト」は100倍の意味なので上写真の場合は「約1018hPa」となります。
平均気圧を検索したら「1013hPa」と出てきたので、測定した日は気温も含め穏やかな日だったことがわかりますね。

「ArduinoIDE」については以下のリンクで詳しく紹介しています。

M5StackシリーズのためのArduino IDEのインストール方法と初期設定、使い方紹介
M5Stackシリーズ(StickC、ATOM等)のためのArduino IDEのインストール方法から初期設定、スケッチ例の書き込み、コピペでの使い方まで詳しく紹介します。インストールはArduinoでも同じです。

「PlatformIO」については以下のリンクで詳しく紹介しています。

プログラミング
Visual Studio Code (VSCode)のインストールと日本語化から基本設定まで紹介
プログラムを書くために必要なエディタのインストールをします。他のプログラミングにも便利な定番エディタです。
pythonのインストール
pythonのダウンロードからインストール方法の紹介
次にインストールするPlatformIOをインストールするために必要なプログラム言語のpythonをインストールします。
PlatformIOでプログラミング
PlatformIO のダウンロードからインストールの紹介。Arduino IDEより速い!高性能!
プログラミングするためのIDE(統合開発環境)のインストールです。
ATOM LITE本体
ATOM LITE の初期設定。プログラミング初心者におすすめ
ATOM LITEにプログラムを書き込むための初期設定とプログラミングの書込みから動作確認まで行います。

7.まとめ

「Arduinoコマンド」を使用したI2C通信の使用方法について紹介しました。

I2C通信は長距離の通信には向きませんが短距離通信では最低でも100kbpsでの通信が可能で、通信に使用する配線も「データ送受信用(SDA)」と「クロック(通信タイミング)信号用(SCL)」の2本だけです。(通信デバイス同士で0Vは共通にしておく必要があります。)

対応デバイスは液晶表示器や各種センサ、モータードライバ等たくさんあり、スレーブとしてデバイスアドレスが違うものであれば1つのマスターで複数のデバイスを制御することができます。

I2C通信を使用する時には専用のライブラリを使うと簡単に使用できますが、プログラム容量が大きくなりがちです。
センサのデータ取得だけであれば数行のプログラムでできることも多いので、状況に応じてライブラリを使用しない方法も検討してみましょう。

Arduinoコマンドの使い方一覧
Arduinoコマンドを使用したプログラミングの記事一覧です。まずはコピペで書き込み、動作確認しながら少しづつ理解を深めましょう♪C言語の理解にもつながるのでお勧めです!

コメント

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