SPI温度センサADT7310を使う(4) 16ビットモードで測定

今回は16ビットモードに設定して測定してみます。

●16ビットモード分解能の設定

基本的にはコンフィギュレーションレジスタを16ビットに設定してAD変換値を読み出し、16ビット用の換算式で計算するだけですが、何点か、引っかかることがあったので、それも説明します。Configration registorのビットアサインを再掲載しておきます。

ADT7310_03

16ビットモードでContinuousモードで使用する場合の設定値は0×80になります。

●ADT7310のソフトウェアリセット

当初、Arduinoのリセットボタンを押してリセットを繰り返してプログラムをリスタートさせると、時々レジスタ設定に失敗し、正常に読み出せないことがありました(Arduinoをリセットしただけでは、ADT7310はリセットされない。前回の状態を保持したまま)。

リセットコマンドのようなものは無いので、何かリセットする方法はないかとデータシートを見ていたら、見つけました。

32回続けて”1″を書き込むとリセットが起こるという記述を見つけました。早速0xFFを4回書き込む処理をプログラムの初期化時に実行させたら、レジスタの書き込みミスが起きなくなったようです。リセットが利いているようです。

プログラムの冒頭で、コンフィギュレーションレジスタを設定して、内容を確認するためにすぐに読み出して、値をシリアルで送信するようにしています。今回のプログラムでは、この値が0×80(16ビットの連続読出し)となっているのが正常です。うまく設定できていないときは、0×00となります。

●読み出しエラー

連続で読み出していると、まれに0.00という値が返ることがあります。ADT7310の変換の周期とプログラムで制御している読み出しの周期が同期していないため、たまたま変換の最中に読み出して失敗しているのだと思います。0℃と単純に区別はつきませんが、0.00となった時は少し時間を空けてリトライするか、ステータスレジスタ(Status Register:0×00)の/RDYビットを調べて変換が完了しているのを確認してから読み出す必要があります。今回はなにもせずにそのままにしてあります。

●16ビットモードでの温度測定のサンプルスケッチ

次にサンプルスケッチを示します。16ビットのAD変換値を読み出したあとの換算はADT7410の処理と同じです。今回は、コマンドバイトを書き込んだあと一旦/CS信号を非アクティブにし、その後の2バイトの読み込み処理の度に/CS信号のアクティブ、非アクティブを繰り返すようにしました。

#include <SPI.h>

int pinCS = 9;      // 温度センサCS D9

#define SPI_CS_ON   digitalWrite(pinCS, LOW)      // /cs = L
#define SPI_CS_OFF  digitalWrite(pinCS, HIGH)     // /cs = H

byte count = 0;

// 初期化
void setup(void) {
  byte reg;

  pinMode(pinCS, OUTPUT);   // spi cs
  SPI_CS_OFF;

  SPI.begin();

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE3); // 負論理クロック 立ち上がりエッジサンプリング

  Serial.begin(19200);

  // ADT7310 ソフトウェアリセット 32bit
  SPI_CS_ON;
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);
  SPI_CS_OFF;

  delay(5);

  // モード設定
  SPI_CS_ON;
  SPI.transfer(0x0C);       // コマンドバイト 0 0 001 100
  SPI.transfer(0x80);       // コンフィギュレーションレジスタ 1 00 00000 16bit conti
  SPI_CS_OFF;

  delay(100);

  // コンフィギュレーションレジスタ読み出し(設定確認)
  SPI_CS_ON;
  SPI.transfer(0x4C);       // コマンドバイト 0 1 001 100
  reg = SPI.transfer(0);    // 読み出し
  SPI_CS_OFF;

  Serial.print("Config: 0x");
  Serial.println(reg, 16);

//  delay(200);   // ディレイ

  // continuous read mode
  SPI_CS_ON;
  SPI.transfer(0x54);           // 開始
  SPI_CS_OFF;
  delay(240);
}

// メインループ
void loop(void) {
  uint16_t val;
  float tmp;
  int ival;

  SPI_CS_ON;
  val = (uint16_t)SPI.transfer(0) << 8;   // AD変換値 上位
  val |= SPI.transfer(0);                 // AD変換値 下位
  SPI_CS_OFF;
  /*  コマンドバイトの書き込みは最初の1回のみでよい */

  ival = (long int)val;
  if(val & 0x8000) {         // 符号判定
    // 負数
    ival = ival - 65536;
  }

  tmp = (float)ival / 128.0;

  Serial.print(count);
  Serial.print(": ");
  Serial.println(tmp, 2);     // xx.xx

  count++;
  delay(500);
}

25行目にソフトウェアリセットの処理があります。35行目でモードを16ビットに設定します。

43行目は内容確認のため、設定したレジスタの内容をすぐに読み出してシリアルで送信しています。

54行目で連続読み出しのスタートコマンドを送信しています。ここでは一旦/CSを非アクティブにしています。

メインループ中の66行目でAD変換値を読み出しています。ここでは2バイトの読み出し処理のみです。読み出しの度にCS信号のアクティブ、非アクティブを繰り返しています。

それ以降の処理は摂氏温度への変換とシリアル送信の処理で、ADT7410の16ビットの時とほぼ同じです。

今回は、読み出し回数を示す8ビットのカウンタを付けて、読み出す度にインクリメントさせ、温度値と一緒に表示させるようにしています。

コメントは受け付けていません。