M5Stackで始めるセンサ・インターフェーシング(8) 気圧センサLPS25HBを利用

 気圧センサは従来補正パラメータが多く、それらを読み出し計算をして気圧を求めていました。ここで利用するSTMicroelectronicsのLPS25HBは、補正がICの内部で行われます。ボードは、秋月電子通商から入手しました。電源がつながるとLEDが点灯しますから、消費電力を抑えたいときはLEDの配線を切って利用します。

  LPS25HB使用 気圧センサーモジュールDIP化キット

LPS25HBボードのおもなスペック

  • 動作電圧 3.3V(デバイスは1.7~3.6 V)
  • 消費電流 約2mA(LED分を含む。ハイレゾ、1Hz測定間隔時25uA)
  • 測定範囲 260~1260hPa
  • 確度 ±0.1hPa(25℃)、±1hPa(0~80℃)
  • インターフェース SPI、I2C。I2C用プルアップ抵抗は実装、デフォルトは切り離し

 データシートはこちらからダウンロードできます。

接続

 I2Cで接続します。取扱説明書に従うと、次のようになります。ボードのピン番号は、OPアンプなどの8ピンDIPと同じように振られています。I2Cのプルアップ抵抗はM5Stack本体でつながっているので、このボードのジャンパを触りません。

ボードのピン番号 M5Stack (GROVEコネクタ)
1 Vdd 3.3
2 SCL SCL
3 SDA SDA
4 SA0 Vddにつないでスレーブ・アドレスは0x5d   -
5 CS Vddに接続してI2Cモードに  
6 NC  -
7 INT  -
8 GND GND

気圧の読み出しと表示

 気圧のデータは、3バイト24ビットです。PRESS_OUT_H (2Ah)、 PRESS_OUT_L (29h)、PRESS_OUT_XL (28h)を読み出し、4096で割るとhPaの値になります。

 1Hzの繰り返しで気圧データを読み出します。電源が入ったのち、パワーダウン・モードになっているので、測定できるモードに変更します。この二つの設定は、「CTRL_REG1」(0x20)に0x90を書き込むことで実現します。

 気圧データの低いアドレス28hから3バイトを読み出しますが、0x28 | 0x80の形で読まないと、正しいデータが読めません。

#include <Wire.h>
#include <M5Stack.h>
#define LPS25HB_address 0x5d

byte readbuffer[3];
float press;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  M5.begin();
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.print("LPS25HB start");
//  Serial.println("start");
  Wire.beginTransmission(LPS25HB_address);
    Wire.write(0x20);Wire.write(0x90);
  Wire.endTransmission();
}


void loop() {
  for(int i=0; i<180; i++) {
    Wire.beginTransmission(LPS25HB_address);
      Wire.write(0x28 | 0x80);
    Wire.endTransmission();
    Wire.requestFrom(LPS25HB_address, 3);
    readbuffer[0] = Wire.read();
    readbuffer[1] = Wire.read();
    readbuffer[2] = Wire.read();
    press = (readbuffer[2] << 16 | readbuffer[1] << 8 | readbuffer[0]) / 4096.0;
      M5.Lcd.setTextColor(WHITE);
      M5.Lcd.print("  "); M5.Lcd.print(press);
      M5.Lcd.setTextColor(YELLOW);
      M5.Lcd.drawString(String(press,1),40,169,7);M5.Lcd.drawString("hPa",224,192,4);
    delay(1000);   
  }
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);
}

 実行結果です。print()関数では、デフォルトの小さい文字を表示します。
 drawString()の最後の引数7は大きめ文字で7セグLEDの数字を表示します。引数4は、中ぐらいの大きさのASCII文字を表示します。

気圧と温度の読み出しと関数化

 確度が±2℃の温度計が内蔵されているので、そのデータを読み出し、480で割り、42.5を加算すると摂氏の温度が得られます。内蔵の温度計なので、周辺温度より高めになるようです。
 読み出して16ビットにした値を(int16_t)でキャストしないと、正しいデータになりませんでした。気圧の24ビット・データも(int32_t)でキャストしていますが、こちらはキャストしなくても正しい値になりました。

#include 
#include 
#define LPS25HB_address 0x5d

byte readbuffer[3];
float press;
float temp;

void setup() {
  Wire.begin();
  M5.begin();
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.print("LPS25HB Press data hPa/Temp data");
  Wire.beginTransmission(LPS25HB_address);
    Wire.write(0x20);Wire.write(0x90);  // wakeup
  Wire.endTransmission();
}

void loop() {
  M5.Lcd.drawString(String(readTemp(),1),50,136,6);M5.Lcd.drawString("`C",164,153,4);
  M5.Lcd.drawString(String(readPress(),1),40,185,6);M5.Lcd.drawString("hPa",214,200,4);
  delay(2000);   
}

