SpresenseでLチカから始める (15) Wireライブラリ 温度EMC1412
温度センサの多くは、それ自体に内蔵された温度を検知するセンサ・デバイスの出力をA-D変換し、非直線性などを補正し、ノイズ成分をフィルタリングしたのちI2CやSPIバスを通してマイコンとやり取りをします。製品のパッケージが大きいと、温度変化に対しての反応速度が遅いです。温度変化が少ない場所の測定に適しています。サーミスタなどは、測定したい場所にデバイスをもっていけ、形状も小さいので温度が急激に変化する場所の測定に向いています。
マイクロチップのEMC1412は、IC自体に温度を測るセンサを内蔵していますが、外部にも温度センサとなるダイオードもしくはトランジスタを接続できます。
●EMC1412のおもな特徴
- 動作電源電圧範囲 -0.3~4.0V。I/Oピンは5Vトレラント
- 消費電流 スタンバイ時170uA、1回/秒変換時430uA
- 温度 確度±0.25℃、分解能0.125℃、測定範囲-40~+125℃
- インターフェース I2C(10~400kHz)
入手したのはEMC1412-1-ACZL-TRで、スレーブ・アドレスは0x4cです。EMC1412-A-xxモデルは、4番ピンのADDRをプルアップする抵抗値でI2Cのスレーブ・アドレスが決定されます。
●接続
MSOP 8ピン・パッケージを購入し、変換基板にはんだ付けしました。
温度センサとして内蔵のダイオードだけを利用するときは、I2CバスのSDAとSCL信号、電源の合計4本の配線だけで動作します。EMC1412の電源電圧は3.3Vです。Arduino UNOのI/Oは5Vです。EMC1412のI/O端子は電源電圧より高い5Vの電圧がかかっても信号のやり取りができる5Vトレラントなので、電圧のレベル変換をせずに接続できます。Spresenseを3.3V電源で使うとき、I/OのHighレベルは3.3Vで、そのまま接続して使えます。
デバイスの外部の温度を測定するときは、2番ピン(DP)と3番ピン(DN)にダイオードもしくはトランジスタを接続します。このセンサの非直線性や配線の抵抗はデバイス内部で補正されます。また、ノイズの影響を軽減するためのフィルタ用にコンデンサ(最大2.2nF)を取り付けられます。
ダイオードやトランジスタはPN接合をもち、温度係数があるので、温度センサとして利用しています。利用したトランジスタは2SA1015です。
6番ピンはAlert出力です。上限温度(デフォルトは85℃)を設定し、設定温度を超えるとこの端子をLowにします。今回利用していません。
●おもなレジスタ
アドレス | 機能 | 初期値 |
---|---|---|
0x00 | 内部ダイオードの読み出し(上位8ビット)。下位ビットは0x29 | 0x00 |
0x01 | 外部ダイオードの読み出し(上位8ビット)。下位ビットは0x10 | 0x00 |
0x02 | ステータス | 0x00 |
0x03 | コンフィギュレーション | 0x00 |
0x04 | 変換レート | 0x06(4回/秒) |
(※)温度データは11ビット2の補数形式。上位バイトに上位8ビットが、下位バイトにはMSBから3ビット分が入る。コンフィギュレーションの初期値0x00ではRUNモードになっているので、変更せずに温度の読み出しができる。初期値での温度の測定範囲は0~127.875℃なので、マイナス値が必要なときは、レジスタの内容を変更する。
(※)外部トランジスタを利用するときは、0x25のベータ・コンフィギュレーション・レジスタで補償パラメータを設定できるが、ここではデフォルト値を使った。外部にダイオードを使うときは、係数Ideality Factorを0x27のレジスタで設定ができる。
●スケッチ
最初に、左詰めで記録されている16ビット分を読み出し、右に5ビット・シフトすれば11ビットの温度データが用意でき、LSBが0.125℃なので乗ずれば摂氏の温度になります。
#include <Wire.h>
#define EMC1412address 0x4c
#define internalR_High 0x00
#define internalR_Low 0x29
#define externalR_High 0x01
#define externalR_Low 0x10
void setup() {
Wire.begin();
Serial.begin(9600);
}
int read_tempdata(int register_address) {
Wire.beginTransmission(EMC1412address);
Wire.write((byte)register_address);
Wire.endTransmission();
Wire.requestFrom(EMC1412address, 1);
//wait for response
while(Wire.available() == 0);
int T = Wire.read();
return T;
}
void loop() {
int internalTemp = ( read_tempdata(internalR_High) << 8 | read_tempdata(internalR_Low) ) >> 5;
Serial.print(internalTemp,BIN); Serial.print(" internal "); Serial.println(internalTemp * 0.125,1);
int externalTemp = ( read_tempdata(externalR_High) << 8 | read_tempdata(externalR_Low) ) >> 5;
Serial.print(externalTemp,BIN); Serial.print(" External "); Serial.println(externalTemp * 0.125,1);
delay(1000);
}
Spresense(電源は3.3V)の実行結果です。トランジスタを指先でつまんでいます。
(※)この温度センサは2008年ごろのインテルおよびAMDのCPUに内蔵されたサーマル・ダイオードを利用してCPUの温度を測定するデバイスのようです。同じような仕様の製品にLM95245があります。こちらは日本語で解説が読めます。