t49's blog

電子工作初心者のブログ

【ADT7310】Arduinoで温度センサを使う

ADT7310の使い方を紹介します。
今回は、温度センサ「ADT7310」から温度を読み取り、シリアル通信でPCに値を表示します。
使用するマイコンボードはArduino Unoで、C言語を使用しています。

ADT7310の主な特徴

  • SPI互換インターフェース
  • 温度範囲: -55°C 〜 +150°C
  • 分解能:
    • 13bit (0.0625°C)
    • 16bit (0.0078°C)

開発環境

  1. MacBook Air 2022 macOS 12.6.2
  2. Arduino IDE 1.8.19

使用した部品

  1. マイコンボード Arduino Uno
  2. ADT7310使用温度センサモジュール AE-ADT7310 (秋月電子)
  3. ブレッドボード
  4. ジャンプワイヤ
  5. USBケーブル

回路図

回路図

SPI通信

ADT7310から温度データを取得するには、各種レジスタにデータを読み書きする必要があります。
コマンドバイトにR/W、対象のレジスタ、連続読み取り(連続読み取りモードが有効の場合)を設定し、対象レジスタのデータを末尾に付けて送信します。
今回は連続読み取りモード、16bit modeで使用するため、その設定値を記載します。
なお、連続読み取りモードはデフォルトで設定されています。
詳細はデータシートを確認してください。

コマンドバイト

C7 C6 C[5:3] C2 C1 C0
0 R/W Register address Continues read 0 0
  • R/W: 1:読み取り、0: 書き込み
  • Register address
Register address Description Power-On Default
0x00 Status 0x80
0x01 Configuration 0x00
0x02 Temperature value 0x0000
0x03 ID 0xCX
0x04 T_CRIT setpoint 0x4980(147°C)
0x05 T_HYST setpoint 0x05(5°C)
0x06 T_HIGH setpoint 0x2000(64°C)
0x07 T_LOW setpoint 0x0500(10°C)
  • Continues read:
    設定レジスタを連続読み取りに設定してる場合に有効なbitで、このbitを立てると連続読み取りモードをアクティブにします。
    連続読み取りモードをアクティブにするにはコマンドバイト0x54(01010100)を送信、非アクティブにする場合はコマンドバイト0x50(01010000)を送信します。
    連続読み取りモードを使用すると、設定レジスタに都度書き込みを行わずに16bitの空のデータを送信すれば、温度データを取得できるので便利です。

設定レジスタ データフォーマット

  • 16bit modeの場合 (0x80)
C7 C[6:5] C4 C3 C2 C[1:0]
Resolution Operation mode NT/CT mode INT pin polarity CT pin polarity Fault queue
1 0 0 0 0 0
  • 13bit modeの場合 (デフォルトの設定) (0x00)
C7 C[6:5] C4 C3 C2 C[1:0]
Resolution Operation mode NT/CT mode INT pin polarity CT pin polarity Fault queue
0 0 0 0 0 0

温度値レジスタ データフォーマット

  • 16bit modeの場合
C15 C[14:8] C[7:3] C2 C1 C0
Sign Temp Temp LSB2 LSB1 LSB0
  • 13bit modeの場合
C15 C[14:8] C[7:3] C2 C1 C0
Sign Temp Temp T_CRIT flag T_HIGH flag T_LOW flag

サンプルコード

#include<SPI.h>
#define SS 10
#define MOSI 11
#define MISO 12
#define SCLK 13

// short: 2byte
short data;

void setup(){
  // シリアル通信を開始
  Serial.begin(9600);
  Serial.println("Serial start");
  
  // 通信を無効
  digitalWrite(SS,HIGH);
  
  delay(300);

  // SPI通信を開始
  SPI.begin();
  Serial.println("SPI start");
  
  // 通信を有効
  digitalWrite(SS,LOW);

  // 連続読み取りモードを終了
  SPI.transfer(0x50);
  
  delay(300);

  // コマンドバイト: 設定レジスタに書き込み
  SPI.transfer(0x0C);
  // 設定レジスタ: 16bit分解能
  SPI.transfer(0x80);
  
  delay(300);
  
  // 温度レジスタに対して連続読み込み
  SPI.transfer(0x54);

  delay(300);
}
  
