Arduinoコマンドを使用したI2C通信の使い方を詳しく紹介します。
例として温度と湿度の測定できるセンサー(ENV Ⅲ)を使用して、ライブラリを使用せずにI2C通信でデータを取得して液晶表示器付きのマイコンボード「M5StickC Plus(M5Stack社)」に表示します。
「M5StickC Plus」については以下のリンクで詳しく紹介しています。
「M5StickC Plus2」で「ENV IV」をI2C通信で使用する方法は以下のリンクで詳しく紹介しています。
他の「Arduinoコマンド」の使い方については以下のリンクで詳しく紹介しています。
1.使用するセンサ(ENV Ⅲ)について
2.I2C通信とは
3.プログラム例(ライブラリ未使用)の書き込み
4.プログラム例の動作確認
5.I2C通信を行うArduinoコマンドについて
・初期設定
・データの受信(読み取り)方法
・データの送信(書き込み)方法
6.ライブラリ使用プログラムの紹介
7.まとめ
1.使用するセンサ(ENV Ⅲ)について
今回使用するセンサは「温度、湿度、気圧」のデータを測定することができる「M5Stack社」製、温湿度気圧センサユニット 「ENV Ⅲ」です。(下写真)
「Groveコネクタ」付きで「M5StickC Plus」とは付属のケーブルで接続するだけで使用できます。
内部に温度と湿度を測定するセンサ「SHT30」と、気圧を測定するセンサ「QMP6988」を内蔵しており、それぞれのセンサからI2C通信で測定データを取得することができます。
今回はI2C通信の確認のため、サンプルプログラムではライブラリを使用せずに温度と湿度のデータのみ取得する方法を紹介します。
センサ本体(デバイス)内の温湿度センサ「SHT30」のI2C通信アドレスは「0x44」です。
測定した温度と湿度のデータは以下表のような条件でレジスタアドレスを指定して受信します。
サンプルプログラムではこの中から赤文字のように指定してデータを取得しています。
2.I2C通信とは
I2C通信とは「アイスクエアドシー」と読み、通称「アイ・ツー・シー」と呼ばれます。
フィリップス社によって開発されたシリアル通信方法で、同じ基板内などの近距離デバイス同士の通信を目的に開発されたものです。
通信速度はスタンダードモードで最大100kbps、ファストモードで最大400kbps、さらに高速な通信モードもありますがArduinoコマンドを使用する場合は標準でスタンダードモードとなります。
通信はマスターとスレーブ間で行われ、スレーブとしてデバイスアドレスが違うものであれば1つのマスターからの指示で複数のスレーブデバイスを制御することができます。
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 Ⅲ」を接続して、サンプルプログラムを書き込んで実行したものは下画像のようになります。
温度と湿度だけであれば数行のプログラムで表示することができます。
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); // 書き込み完了
delay(100) // データ受信待機(時間はデータシートで確認)
// データ受信(読み取り)
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」のリンク先で公開されています。
ライブラリをインストールして「Git Hub」のプログラムを書き込んだものは下画像のようになります。
温度と湿度だけでなく気圧も表示されます。
表示の文字はすごく小さいですw 測定データ部を「M5.Lcd.setTextFont(4);」で指定して表示させると良い感じになります。
「ArduinoIDE」については以下のリンクで詳しく紹介しています。
「PlatformIO」については以下のリンクで詳しく紹介しています。
7.まとめ
「Arduinoコマンド」を使用したI2C通信の使用方法について紹介しました。
I2C通信は長距離の通信には向きませんが短距離通信では最低でも100kbpsでの通信が可能で、通信に使用する配線も「データ送受信用(SDA)」と「クロック(通信タイミング)信号用(SCL)」の2本だけです。(通信デバイス同士で0Vは共通にしておく必要があります。)
対応デバイスは液晶表示器や各種センサ、モータードライバ等たくさんあり、スレーブとしてデバイスアドレスが違うものであれば1つのマスターで複数のデバイスを制御することができます。
I2C通信を使用する時には専用のライブラリを使うと簡単に使用できますが、プログラム容量が大きくなりがちです。
センサのデータ取得だけであれば数行のプログラムでできることも多いので、状況に応じてライブラリを使用しない方法も検討してみましょう。
コメント