ArduinoのSPI(Serial Peripheral Interface)を使って、K型熱電対用センサーIC、MAX6675を動作させてみたわけですが、そのSketchを書いている時に得た知見を備忘録として列挙しておきます。
また、このエントリの後半には、得られた知見を元に書いたサンプルSketchを掲載しました。
1.Arduino IDEでは「SS」「SCK」「MISO」「MOSI」は予約語で、汎用的な変数名としては使えない
上記文字列はSPI専用の変数として予約されているようで、コンパイルすると「conflicting declaration」エラーが出ます。図1参照。SSやSCKなどは他のSketchでも使いそうですが、使えないようです。
図1 SS,SCK,MISO,MOSIを使った場合のコンパイルエラー
2.SPIに関連するArduinoのピンは固定されている
Arduinoのボードによって違いますが、UNOの場合、SSは10番ピン、SCKは13番ピン、MOSIは11番ピン、MISOは12番ピンです。ボードごとの違いはここの「Connections」を参照ください。
3.SPIの各種設定は、「SPISettings」で一括設定が可能
SPISettingsを使うと、「SCKの周波数」「データ順」「データモード」を一括設定できます。文法は、
SPISettings mySettting(speedMaximum, dataOrder, dataMode)
MAX6675の場合、動作周波数(speedMaximum)は4MHz=4000000、データ順(dataOrder)はMSBを先に出力、データモード(dataMode)は「0」(アイドル時のクロックはローレベル、データのラッチは立ち上がりエッジ)なので、
SPISettings MAX6675Setting (4000000, MSBFIRST, SPI_MODE0)
この設定を行った時の波形を図2に示します。
図2 MAX6675とArduinoとをSPIで接続したときの波形
SCKの周波数は、Arduinoが搭載しているシステムクロックを基準にしており、その周波数の1/2、1/4、1/8、1/16、1/32、1/64、1/128の中から選ぶことができます。
Arduino UNOの場合、クロック周波数が16MHzなので、SCKは8MHz、4MHz、2MHz、1MHz、500KHz、250KHz、125KHzが選択できます。
データモードに関しては、このページに掲載してある表が分かりやすいです。
4.接続図とサンプルSketch
MAX6675を経由して送られてくるK型熱電対先端温度をCOMに表示します。また、SPI上に流れているデータをオシロスコープで確認するために、MAX6675からArduinoへ送られてくるMISO信号の生データも16進で表示します。ArduinoとMAX6675との接続は図3参照。電源は、Arduinoの5VとGNDを使っています。
//これは、ArduinoのSPIを使ってK型熱電対用センサーIC、MAX6675を
//評価するためのサンプルSketchです。
//
//SPIを使うので、SPI用ヘッダーファイルをインクルード
#include <SPI.h>
//MAX6675のデータ格納用変数
int rdata;//MAX6675用SPIの各種設定
//SPIクロックは4MHz、データの出力順は、MSBが先、
//SPIモードは0(クロックはローレベルからスタート、立ち上がりエッジでデータラッチ)
SPISettings MAX6675Setting (4000000, MSBFIRST, SPI_MODE0);void setup() {
//SPIを開始する
SPI.begin();
//COMポートを有効化
Serial.begin(9600);
//MAX6675は、電源投入時にADCの変換時間である最大220msを待たないと、
//内部ADCのデータが不安定になるようで、念のため待ち時間をもうける
//決め打ちで500ms
delay(500);
}void loop() {
//SPIの設定を指定し、SPIを開始する
SPI.beginTransaction(MAX6675Setting);//SSピン(D10)をローレベルとし、MAX6675を選択
digitalWrite(SS,LOW);
//MAX6675からの出力データを読み込む
rdata=SPI.transfer(0xFF) << 8;
rdata=rdata+SPI.transfer(0xFF);
//SSピンをハイレベルとし、MAX6675の選択解除
digitalWrite(SS,HIGH);//SPIを終了する。
SPI.endTransaction();//MAX6675が受け取った16ビットの生データをCOMに表示する
//オシロスコープを使ったデータデコードの確認用にHEXデータをCOMに表示
Serial.print(rdata,HEX);
Serial.print(“, “);
//MAX6675が受け取ったデータのうち、3ビット右シフトして12ビットの温度データのみ抜き出し、
//MAX6675の1LSB分の温度分解能である0.25℃をかけて、温度を計算しCOMに表示する
Serial.print((rdata>>3)*0.25);
Serial.println(” deg C”);delay(1000);
}
実行結果を図4に示します。