SpresenseでLチカから始める (25) Wireライブラリ 温度気圧MS5837-30BA
TEの気圧センサMS5837-30BAは、Oリングを使って接続ができる外形をしています。実験用に、プリント基板に3mmΦの穴をあけ、端子をはんだ付けしました(写真は裏面)。
●MS5837-30BAのおもなスペック
- 動作電圧 1.5~3.6V
- 消費電流 0.6uA
- 分解能 0.3mbar
- 変換時間 0.5ms
- 動作時の温度 -20~85℃(0~30bar)
- インターフェース I2C(最大400kHz)
- Oリング 1.8×0.8mm
●接続
Spresenseは3.3Vで利用しています。
MS5837-30BA | Spresense | |
---|---|---|
1 | GND | GND |
2 | Vdd | 3.3V |
3 | SCL | SCL |
4 | SDA | SDA |
●スケッチ
読み出し手順はデータシートには次のように指定されています。
- リセット
- キャリブレーション・データの読み出し(一度だけ)
- D1データの指定と読み出し
- D2データの指定と読み出し
- 温度をキャリブレーション・データで補正
- 温度が-15℃以下、20℃以下、それ以上の温度の条件でそれぞれ補正データを計算
- それらを使って気圧データを補正
データの型はデータシートに従って指定しました。64ビットの型は指定していますが、コンパイラによって64ビット整数になっているかは不明です。キャリブレーション・データの最初のデータはCRC-4ですが、計算せずに読み飛ばしました。
#include <Wire.h>
#define MS5837_address 0x76
#define reset 0x1e
#define PROMread 0xa0 //a0 to ae
#define Convert_D1 0x4a // OSR 8192
#define Convert_D2 0x5a // OSR 8192
#define ADCread 0x00
uint16_t c1,c2,c3,c4,c5,c6;
float Temp,P;
int64_t OFF, SENS, OFF2, SENS2;
int32_t dT, Ti, SENSi, OFFi;
int readbuffer[12];
void setup() {
Serial.begin(9600);
Serial.println("\nStart");
Wire.begin();
Wire.beginTransmission(MS5837_address);
Wire.write(reset);
Wire.endTransmission();
delay(100);
for ( byte i = 0 ; i < 7 ; i++ ) {
Wire.beginTransmission(MS5837_address);
Wire.write(PROMread + i * 2);
Wire.endTransmission();
Wire.requestFrom(MS5837_address,2);
readbuffer[i] = (Wire.read() << 8) | Wire.read();
}
c1 = readbuffer[1]; //readbuffer[0] is CRC
c2 = readbuffer[2];
c3 = readbuffer[3];
c4 = readbuffer[4];
c5 = readbuffer[5];
c6 = readbuffer[6];
Serial.println(c1);
Serial.println(c2);
Serial.println(c3);
Serial.println(c4);
Serial.println(c5);
Serial.println(c6);
}
void loop() {
Wire.beginTransmission(MS5837_address);
Wire.write(Convert_D1);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(MS5837_address);
Wire.write((byte)ADCread);
Wire.endTransmission();
delay(100);
Wire.requestFrom(MS5837_address, 3);
readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); readbuffer[2] = Wire.read();
uint32_t d1 = readbuffer[0] << 16 | readbuffer[1] << 8 | readbuffer[2];
Wire.beginTransmission(MS5837_address);
Wire.write(Convert_D2);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(MS5837_address);
Wire.write((byte)ADCread);
Wire.endTransmission();
delay(100);
Wire.requestFrom(MS5837_address, 3);
readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); readbuffer[2] = Wire.read();
uint32_t d2 = readbuffer[0] << 16 | readbuffer[1] << 8 | readbuffer[2];
dT = d2 - c5 * pow(2,8);
Temp = 2000.0 + dT * c6 / pow(2,23);
// Serial.print("Temp_o ");Serial.println( Temp);
OFF = c2 * pow(2,16) + (c4 * dT) / pow(2,7);
SENS = c1 * pow(2,15) + (c3 * dT) / pow(2,8);
P = (d1 * SENS / pow(2,21) - OFF ) / pow(2,13);
// Serial.print("dT ");Serial.println(dT);
// Serial.print("OFF_o ");Serial.println(OFF);
// Serial.print("SENS_o ");Serial.println(SENS);
// Serial.print("P_o ");Serial.println(P);
if (Temp <2000.0) {
Ti = 3 * dT * dT / pow(2,33);
OFFi = 3 * (Temp - 2000) * (Temp - 2000) / pow(2,1);
SENSi = 5 * (Temp - 2000) * (Temp - 2000) / pow(2,3);
if (Temp <-1500.0) {
OFFi = OFFi + 7 * (Temp + 1500) * (Temp + 1500);
SENSi = SENSi + 4 * (Temp + 1500) * (Temp + 1500);
}
} else {
Ti = 2 * dT * dT / pow(2,37);
OFFi = (Temp - 2000) * (Temp - 2000) / pow(2,4) ;
SENSi = 0;
}
OFF2 = OFF - OFFi;
SENS2 = SENS - SENSi;
Temp = (Temp - Ti) /100.0;
P = (((d1 * SENS2) / pow(2,21) - OFF2) / pow(2,13)) / 10;
Serial.print("Temp ");Serial.println(Temp);
Serial.print("P ");Serial.println(P);
delay(2000);
}
実行中の様子です。
●ライブラリの利用
MS5837で検索すると一つ見つかります。
サンプルのMS5837_Exampleを読み込んで実行しました。