MAX6675(写真1)はSPIインターフェースを持つ、K型熱電対用センサーです。Arduinoを使って評価をしていたのですが(写真2)、COMに表示されるデータのうち、一番目のデータのみあり得ないデータになってしまいました。
写真2 測定の様子
SPIインターフェースに流れる波形を確認したいので、
キーサイトテクノロジーのオシロスコープDSOX2014を使った
図1 1回目はあり得ないデータが取得されている。2回目以降は問題ない。
このエントリでは、なぜ一番目のデータのみ、あり得ないデータが取得されたその理由と対策を備忘録として記載します。
結論から先に書くと、MAX6675の電源を、Arduinoのデジタルピンの8番(VCC)と9番(GND)から取っていたからです(図2参照)。
図2 MAX6675のVCCをピン8に、GNDをピン9に接続した。
図2は、「Arduinoで計る,測る,量る」 の108ページに記載がある回路図を参照して配線しました。
また以下のSketchは、同書の110ページにあるものをコピペして使い、さらにスイッチサイエンスさんのこのページを参照しました。
#include <SPI.h>
int VCC=8,GND=9;
int rdata;
void setup() {
pinMode(VCC,OUTPUT); <—–8番ピンを出力に設定
pinMode(GND,OUTPUT); <—–9番ピンも出力に設定
digitalWrite(VCC,HIGH); <——8番ピンをHIGHレベルにする。これで5Vが出力される
digitalWrite(GND,LOW); <——9番ピンをLOWレベルにする。これでここは0Vとなる
SPI.begin();
Serial.begin(9600);
}void loop() {
digitalWrite(SS,LOW);
rdata=SPI.transfer(0xFF) << 8;
rdata=rdata+SPI.transfer(0xFF);
digitalWrite(SS,HIGH);
Serial.print(rdata,HEX); <——図1の「5DDC」はこの行が出力している。
Serial.print(” “);
Serial.print(rdata>>3);
Serial.print(” “);
Serial.print(rdata>>3,HEX);
Serial.print(” “);
Serial.println((rdata>>3)*0.25);
delay(500);
上記SketchをインストールしたArduinoを起動させ、起動直後のVCC(5V)、SS(~CS1)、SCK(CLK1)、MISO(MISO1)波形は図3の通り。
図3 MAX6675のVCCをArduinoの8ピン、GNDを9ピンでとったときの波形
起動時、MAX6675に与えられているVCC(5V)が十分に上がっていないのでゴミデータ(0x5DDC)を測定してしまい、そのデータをArduinoが読み込んで、COMに出力したようです。
このままでは問題なので、VCCをArduinoの5Vに、GNDに接続してみました(図4)。本来こうあるべきなんですがね…
図4 MAX6675のVCCをArduinoの「5V」に、GNDをArduinoの「GND」に接続した。
この時の、VCC(5V)、SS(~CS1)、SCK(CLK1)、MISO(MISO1)の波形は図5の通り。
図5 VCCをArduinoの「5V」に、GNDをArduinoの「GND」に接続した時の波形
起動時に観測されるSS(~CS1)、SCK(CLK1)、MISO(MISO1)の波形の挙動は、図3と同じですが、VCC(5V)の変動は見られません。またMISOは「03F0」とリーズナブルな値を出力しており、COMでも同じ値が出力されています(図6)。
やっぱ、電源は電源端子からとりましょう!当たり前だけど…
【2019年9月29日追記】
とある組み込み機器設計エンジニアより以下の指摘がありました。
- 小さな消費電流のデバイスに対して、DIOピンを電源代わりに使うことがある。
- そのデバイスを使わない時、DIOの電圧をローレベルにして電源をオフにできるので、組み込み機器全体の消費電力を減らすことができる。
- ArduinoのDIOはソースもシンクも40mA流せる。MAX6675の消費電流の最大値は最大1.5mA(表1参照)なので問題にならないと思われる。
- MAX6675のデータシートを見ると、ADコンバータの変換時間は最大220msである(表1参照)。今回の場合、電源(DIO)の立ち上がりが遅いため、220msの変換時間に間に合わずゴミデータが出力されてしまうのではないか?
これらの指摘を受け、setup()にdelay(250)を追加して、DIO(電源)が立ち上がってから250ms待ってから、loop()に入るようにした。その結果、1回目の計測でゴミデータが出ることがなくなり、問題なく動くようになった(図7)。
波形も問題ない(図8)。