マスタリングWireライブラリ その7 温度センサADT7410 リピーテッド・スタート・コンディション
アナログ・デバイセズの温度センサADT7410は、16ビットの分解能があります。デフォルトは13ビットで、コンフィギュレーション・レジスタの内容を16ビット対応に変更し、データを読み出します。本デバイスでは、リピーテッド・スタート・コンディションが要求されるタイミングがあります。
●ADT7410のおもなスペック
動作電圧は3.3V、5Vのどちらでもかまいません。データシートによると、電源電圧が5Vだと確度の最大値が悪くなる傾向があるようです。測定する温度範囲は-55~+150℃、16ビットを選択すると温度の分解能は0.0078℃です。変換時間は240msで、I2Cのデータ転送速度は最大で400kHzです。
入手した秋月電子通商のボードでは、設定した温度を超えたときに警報が出るINT、CT端子は外部に出ていません。
●接続
スレーブ・アドレスはボード上のジャンパで変更できます。デフォルトはA0、A1端子がLOWの0x48です。ここではJ3をショートして0x49に変更しました。
●コンフィギュレーション・レジスタ(0x03)
デフォルトが13ビットなので、0x80を書き込んで16ビットに変更します。
bit7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0=13ビット 1=16ビット |
オペレーション・モード | INT/CTモード | INT極性 | CT極性 | フォルト・キュー |
●読み出した温度データの形式
最上位ビットD15が符号の2の補数形式です。温度の入っているレジスタは0x00と0x01です。上位バイトの0x00を読み出すと、自動的にアドレスはインクリメントされ、下位バイトの0x01を読み出します。
上位バイト | 下位バイト | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
●スケッチ
#include <Wire.h>
unsigned char ADT7410_address = 0x49; //A0=HIGH
const unsigned char Configuration_register = 0x03 ;
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("start ");
Wire.beginTransmission(ADT7410_address);
Wire.write(Configuration_register);
Wire.write(0x80);
Wire.endTransmission();
delay(240);
}
void loop() {
Wire.requestFrom(ADT7410_address, 2);
int tempSign = (Wire.read()<<8) | Wire.read() ;
int temp = tempSign & 0x7fff;
if (tempSign & 0x8000 ) temp = -( (~temp & 0x7fff) +1);
float temperature = temp * 0.0078 ;
Serial.println(temperature);
delay(100);
}
このときの波形です。温度レジスタを指定してないのに、温度は正常に読み出せています。温度レジスタのアドレスが最下位の0x00なのが理由かもしれません。
●リピーテッド・スタート・コンディションが必要なスケッチ
IDを読み出します。IDのデフォルト値は11001xxxです。11001が製造者IDで不変です。xxxはリビジョンIDで、ロットにより異なるようです。
#include <Wire.h>
unsigned char ADT7410_address = 0x49; //A0=HIGH
const unsigned char Configuration_register = 0x03 ;
const unsigned char Temp_register = 0x00 ;
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("start ");
Wire.beginTransmission(ADT7410_address);
Wire.write(Configuration_register);
Wire.write(0x80);
Wire.endTransmission();
}
void loop() {
Wire.beginTransmission(ADT7410_address);
Wire.write(0x0b);
Wire.endTransmission();
Wire.requestFrom(ADT7410_address, 1);
...
}
波形です。IDは正しく読み出せていません。
スケッチの19行目をWire.endTransmission(false); に変更しました。0xcbと正しいと思われるIDが読み出せました。
臨界温度を設定するレジスタ0x08を読み出します。デフォルトは147℃の0x49と0x80が入っています。
#include <Wire.h>
unsigned char ADT7410_address = 0x49; //A0=HIGH
const unsigned char Configuration_register = 0x03 ;
const unsigned char Temp_register = 0x00 ;
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("start ");
Wire.beginTransmission(ADT7410_address);
Wire.write(Configuration_register);
Wire.write(0x80);
Wire.endTransmission();
}
void loop() {
Wire.beginTransmission(ADT7410_address);
Wire.write(0x08);
Wire.endTransmission();
Wire.requestFrom(ADT7410_address, 2);
int tempSign = (Wire.read()<<8) | Wire.read() ;
int temp = tempSign & 0x7fff;
if (tempSign & 0x8000 ) temp = -( (~temp & 0x7fff) +1);
float temperature = temp * 0.0078 ; // 0.0078125
Serial.println(temperature);
delay(100);
}
スケッチの19行目Wire.endTransmission();のときの波形です。0x0a、0x15なので正しくありません。モニタには20℃付近の温度が出力されているので、温度レジスタ0x00を読み出しているようです。
Wire.endTransmission(false); に変更しリピーテッド・スタート・コンディションを有効にしました。0x49と0x80が読み出され、モニタには約147℃が表示されています。