SpresenseでLチカから始める (27) Wireライブラリ 温度気圧DPS310

 Infineonの気圧センサのDPS310は、300~1200hPaが測れます。実験に便利なボードに実装されたMikroElektonikaのPressure 3 clickボードを入手しました。電源電圧は3.3Vです。

DPS310のおもなスペック

  • 動作電圧 1.2~3.6V
  • 動作範囲 300~1200hPa
  • 消費電流 3uA
  • 分解能 ±0.005hPa、±5cm
  • 確度 ±1hPa、±8m
  • 変換時間 3.6ms
  • 動作時の温度 -40~85℃
  • 温度の確度 ±0.5℃
  • 温度の分解能 0.01℃
  • インターフェース I2C(最大400kHz)とSPI

接続

 I2Cで接続します。I2Cscannerを動かすと0x76に見つけました。Spresenseは3.3Vで利用しています。

Pressure 3 click Spresense
GND GND
+3.3V 3.3V
SCL SCL
SDA SDA

スケッチ

 最初に補正データの入っているレジスタ0x10~0x21の内容を1バイトずつ読み出し、変数c0、c1、c00、c10、c01、c11、c20、c21、c30へ必要な長さ分を収納します。データは2の補数形式なので符号のチェックをします。

 気圧の設定をするPRS_CFG(0x06)レジスタに、1秒間に8回測定しその平均値(?)を収納、128倍のオーバサンプリングの設定値0x37を書き込みます。
 温度の設定をするTMP_CFG(0x07)レジスタに、1秒間に16回測定しその平均値(?)を収納、128倍のオーバサンプリングの設定値0xc7を書き込みます。
 CFG_REG(0x09)レジスタへは、オーバサンプリングをしたのでシフトを指示する0x0cを書き込みます。
 ここまでが初期設定です。

 最初に温度を求めます。MEAS_CFGレジスタに温度を測定する設定を書き込みます。TMP_B2レジスタから3バイトを読み込みます。2の補数形式なので、符号をチェックします。
 補正変数を用いて温度を計算します。Ktはオーバサンプリング時の係数です。

 次に気圧を求めます。MEAS_CFGレジスタに気圧を測定する設定を書き込みます。PSR_B2レジスタから3バイトを読み込みます。2の補数形式なので、符号をチェックします。
 補正変数を用いて気圧を計算します。Ptはオーバサンプリング時の係数です。

#include <Wire.h>
#define DPS310_address 0x76
#define reset 0x0c
#define PSR_B0 0x02
#define PSR_B1 0x01
#define PSR_B2 0x00
#define TMP_B0 0x05
#define TMP_B1 0x04
#define TMP_B2 0x03

#define MEAS_CFG 0x08
#define TempMeasurement 0x06
#define PMeasurement 0x05
#define PRS_CFG 0x06
#define SportsP 0x37 //0 011 - 8 measurements pr. sec. 0111 - 128 times (High Precision).
#define TMP_CFG 0x07
#define SportsT 0xc7 //1-MEMS 100 - 16 measurements pr. sec 0111-oversampling 128
#define CFG_REG 0x09
#define SHIFT 0x0c // temp & P shift
#define Kt 2088960.0 // 128times Compensation Scale Factors
#define Kp 2088960.0 // 128times Compensation Scale Factors

#define COEF 0x10 //0x10 - 0x21
byte readbuffer[30];
int16_t c0,c1,c01,c11,c20,c21,c30;
int32_t c00,c10;

