Raspberry Pi 4 + Python3入門 <STEP1> (7) 7セグメントLED HT16K33 その2 BME280のデータ表示

 QUAD ALPHANUMERICの14 segment LEDは、数字以外にもアルファベットや記号も表示できます。数字もそうですが、アスキ表を見ると、アルファベットも順番に並んでいるので、プログラムでは扱いやすいです。ここでは、小数点の数値を表示します。

小数点の管理

 74HC595を使った表示器では、数値の終わりの桁からそれぞれの表示セグメントのデータを処理していました。したがって、小数点を見つけると、次の数値にドットを追加すれば処理できました。HT16K33 では、数値の先頭の桁から各セグメントを処理します。そのため、まず、小数点の存在を探しておいて、その手前の数値にドットを追加するようにします。

 マイナスの符号は数値の先頭にあるという前提です。見つかれば、表示データを用意し、マイナス符号を取り去り、次の処理に渡します。

 ドットは、

num[lookupNumber] | 0x4000

 14ビット目を'1'にします。ドットが不要なところは何もせずに表示してしていました。テスト・データのときは正常だったのですが、実際に連続して表示すると、必要のない場所にドットが表示されることが起こりました。原因は不明ですが、ドットがないところは強制的に'0'を書き込んで回避しました。

num[lookupNumber] & ~0x4000

 このプログラムでは、ドットが存在しないときの処理は入れていません。

import smbus, time, bme280
i2c = smbus.SMBus(1)
HT18K33_address = 0x70
#         0    1     2     3     4      5      6    7     8     9
num = [0xc3f, 0x6, 0xdb, 0x8f, 0xe6, 0x2069, 0xfd, 0x7, 0xff, 0xef]
minus = 0xc0

i2c.write_byte(HT18K33_address, (0x20 | 0x01))  # system setup
i2c.write_byte(HT18K33_address, (0x80 | 0b00000001))  # dispaly setup blink OFF

def clear():
    i2c.write_i2c_block_data(HT18K33_address, 0x00, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])

def digitData(n):
    nn = list(str(n))
#    print(nn)
    ff = []
    x = 0
    number = 0
    if '-' in str(n):
#        print(minus)
        number = [minus, minus >> 8]
        ff = ff + number
#        print('find minus',number)
        nn = nn[1:]
        n = abs(n)
#        print('new number', nn)
    dotnumber = str(n).index('.')
#    print('find dot index',dotnumber,'length=',len(str(n)))
    for x in range(int(len(str(n)))-3):
#        print(x,n)
        lookupNumber = int(nn[x])
#        print('not dot number', lookupNumber)
        num[lookupNumber] = num[lookupNumber] & ~0x4000
        number = [num[lookupNumber], num[lookupNumber] >> 8]
        ff = ff + number
#        print('not dot', ff)
    # dot number
    lookupNumber = int(nn[dotnumber-1])
#    print('     find dot dotnumber-1=',dotnumber-1,lookupNumber)
    num[lookupNumber] = num[lookupNumber] | 0x4000  # dot
    number = [num[lookupNumber], num[lookupNumber] >> 8]
    ff = ff + number
#    print('     dot', ff)
    # last digit
    lookupNumber = int(nn[dotnumber+1])
#    print('last x=',x,lookupNumber)
    num[lookupNumber] = num[lookupNumber] & ~0x4000
    number = [num[lookupNumber], num[lookupNumber] >> 8]
    ff = ff + number
#    print(ff)
    return ff

def disp14seg(nnnn):
    i2c.write_i2c_block_data(HT18K33_address, 0x00, digitData(nnnn))

# main
clear()

bus = smbus.SMBus(1)
bme280.load_calibration_params(bus, 0x76)

while 1:
    s = bme280.sample(bus,0x76)
    print(s)
    findString = 'temp='
    t = str(s).find(findString)
    temp = str(s)[t+len(findString):t+len(findString)+4]
    print('\ntemperature ',temp, '\n')

    clear()
    disp14seg(temp)
    time.sleep(3.14)

表示部分を分離

 74HC595のときと同様に、LEDの表示部分を分離して、本体のプログラムを見やすくします。ファイル名LED14seg.pyで保存しました。

import smbus, time, bme280
i2c = smbus.SMBus(1)
HT18K33_address = 0x70
#         0    1     2     3     4      5      6    7     8     9
num = [0xc3f, 0x6, 0xdb, 0x8f, 0xe6, 0x2069, 0xfd, 0x7, 0xff, 0xef]
minus = 0xc0

i2c.write_byte(HT18K33_address, (0x20 | 0x01))  # system setup
i2c.write_byte(HT18K33_address, (0x80 | 0b00000001))  # dispaly setup blink OFF

def clear():
    i2c.write_i2c_block_data(HT18K33_address, 0x00, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])

def digitData(n):
    nn = list(str(n))
    ff = []
    x = 0
    number = 0
    if '-' in str(n):
        number = [minus, minus >> 8]
        ff = ff + number
        nn = nn[1:]
        n = abs(n)
    dotnumber = str(n).index('.')
    for x in range(len(str(n))-3):
        lookupNumber = int(nn[x])
        num[lookupNumber] = num[lookupNumber] & ~0x4000
        number = [num[lookupNumber], num[lookupNumber] >> 8]
        ff = ff + number
    # dot number
    lookupNumber = int(nn[dotnumber-1])
    num[lookupNumber] = num[lookupNumber] | 0x4000  # dot
    number = [num[lookupNumber], num[lookupNumber] >> 8]
    ff = ff + number
    # last digit
    lookupNumber = int(nn[dotnumber+1])
    num[lookupNumber] = num[lookupNumber] & ~0x4000
    number = [num[lookupNumber], num[lookupNumber] >> 8]
    ff = ff + number
    return ff

def disp14seg(nnnn):
    i2c.write_i2c_block_data(HT18K33_address, 0x00, digitData(nnnn))

BME280のデータを表示

 ライブラリRPi.bme280を利用してセンサBME280の温度、気圧、湿度のデータを取得し、LEDに表示します。上記の表示部分は、

import LED14seg as LED14

で利用します。温度と湿度は4桁、気圧は6桁の測定結果を切り出します。

import smbus, time, bme280
import LED14seg as LED14

bus = smbus.SMBus(1)
bme280.load_calibration_params(bus, 0x76)

while 1:
    s = bme280.sample(bus,0x76)
    print(s)
findString = 'temp=' t = str(s).find(findString) temp = str(s)[t+len(findString):t+len(findString)+4] print('temperature ',temp) LED14.clear() LED14.disp14seg(temp) time.sleep(3.14) findString = 'pressure=' t = str(s).find(findString) temp = str(s)[t+len(findString):t+len(findString)+6] print('pressure ', temp) LED14.clear() LED14.disp14seg(temp) time.sleep(3.14) findString = 'humidity=' t = str(s).find(findString) temp = str(s)[t+len(findString):t+len(findString)+4] print('humidity ', temp) LED14.clear() LED14.disp14seg(temp) time.sleep(3.14)

 実行例です。

(※) 本Webのプログラム中、インデントなどのスペースもしくは改行は、通常のプログラム内ではごみ文字になるので、コピペした後、エディタでスペース文字などを入れなおしてください。