CircuitPython 10行プログラミング Step3 (7) 気圧センサLPS25HB
気圧センサは従来補正パラメータが多く、それらを読み出し計算をして気圧を求めていました。ここで利用するSTMicroelectronicsのLPS25HBは、補正がICの内部で行われます。ボードは、秋月電子通商から入手しました。電源がつながるとLEDが点灯しますから、消費電力を抑えたいときはLEDの配線を切ります。
●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()
実行している様子です。