気圧センサーが比較的安く購入できるようになったということを知り、秋葉原に行った時に秋月電子で¥1,800で購入し早速Arduinoで試してみました。
気圧センサーSCP1000の概要
VTIテクノロジー社製の絶対圧気圧センサー
8PINでDIP型になっているのでブレッドボードで接続ができる
電源電圧 2.4~3.3V
インターフェイス SPI(Serial Peripheral Interface)
測定範囲 30Kpa ~ 120kPa(300ヘクトパスカル~1200ヘクトパスカル)
外観
接続とスケッチについて、いろいろ情報を入手しましたが、今回はArduinoのホームページから入手した配線図とスケッチを参考にしました。
ライブラリは Arduino のバージョン0018以降にSPIのライブラリがアップされておりますので、それを利用することとしました。
情報入手先URL http://arduino.cc/en/Tutorial/BarometricPressureSensor
SCP1000は温度と気圧が読み取ることができ、インターフェイスSPIにより情報を取り出します。
温度は16ビットの値を返すようになっており、実際の温度換算は読み取った値を「20」で除算すると℃に表示になります。
2011.2.13追記・修正
データに一部誤りがありましたので修正しました。
気圧は上位3ビット、下位16ビットの2つの部分に分かれており、それを読み込んだ後、上位を16ビットシフトさせ、上位・下位を OR 演算で組み合わせます。
その19ビットの値を読み取ることで気圧の情報が取り出せます。
実際の気圧換算は読み取った値を「4」で除算でパスカル(pa)に換算されます。ヘクトパスカル(hpa)の時はさらに「100」で除算します。
ブレッドボードで配線の状態
SCP1000は3.3Vでの動作になりますので、Arduinoとの電圧レベル変換のため分圧抵抗を挿入しております。
ArduinoからXBeeにより、シリアル無線伝送によりPCに取り込みました。
スケッチ
スケッチは取りあえずArduinoを起動した後 OPEN →SPI→Barometric Pressure Sensorをロードして動作させました。
その結果、温度は正常に計測されましたが、気圧は「2000」前後の値が計測されます。
1気圧 「1013」hpaですのでどう見ても異常な値が出ているようで、このままでは使用できない状況です。
温度は正常に計測されておりますので、各部品と結線は正常と判断しスケッチを調べることにしました。
気圧データの内上位データ読み取り部分
//Read the pressure data highest 3 bits:
byte pressure_data_high = readRegister(0x1F, 1);
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
気圧データの内下位データ読み取り部分
//Read the pressure data lower 16 bits:
unsigned int pressure_data_low = readRegister(0x20, 2);
16ビットシフト・OR演算・気圧換算
//combine the two parts into one 19-bit number:
long pressure = ((pressure_data_high << 16) | pressure_data_low)/4;
以上が気圧データに関する部分ですが見たところ特に異常は無いようにみえます。
そこでArduinoのSerial.print()機能を使い、各変数の値をPCモニターに表示して読み取り結果と演算結果を順次追いかけてみました。
結果の例
上位データ(pressure_data_high) 101
下位データ(pressure_data_low) 10001010000011 (8835)
OR演算結果(long pressure)/0.25 10001010000011 (8835)
気圧換算結果 2208pa
上記の結果から最終の結果と下位データの結果が全く同じということになりました。
そのことから上位データの16ビットシフトかOR演算がうまく行われていない可能性が出てきました。
いろいろ見ているうちに、上位データと下位データおよび最終結果の変数のデータ型がそれぞれ別のデータ型になっていることに気づき、unsigned longで統一してみたところ正規の値が表示できるようになりました。
変更内容
// byte pressure_data_high = readRegister(0x1F, 1);
unsigned long pressure_data_high = readRegister(0x1F, 1);
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
//Read the pressure data lower 16 bits:
unsigned long pressure_data_low = readRegister(0x20, 2);
//combine the two parts into one 19-bit number:
long pressure = (((pressure_data_high << 16) | pressure_data_low)/4) /100;
そのほかの変更内容
将来Excelにインポートすることを考慮しSerial.print()の部分を変更
No.と各項目の間に「,」を挿入
// display the temperature & pressure
n = n + 1;
Serial.print(n);
Serial.print(",");
Serial.print(realTemp);
Serial.print(",");
Serial.println( String(pressure));
delay(1000);
BIN表示のSerial.print()はカット
// Serial.print(thisRegister, BIN);
//Serial.print("\t");
//Serial.println(thisRegister, BIN);
Tera Termで最終結果をPCに表示
2011.2.13 追記
マイナス温度の表示修正
温度が氷点下の時正常に表示されないことが判明しましたので、スケッチを一部変更しました。
SCP1000の温度データは符号も含めて14ビットで表現されていますが、温度が氷点下になった時に14ビット目の符号ビットに「1」が入り、表示がマイナスにならなければなりませんが、この符号ビットもそのまま計測データとして計算されておるようです。
そこで温度データを2ビット左にシフトして本来の16ビットとして計算することにしました。
2ビットシフトした分温度換算の時に「 1/4 」に戻しております。
スケッチの変更
//Read the temperature data
int tempData = readRegister(0x21, 2);
tempData = tempData << 2 ;
int realTemp = tempData / 80.0;
※コメント投稿者のブログIDはブログ作成者のみに通知されます