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)

 動作している様子です。