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)の使い方などが難しくなってくるとは思いますが、今回はここまでにします。