CircuitPython 10行プログラミング Step3 (7) 気圧センサ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と同じように振られています。

ボードのピン番号 Metro M4 Express AirLift (WiFi)
1 Vdd 3.3
2 SCL SCL
3 SDA SDA
4 SA0 Vddにつなぐとスレーブ・アドレスは0x5d、GNDへつなぐと0x5c
5 CS

Vddに接続するとI2Cモードになる

6 NC  -
7 INT  -
8 GND GND

 簡易的に、次の接続にしました。

ボードのピン番号 Metro M4 Express AirLift (WiFi)
1 Vdd 3.3
2 SCL SCL
3 SDA SDA
4 SA0  -
5 CS

 -

6 NC  -
7 INT  -
8 GND GND

I2Cscan

 次のプログラムで、デバイスのスレーブ・アドレスを調べます。0x5dでした。

import board
import busio
import time

# Initialize and lock the I2C bus.
i2c = busio.I2C(board.SCL, board.SDA)

while not i2c.try_lock():
pass

while True:
print("I2C addresses found:", [hex(device_address)
for device_address in i2c.scan()])
time.sleep(2)
i2c.unlock()

WHO_AM_I

 ボード購入時に付属している取扱説明書に、WHO_AM_I(0x0f)を読み出し、0xbdが読めれば正常に通信できていると書かれているので実行します。

import board
import busio
import time

i2c = busio.I2C(board.SCL, board.SDA)

while not i2c.try_lock():
pass

i2c.writeto(0x5d, bytes([0x0f]), stop=False)
result = bytearray(1)
i2c.readfrom_into(0x5d, result)
print(result)
i2c.unlock()

 0xbdが読めました。

気圧のデータは3バイト

 1Hzの繰り返しで気圧データを読み出します。電源が入ったのち、パワーダウン・モードになっているので、測定できるモードに変更します。この二つの設定は、「CTRL_REG1」(0x20)に0x90を書き込むことで実現します。
 「PRESS_OUT_XL」(0x28)、「PRESS_OUT_L」(0x29)、「PRESS_OUT_H」(0x2A)で気圧を読み取ります。これらのレジスタはポインタではなさそうなので、0x28から3バイトを読み取ればよいようです。データの並びは逆順です。

  • PRESS_OUT_H 上位7ビット+最上位は符号1ビット
  • PRESS_OUT_L 中位8ビット
  • PRESS_OUT_XL 下位8ビット

 合計24ビットの2の補数形式です。測定値に負の数自体は存在しないと思うので、無視します。

  読み出した3バイトを4096で割るとhPaの値が得られるマニュアルには書かれていますが、変な値になります。

  ControlEverythingCommunity/LPS25HB

にあるサンプル・プログラムでは、

  0x28 | 0x80

の記述があるので、そのようにすると、妥当な値が読み出せました。

import board
import busio
import time

LPS25HB_adr=0x5d

i2c = busio.I2C(board.SCL, board.SDA)

while not i2c.try_lock():
pass

i2c.writeto(LPS25HB_adr, bytearray([0x20,0x90]), stop=False)
time.sleep(1)
i2c.writeto(LPS25HB_adr, bytes([0x28 | 0x80]), stop=False)
result = bytearray(3)
i2c.readfrom_into(LPS25HB_adr, result)
print(result)
press = (result[2]<<16 | result[1]<<8 | result[0]) / 4096.0
print(str(press) + 'hPa')
i2c.unlock()

 実行している様子です。