今回は、M5Stackを使って気温計を作ったので、作り方を紹介しちゃいます。
温度センサにはADT7410というものを使いました。この温度センサは、I2C通信出来るので、M5Stackとの接続が非常にシンプルでおすすめです。その上、±0.4℃の高精度!
気温表示は、M5Stackディスプレイに出力するシンプルなものです。ゆくゆくはPCやスマホから見れるようにする予定です。
では作っていきましょう!
こんな人におすすめ!
- M5Stackで気温計を作りたい人
- I2C通信について知りたい人
I2C通信とは
I2C通信について説明します。知ってる人は読み飛ばしちゃって結構です。
マスタ・スレーブ方式
I2Cが採用するマスタ・スレーブ方式とは、管理・制御する側のマスターと制御される側のスレーブ間でデータ通信する方式です。
マスターは、クロックを出力し、マスター/スレーブはこのクロック周波数に合わせてデータを送受信します。
今回の場合、マスターはM5Stack、スレーブはADT7410になりますね。
スレーブデバイスにはアドレスがあり、マスターがそれぞれのアドレスを指定することで、1対複数のデータ通信が可能です。
必要な接続線は2本
通信に必要な接続線はSDA、SCLの2本のみです。
SDAはシリアル・データラインで信号送受信用の線です。SCLはシリアル・クロックラインでクロック用の線です。
各信号線はプルアップ抵抗が必要となります。
温度センサ ADT7410の使い方
電子工作する上でセンサの知識は必須ですね。仕様と通信方法を見ていきましょう。
仕様
ADT7410の測定温度範囲、温度精度、温度分解能、端子は下表のとおりです。
測定温度範囲 | -55℃ ~ +150℃ |
温度精度 | ±0.4℃ @-40℃~+105℃ (3.0V) |
温度分解能 | 0.0078℃ (16bit使用時) 0.0625℃ (13bit使用時) |
端子 | VDD: 電源 GND SDA SCL |
温度分解能は設定モードによって異なり、16bitモード、13bitモードが使用できます。13bitモードだと温度分解能が温度精度より大きいです。精度を求めるのであれば、16bitモードに設定した方が良いでしょう。今回は気温計でそこまで精度は求めていないので、13bitモードを使用します。
通信方法
ADT7410のアドレスは0x48です。
マスターからADT7410へデータ返信を要求すると、ADT7410は2byteの値を返します。
13bitモードの各bit定義と温度換算式は下記表の通りとなります。
Bit 15 | Bit 14-3 | Bit 2-0 | 温度換算式 |
温度符号 0: 正 1: 負 | Data | ー | 温度が正のとき Data / 16 温度が負のとき (Data – 8192) / 16 |
気温計の作り方
では、M5Stack、ADT7410を使った気温計の作り方を紹介していきます。
準備したもの
- M5Stack Basic
- 温度センサ ADT7410
- ジャンパワイヤ オス-メス
M5StackはGrayやGoでも問題ないですよ。
M5StackとADT7410の配線
M5StackとADT7410の接続は下表のとおりです。M5Stackの21,22ピンがI2Cに対応している端子になります。
M5Stack | ADT7410 |
---|---|
21 | SDA |
22 | SCL |
3V3 | VDD |
G | GND |
温度計測プログラム
M5Stackのディスプレイに気温を表示するプログラムはこちらになります。
#include <M5Stack.h>
#include <Wire.h>
int address = 0x48; // ADT7410温度センサのアドレス
void setup() {
M5.begin();
M5.Lcd.setTextSize(3);
// 内部プルアップ抵抗有効化
pinMode(21, INPUT_PULLUP);
pinMode(22, INPUT_PULLUP);
Serial.begin(9600); // 通信速度を9600bpsに設定
Wire.begin(); // I2Cバスにマスタとして接続
}
void loop() {
uint16_t data;
float temp;
Wire.requestFrom(address, 2); // ADT7410に2byteのデータを要求
data = Wire.read() << 8; // 1byte受信し、1byte左シフト
data |= Wire.read(); // 1byte受信し、前回値に加算
data >>= 3; // 3bit右シフト
if(data & 0x1000){ // bit 12が1のとき
temp = (float)(data-8192) / 16.0; // 負の温度換算
}
else{
temp = (float)data / 16.0; // 正の温度換算
}
M5.Lcd.setCursor(20, 80);
M5.Lcd.print("Temp: ");
M5.Lcd.print(temp);
M5.Lcd.print("'C");
delay(1000);
}
それぞれの処理について解説します。
内部プルアップ抵抗の使用
SDA,SCLはプルアップ抵抗が必要のため、M5Stackの内部プルアップ抵抗を有効化します。
pinMode(21, INPUT_PULLUP);
pinMode(22, INPUT_PULLUP);
通信速度の設定
I2C通信速度を設定します。
Serial.begin(9600);
単位はbpsで、設定値は300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200から選択します。
I2Cバスに接続
I2Cバスに接続します。引数に何も指定しないとマスタとして接続になります。スレーブとして接続する場合は、引数にアドレスを指定します。
Wire.begin();
ADT7410から温度データ受信
温度データを受信するために、Wire.requestFrom()、Wire.read()を使います。
Wire.requestFrom()は、第1引数のアドレスに、第2引数で指定したbyte数分のデータを要求します。Wire.read()で1byte分受信します。
Wire.requestFrom(address, 2); // ADT7410に2byteのデータを要求
data = Wire.read() << 8; // 1byte分読み取りし、1byte左シフト
data |= Wire.read(); // 1byte分読み取りし、前回値に加算
data >>= 3; // 3bit右シフト
この処理は何をしているかというと下図を参照ください。
ADT7410からの受信データは、Bit 15-3が温度データです。まず受信データを1byte読み出し、dataに格納すると、dataの下位バイトが受信データの上位バイトになります。そのため、dataを1byte左にシフトさせます。もう一度受信データを1byte読み出し、dataの下位バイトに格納します。dataのBit15-3が温度データとなるため、3bit右にシフトさせます。これによってdata = 温度データとすることが出来ます。
温度換算
温度データをdataに格納出来ましたので温度換算するだけです。dataのBit 12が温度符号になっていますので、Bit 12が1のときは、負の温度換算式を用います。Bit 12が0のときは、正の温度換算式を用います。
if(data & 0x1000){ // bit 12が1のとき
temp = (float)(data-8192) / 16.0; // 負の温度換算
}
else{
temp = (float)data / 16.0; // 正の温度換算
}
出来上がった気温計で温度計測
こんな感じで表示されます。
まとめ
M5StackとADT7410温度センサを使った気温計の作り方を紹介しました。
作る過程でI2C通信も一緒に学べるので是非挑戦してみて下さい。
今回、気温表示はM5Stackのディスプレイ表示でしたが、今後、PCやスマホから見れるようにする予定です。
最後までお読み頂きありがとうございました。
私はスイッチサイエンスさん(Amazon)でM5Stackを買いました。
書籍もKindleストアで「みんなのM5 Stack入門」を購入し、読みながら勉強してまーす。