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のプログラム中、インデントなどのスペースもしくは改行は、通常のプログラム内ではごみ文字になるので、コピペした後、エディタでスペース文字などを入れなおしてください。