float readPress(){
  Wire.beginTransmission(LPS25HB_address);
    Wire.write(0x28 | 0x80);
  Wire.endTransmission();
  Wire.requestFrom(LPS25HB_address, 3);
  readbuffer[0] = Wire.read();
  readbuffer[1] = Wire.read();
  readbuffer[2] = Wire.read();
  press = (int32_t)(readbuffer[2] << 16 | readbuffer[1] << 8 | readbuffer[0]) / 4096.0;
  return press;
}

float readTemp(){
  Wire.beginTransmission(LPS25HB_address);
    Wire.write(0x2b | 0x80);
  Wire.endTransmission();
  Wire.requestFrom(LPS25HB_address, 2);
  readbuffer[0] = Wire.read();
  readbuffer[1] = Wire.read();
  M5.Lcd.print(readbuffer[1]);M5.Lcd.print("  ");M5.Lcd.print(readbuffer[0]);M5.Lcd.print("  ");
  temp = 42.5 + (int16_t)(readbuffer[1] << 8 | readbuffer[0])/480.0;
  return temp;
}

 実行結果です。

グラフを描く

 スプライトの機能を使って、折れ線グラフを描きます。

 M5.Lcd.から始まる関数は、オレンジ色の座標です。graph1.から始まる関数の座標は、グレーのスプライト領域の座標です。ただし、graph1.pushSprite(5, 20);の座標は、オレンジ色の座標です。

 グラフは、スプライト領域の左から右へ '.' どっとを打っていきます。右端にくると、x座標は同じ場所にドットを打ちます。そしてスプライト領域を左にシフトします。常に新しい値がグラフになります(右端で数ドットずれているかもしれない)。

#include <Wire.h>
#include <M5Stack.h>
#define LPS25HB_address 0x5d

byte readbuffer[3];
float press;
float temp;
TFT_eSprite graph1 = TFT_eSprite(&M5.Lcd);

void setup() {
  Wire.begin();
  M5.begin();
  M5.Lcd.setCursor(50, 10);
  M5.Lcd.print("LPS25HB Press & Temp data");
  Wire.beginTransmission(LPS25HB_address);
    Wire.write(0x20);Wire.write(0x90);  // wakeup
  Wire.endTransmission();
  graph1.setColorDepth(8);
  graph1.createSprite(314, 160);  // 320, 240
  graph1.fillSprite(BLACK); 
 //graph1.drawString("ABCDEFGABCDEFGABCDEFG",0, 0, 4); // スプライト領域内の相対座標
}
int x=3; void loop() { graph1.pushSprite(5, 20); // x,y 左上の座標。スプライト領域内 if (x<317) { x = x+2; graph1.setTextColor(RED); graph1.drawString(".",x, 1050-int(readPress()), 4); graph1.setTextColor(CYAN); graph1.drawString(".",x, 40-int(readTemp()), 4); } else { graph1.setTextColor(GREENYELLOW); graph1.drawString(".", 310, 1050-int(readPress()), 4); graph1.setTextColor(YELLOW); graph1.drawString(".", 310, 40-int(readTemp()), 4); graph1.scroll(-1, 0); } delay(1000); M5.Lcd.drawRoundRect(0, 0, 320, 182, 2, WHITE); M5.Lcd.drawLine(1, 80, 5, 80, WHITE); M5.Lcd.setTextColor(YELLOW); M5.Lcd.fillRect(0, 186, 320, 44, TFT_BLACK); M5.Lcd.drawString(String(round(readTemp()),0),8,192,6);M5.Lcd.drawString("'C",64,208,4); M5.Lcd.setTextColor(GREENYELLOW); M5.Lcd.drawString(String(readPress(),1),102,192,6);M5.Lcd.drawString("hPa",256,208,4); } float readPress(){ Wire.beginTransmission(LPS25HB_address); Wire.write(0x28 | 0x80); Wire.endTransmission(); Wire.requestFrom(LPS25HB_address, 3); readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); readbuffer[2] = Wire.read(); press = (int32_t)(readbuffer[2] << 16 | readbuffer[1] << 8 | readbuffer[0]) / 4096.0; return press; } float readTemp(){ Wire.beginTransmission(LPS25HB_address); Wire.write(0x2b | 0x80); Wire.endTransmission(); Wire.requestFrom(LPS25HB_address, 2); readbuffer[0] = Wire.read(); readbuffer[1] = Wire.read(); //M5.Lcd.print(readbuffer[1]);M5.Lcd.print(" ");M5.Lcd.print(readbuffer[0]);M5.Lcd.print(" "); temp = 42.5 + (int16_t)(readbuffer[1] << 8 | readbuffer[0])/480.0; return temp; }

 実行結果です。途中で、センサを加熱しました。

前へ

フルカラー7セグメントLEDの点灯②数値を表示

次へ

プログラマブル・ゲイン・アンプMCP6S22