void setup() {
Serial.begin(9600);
Serial.println("\nStart");
Wire.begin();
Wire.beginTransmission(DPS310_address);
Wire.write(reset);
Wire.endTransmission();
delay(100);
for ( int i = 0 ; i < 19 ; i++ ) {
Wire.beginTransmission(DPS310_address);
Wire.write(COEF + i);
Wire.endTransmission();
Wire.requestFrom(DPS310_address,1);
readbuffer[i] = Wire.read();
}
c0 = (readbuffer[0] << 8 | readbuffer[1] & 0xf0 ) >> 4;
c0 = -(c0 & 0b100000000000) | (c0 & 0b011111111111);
c1 = (readbuffer[1] & 0x0f ) << 8 | readbuffer[2] ;
c1 = -(c1 & 0b100000000000) | (c1 & 0b011111111111);
c00 = (readbuffer[3] << 16 | readbuffer[4] << 8 | readbuffer[5] & 0xf0 ) >> 4;
c00 = -(c00 & 0b10000000000000000000) | (c00 & 0b01111111111111111111);
c10 = ((readbuffer[5] & 0x0f) <<16 | readbuffer[6] << 8 | readbuffer[7]);
c10 = -(c10 & 0b10000000000000000000) | (c10 & 0b01111111111111111111);
c01 = readbuffer[8] << 8 | readbuffer[9];
c01 = -(c01 & 0b1000000000000000) | (c01 & 0b0111111111111111);
c11 = readbuffer[10] << 8 | readbuffer[11];
c11 = -(c11 & 0b1000000000000000) | (c11 & 0b0111111111111111);
c20 = readbuffer[12] << 8 | readbuffer[13];
c20 = -(c20 & 0b1000000000000000) | (c20 & 0b0111111111111111);
c21 = readbuffer[14] << 8 | readbuffer[15];
c21 = -(c21 & 0b1000000000000000) | (c21 & 0b0111111111111111);
c30 = readbuffer[16] << 8 | readbuffer[17];
c30 = -(c30 & 0b1000000000000000) | (c30 & 0b0111111111111111);
Serial.println(c0);
Serial.println(c1);
Serial.println(c00);
Serial.println(c10);
Serial.println(c01);
Serial.println(c11);
Serial.println(c20);
Serial.println(c21);
Serial.println(c30);

Wire.beginTransmission(DPS310_address);
Wire.write(PRS_CFG); // 0x06
Wire.write(SportsP);
Wire.endTransmission();

Wire.beginTransmission(DPS310_address);
Wire.write(TMP_CFG); // 0x07
Wire.write(SportsT);
Wire.endTransmission();

Wire.beginTransmission(DPS310_address);
Wire.write(CFG_REG); // 0x09
Wire.write(SHIFT);
Wire.endTransmission();
}

void loop() {
//temp
Wire.beginTransmission(DPS310_address);
Wire.write(MEAS_CFG);
Wire.write(TempMeasurement);
Wire.endTransmission();
delay(100);

Wire.beginTransmission(DPS310_address);
Wire.write(TMP_B2);
Wire.endTransmission(false);
delay(100);

Wire.requestFrom(DPS310_address,3);
readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); readbuffer[2] = Wire.read();
int32_t Temp0 = readbuffer[0] << 16 | readbuffer[1] << 8 | readbuffer[2];
Temp0 = -(Temp0 & 0b100000000000000000000000) | (Temp0 & 0b011111111111111111111111);
// Serial.print("Temp_oF ");Serial.println(String(Temp0,HEX));
float Temp = c0 * 0.5 + c1 * Temp0 / Kt;
Serial.print("Temp ");Serial.println(Temp);
//p
Wire.beginTransmission(DPS310_address);
Wire.write(MEAS_CFG);
Wire.write(PMeasurement);
Wire.endTransmission();
delay(100);

Wire.beginTransmission(DPS310_address);
Wire.write(PSR_B2);
Wire.endTransmission(false);
delay(100);

Wire.requestFrom(DPS310_address,3);
readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); readbuffer[2] = Wire.read();
int32_t P0 = readbuffer[0] << 16 | readbuffer[1] << 8 | readbuffer[2];
P0 = -(P0 & 0b100000000000000000000000) | (P0 & 0b011111111111111111111111);
// Serial.print("P_oF ");Serial.println(String(P0,HEX));
float Praw = P0 / Kp;
float P = c00 + Praw * (c10 + Praw * (c20 + Praw * c30)) + (Temp0 / Kt) * c01 + (Temp0 / Kt) * Praw * (c11 + Praw * c21);
Serial.print("P ");Serial.println(P/100);
Serial.println("--- ");
delay(2000);
}

 実行している様子です。温度は摂氏、気圧はhPaです。

ライブラリを利用

 DPS310で検索すると一つ見つかりました。インストールします。

 サンプルのI2C_commandを読み込んで実行します(1か所修正 Dps310PressureSensor.begin(Wire, 0x76);)。


前へ

SpresenseでLチカから始める (26) Wireライブラリ 温度気圧MS5637-02BA03

次へ

SpresenseでLチカから始める (28) ハイレゾの再生V1.1.2