温度センサADT7410の2回目です。前回はI2C通信の簡単な概要とADT7410モジュールをRaspbery Piに接続してアドレスの確認まで行いました。今回はArduinoでADT7410を使ってみます。Raspbery Piは次回で使います。
ADT7410は以下を使っています。
ADT7410使用 高精度・高分解能 I2C・16Bit 温度センサモジュール
仕様書は今現在で上記の製品ページのマニュアルPDFのリンクと仕様半導体資料のリンクから参照出来ます。直接のリンクは以下です。
ADT7410モジュールマニュアル
使用半導体資料(データシート)
ArduinoはArduino UNOでArduino IDEはVer1.6.5です。また開発用のPCはWindows8.1Proです。プログラミングで利用するi2CのWireライブラリのリファレンスは以下です。
Arduino Wire Library
日本語訳もいろいろとあるようです。例えば以下にあります。Wireの項に今回のライブラリのリファレンスがあります。
Arduino 日本語リファレンス
ADT7410とArduinoとの接続
リファレンスにもありますが、Arduino UNOのSDA(データライン)はA4ピン、SCL(クロックライン)はA5ピンです。これをADT7410のSDAとSCLへ接続して、VDDとGNDを接続します。プルアップ抵抗はADT7410モジュール側で(下手な)はんだ付けをして有効にしています。(※但しですが、今回のWireライブラリを利用する場合はわざわざはんだ付けをしなくても大丈夫なようです。というのはArduino側で有効になるからです。以下等を参照して下さい。いずれにしてもi2Cの場合はラインのどこか一か所でプルアップ抵抗が必要です。)
ArduinoでI2C接続するときにSCL,SDAにプルアップ抵抗は必要か?
ATD7410モジュールの仕様
接続が完了したとするとArduinoから温度データを取得することが出来ますが、その前にADT7410モジュールのデータシートを確認します。詳細は実際に見て頂ければと思いますが、要点と思われる点を抜粋します。
13/16ビットADCを内蔵していて、分解能が0.0625°C(13ビット設定時)と0.0078°C(16ビット設定時)となっています。ここではデフォルトの13ビットを使います。(16ビットへの変更は設定レジスタで行います。)また、i2Cバスアドレスを選択することが出来て、デフォルトが0x48で、J3・J4の各ジャンパ・パターンをはんだ付けすることにより変更出来るようです。ここでは前回確認しましたが、デフォルトの0x48です。(※設定レジスタはここでは使いませんが今現在使用半導体資料(データシート)の13ページあたりから説明があります。)
基本的な温度の計算方法(13ビット設定時)は以下です。
プラスの温度の場合:ADCの値/16 (1/16 = 分解能の0.0625)
マイナスの温度の場合:(ADCの値-8192)/16 (8192 = 2の13乗)
プラスかマイナスかは13ビット(MSB)で判定します。0℃を基準として、零下が”1″で表現されます。(2進数で負の数値を表現する際に使用される2の補数表現です。)
Arduinoからの温度データ取得
それでは、Arduinoから温度データを取得します。最初に書いた通り、Wireライブラリを利用します。ここでは以下の関数を使います。(※いちいち細かいことでどちらでもいいと思いますが、C++でオブジェクト指向ということではメソッドという表現かと思いますが、今現在の英語のリファレンスにFunctionsと書いてあるので、関数という表現を使います。)
begin() ライブラリの初期化とi2Cのスタかスレブでバスに参加する
requestFrom() マスタからスレブへデータの取得要求
read() スレブから1バイト読み込む
以下のようなスケッチ(プログラム)を用意しました。
#include <Wire.h> int adt7410I2CAddress = 0x48; // 初期化 void setup(void) { Serial.begin(19200); Wire.begin(); //マスタで初期化 } // メインループ void loop(void) { uint16_t uiVal; //2バイト(16ビット)の領域 float fVal; int iVal; //符号ありの整数の値を保持 Wire.requestFrom(adt7410I2CAddress, 2); //2バイト要求 uiVal = (uint16_t)Wire.read() << 8; // 1バイト読み出しで上位にシフト uiVal |= Wire.read(); // 1バイト読み出して下位にセット uiVal >>= 3; // シフトで13bit化 //uiVal = 0x1fff; //確認テスト用 if(uiVal & 0x1000) { // 13ビットで符号判定 iVal = uiVal - 0x2000; // マイナスの時 (10進数で8192) } else{ iVal = uiVal; //プラスの時 } fVal = (float)iVal / 16.0; // 温度換算(摂氏) Serial.println(fVal, 4); // シリアル送信 delay(5000); //5秒待つ }
これを実行すると以下のような結果になりました。途中で指でセンサを押さえました。暑いですが、6月下旬で室内でだいたいこれぐらいだろうというところです。
それではマイナスの時はどうかということですが、マイナスになる温度環境を用意すればいいのかもしれないですが、さすがに手間がかかるので、データシートに書いてある値の例をスケッチ上で「確認テスト用」となっているところを有効にしてその値を代入して結果を確認します。
0x1FFF → -0.0625℃
0x1E70 → -25℃
0x1CE0 → -50℃
上記の値がそれぞれ確認出来ました。これでプラス、マイナスの判定も問題ないだろうということです。
今回はここまでです。次回はRaspbery Piで使ってみます。