CircuitPython 10行プログラミング Step7 (4) LPS22HBと7セグメントLEDの表示
Trinket M0マイコン・ボードとCircuitPythonを使って、I2CバスにつながるセンサBMP280を利用します。測定値は7セグメントLEDに表示します。
実験の途中でメモリが足りなくなったので、BMP280ではなくLPS22HBに変更しました。
●CircuitPythonは7.1.0
執筆時点でCircuitPythonは7.xになっています。7.1.0をダウンロードします。ダウンロードしたadafruit-circuitpython-trinket_m0-ja-7.1.0.uf2は、Trinket M0マイコン・ボードのリセットボタンをダブルクリックしてドライブを表示し、そこへコピーします。
https://circuitpython.org/board/trinket_m0/
サンプルやlibファイルは7.x用をダウンロードし、PCに保存します。Trinket M0マイコン・ボードのlibの容量は小さいので、必要なファイルだけしか保存できません。
●7セグメントLED
使用する7セグメントLEDのコントローラはmax7219です。CircuitePythonのライブラリがありますが、adafruit-circuitpython-bundle-7.x-mpy-20210921には入っていませんでした。adafruit-circuitpython-max7219-7.x-mpy-1.5.0(https://github.com/adafruit/Adafruit_CircuitPython_MAX7219)をダウンロードし、adafruit_max7219フォルダごとTrinket M0マイコン・ボードのlibフォルダにコピーします。
なお、実行時には下記のファイルも必要なので、libにコピーしておきます。
- adafruit_bus_deviceフォルダ
- adafruit_framebuf.mpyファイル
max7219は、ドット・マトリクスと、7セグメントLEDの両方に対応しています。
●接続
Trinket M0マイコン・ボード | 7セグメントLED(max7219) |
---|---|
GND | GND |
MOSI Tx | Din |
SCK Rx | CLK |
3.3V | Vcc |
D1 | CS |
●プログラム
from adafruit_max7219 import bcddigits
from board import TX, RX, D1
import busio
import digitalio
clk = RX
mosi = TX
cs = digitalio.DigitalInOut(D1)
spi = busio.SPI(clk, MOSI=mosi)
display = bcddigits.BCDDigits(spi, cs, nDigits=8)
display.brightness(1)
display.clear_all()
display.show_str(0, "1012")
display.show_str(4, " 25.2")
display.show()
●気圧センサBMP280のおもなスペック
- 電源電圧;1.71~3.6V
- 温度測定範囲;-40~+85℃、分解能0.01℃
- 気圧測定範囲;300~1100hPa、確度±1hPa、分解能0.12hPa
- インターフェース;SPI(データ転送速度最大10MHz)、I2C(データ転送速度最大3.4MHz)
- I2Cアドレス;0x76、0x77どちらかを選択
●気圧センサBMP280の接続
I2Cバスで接続します。
I2Cバスで利用するためのCSBとSDO端子は基板上で配線されているので、マイコン・ボードとの接続はありません。
Trinket M0マイコン・ボード | BMP280ボード |
---|---|
GND | GND |
3.3V | Vcc |
D2 SCL | SCL |
D0 SDA | SDA |
配線しない(3.3Vへ10kでプルアップされている) |
CSB |
配線しない(GNDへ10kでプルダウンされている) | SDO |
●BMP280の読み出しプログラム
examplesに入っていたBMP280のデータ読み出しプログラムです。I2Cアドレスは0x76用に修正しています。
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
"""Simpletest Example that shows how to get temperature,
pressure, and altitude readings from a BMP280"""
import time
import board
# import digitalio # For use with SPI
import adafruit_bmp280
# Create sensor object, communicating over the board's default I2C bus
i2c = board.I2C() # uses board.SCL and board.SDA
bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c,0x76)
# OR Create sensor object, communicating over the board's default SPI bus
# spi = board.SPI()
# bmp_cs = digitalio.DigitalInOut(board.D10)
# bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)
# change this to match the location's pressure (hPa) at sea level
bmp280.sea_level_pressure = 1013.25
while True:
print("\nTemperature: %0.1f C" % bmp280.temperature)
print("Pressure: %0.1f hPa" % bmp280.pressure)
print("Altitude = %0.2f meters" % bmp280.altitude)
time.sleep(2)
必要な部分を抜き出し、最初のLEDの表示プログラムと合体します。
>>>中断<<<
合体すると、どうもメモリが足りないというエラー・メッセージが出ます。BMP280のライブラリを使わない形でプログラムを作ると、大変な行数になります。そこで、別の気圧センサLPS22HBを利用します。
●気圧センサLPS22HBのおもなスペック
- 動作電圧 1.7~3.6V
- 測定範囲 260~1260hPa
- 気圧分解能 24ビット
- 温度分解能 16ビット
- インターフェース I2CとSPI
●気圧センサLPS22HBの接続
I2Cバスで接続します。
libの中身です。
●プログラム
from adafruit_max7219 import bcddigits
from board import TX, RX, D1
import time
import board
import busio
import digitalio
clk = RX
mosi = TX
cs = digitalio.DigitalInOut(D1)
spi = busio.SPI(clk, MOSI=mosi)
display = bcddigits.BCDDigits(spi, cs, nDigits=8)
display.brightness(1)
display.clear_all()
LPS22_adr=0x5d
i2c = board.I2C()
while not i2c.try_lock():
pass
i2c.writeto(LPS22_adr, bytearray([0x11,0x04])) # reset
time.sleep(1)
i2c.writeto(LPS22_adr, bytearray([0x10,0x10]))
i2c.writeto(LPS22_adr, bytearray([0x0f]))
resultW = bytearray(1)
#i2c.readfrom_into(LPS22_adr, resultW)
#print(resultW) # 0xb1
while 1:
i2c.writeto(LPS22_adr, bytearray([0x11,0x11]))
i2c.writeto(LPS22_adr, bytes([0x28 | 0x80]))
resultP = bytearray(3)
i2c.readfrom_into(LPS22_adr, resultP)
#print(resultP)
press = (resultP[2]<<16 | resultP[1]<<8 | resultP[0]) / 4096.0
#print(str(press) + 'hPa')
i2c.writeto(LPS22_adr, bytes([0x2b | 0x80]))
resultT = bytearray(2)
i2c.readfrom_into(LPS22_adr, resultT)
#print(resultT)
temp = (resultT[1]<<8 | resultT[0]) / 100.0
#print(str(temp) + '`C')
display.clear_all()
display.show_str(0, str(int(press)))
display.show_str(5, str(temp))
display.show()
time.sleep(2)
動作している様子です。