Arduino UnoでSPI通信の2回目です。前回のArduino UnoでSPI通信(その1)Arduino2台で通信ではArduino Uno2台でSPI通信を確認しました。今回は実際のデバイスでデータを取得します。ここではADT7310という温度センサを使いました。以前に以下でADT7410を使いましたが、ADT7410はI2C通信で、今回のADT7310はSPI通信です。通信方法以外は同じような使い方なのでここではADT7310を使ってみました。
温度センサADT7410(その2)Arduinoでの利用
ADT7310は以下を使っています。
ADT7310使用 高精度・高分解能 SPI・16Bit 温度センサモジュール

Arduino Unoとは以下のように接続します。
ADT7310 – Arduino
CS – Pin10 SS(CS)
SDI – Pin11 MOSI
SDO – Pin12 MISO
SCL – Pin13 SCK
VDD – 5V
GND – GND
スケッチは以下です。
(※2017/03/23 ソフトウェアリセットを追加しました。これで動作が安定しました。)
(※2017/05/29 問題がありましたのでスケッチを修正しました。)
#include <SPI.h>
/*
* ADT7310での温度データ取得
* ADT7310 - Arduino
* CS - Pin10 SS(CS)
* SDI - Pin11 MOSI
* SDO - Pin12 MISO
* SCL - Pin13 SCK
* VDD - 5V
* GND - GND
*/
int SSPin = 10; // Pin10をSS
// 初期化
void setup(void) {
pinMode(SSPin, OUTPUT);
Serial.begin(9600);
SPI.setBitOrder(MSBFIRST); //最上位ビット(MSB)から送信
SPI.setClockDivider(SPI_CLOCK_DIV128); //通信速度を遅く設定
SPI.setDataMode(SPI_MODE0); //CPOL(クロック極性):0 CPHA(クロックフェーズ):0
SPI.begin();
SetSSPin(LOW);
//ソフトウェアリセット
SPI.transfer(0xFF);
SPI.transfer(0xFF);
SPI.transfer(0xFF);
SPI.transfer(0xFF);
SPI.transfer(0x54); // 測定開始(continuously read)
delay(500); // 仕様上は、240msで開始
}
// メインループ
void loop(void) {
uint16_t uiVal;
float fVal;
int iVal;
uiVal = (uint16_t)SPI.transfer(0) << 8; // AD変換値 上位
uiVal |= SPI.transfer(0); // AD変換値 下位
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秒待つ
}
/*
* SSピンの設定
* Lowでマスタからの通信が有効(セレクト)
* (Highではマスタから通信出来ない(無視される)セレクト解除の状態)
*/
void SetSSPin(int val)
{
digitalWrite(SSPin, val);
}
このスケッチでは単純に13ビットモードで温度データを取得しています。SPI通信の処理はArduinoのライブラリで処理しています。初期設定の部分はこのように書いたらデータが取得出来たというところもあります。
ADT7310は16ビットモードでの温度取得も出来ます。またSPI通信に関しては複数のスレーブになった場合のSS(CS)の使い方などが難しくなってくるとは思いますが、今回はここまでにします。