void loop(){
  // 16bitで温度データを取得
  data = SPI.transfer16("");

  Serial.print("BIN DATA: ");
  Serial.println(data,BIN);

  // 符号ありの為、32768 = 0b1000_0000_0000_0000からマイナス
  if(data >= 32768){
    // 65535 = 0b1111_1111_1111_1111 = -1と表現
    // 65536を引くことで、65535から-1と表現する
    // 16bit分解能: 0.0078°C ≒ 1/128
    Serial.print((double)data-65536/128);
  } else {
    Serial.print((double)data/128,4);
  }
  
  Serial.println("[°C]");
  
  delay(500);
}

実行結果

連続読み取りモードで温度データを取得できました。

補足

温度レジスタの値には2補数表現が使われています。
補数について、下記に補足します。

2の補数表現

補数には2つの意味があります。

  • 基数の補数....あるn進数に加算すると、桁が繰り上がる(nのべき乗になる)最小の数。
  • 減基数の補数....あるn進数に加算しても、桁が繰り上がらない(nのべき乗-1)最大の数。

2進法の場合、基数の補数を「2の補数」、減基数の補数を「1の補数」と呼びます。
あるn桁の2進数とその2の補数を加算し、n桁の部分のみを見ると「0」になります。
これは、2の補数をマイナスの値として表現することで例えば「1+(-1) = 0」と同じ状態と見なせます。
この表現を利用し、加算のみで減算を行うことができます。
例として加算してみます。

例 ) 4桁の2進数
1101 - 1101 = 0

1101 (元の数)
↓ 1の補数を求める(bitを反転)
1111 - 1101 = 0010
↓ 2の補数を求める(1の補数に1を加算)
0010 + 0001 = 0011
↓ 元の数と2の補数を加算
1101 + 0011 = 10000
→ 5bit目は桁溢れのため、0とみなす。

例2) 5桁の2進数と4桁の2進数の減算
11000 - 1100 = 1100

01100 (元の数)
↓ 1の補数を求める
11111 - 01100 = 10011
↓2の補数を求める
10011 + 00001 = 10100
↓ 元の数と2の補数を加算
11000 + 10100 = 101100
→ 6bit目は桁溢れのため、1100とみなす。

5桁の2進法なので、基準は10000、1100に対する2の補数は10100となります。
元の数と2の補数を加算すると101100、6bit目は不可視のため1100となります。

また、10進数で同様のことをすると、

例3) 有効桁数2桁
13 - 2 = 11

2 (元の数)
↓ 10の補数を求める
100 - 2 = 98
↓ 元の数と10の補数を加算する
13 + 98 = 111 → 最上位の桁を除き11とみなす。

今回は最大2桁の10進数なので、基準は100となり 、2に対する10の補数は98となります。
これは、10の補数の世界では、今回の例だと99が-1、98が-2のように99~50を-1~-50として表現し、100を下回った分の数が「-」と表現される為です。

10の補数と元の数を加算するという操作は、桁を1つ増やし、元々の桁の部分を「0」にして、その桁の中で減算をしています。(100を下回る場合には上記のように「-」と表現されます。)
式を分解してみると、13 - 2の計算に100を加算して桁を繰り上げています。

13 - 2

13 + (100 - 2)

100 + 13 - 2 = 111

元の数に10の補数を加算すると111、最上位の桁を除くと11となり減算した結果と同じことが分かります。

2の補数表現を利用すると、最上位のbitを符号として表現することができます。
n桁の符号あり2進数は-2n-1 ~ 2n-1-1、符号なし2進数は2nの範囲の値を表現することができます。
「-」の範囲が大きいのは、2n bitがちょうど値の中間となりこれを「-」とすると最上位bitを符号として表現するのに都合がいいからだと考えられます。

例) 4bitの10進数表現

2進数 10進数(符号なし) 10進数(符号あり)
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 -8
1001 9 -7
1010 10 -6
1011 11 -5
1100 12 -4
1101 13 -3
1110 14 -2
1111 15 -1