センサ・シリーズ 温湿度①SHT31 その5 BLEセントラル
SHT31で測定した温湿度をBLEで通信できるようにしました。前回ラズパイはサーバの立場のペリフェラル動作です。ここでは、Raspberry Pi Zero Wでセントラルのプログラムを動かし、14セグメントLEDに温湿度を表示します。
使用環境
|
●ペリフェラルはSHT31-SMART-GADGET
湿度センサSHT31を製造しているSENSIRIONから、BLEのデモ・ボードが販売されています。
Digi-KeyやMouserで購入できますが、送料を考慮し、マルツで入手しました。【SHT31-SMART-GADGET】Sensirion 温度 / 湿度センサ(3,140円)BLEモジュールには技適のマークが印刷されています。
データシートは同社のダウンロードセンターから入手できます。UUIDの構成は、GitHubにありました。
●bluepyのインストール
ここでは、セントラルのプログラムを書くために、bluepyライブラリをインストールします。このBLEライブラリは、pythonでセントラルのプログラムだけが書けます。
ラズパイ4は最新の状態にしておきます。次の2点をインストールします。
$ sudo apt-get install python3-pip libglib2.0-dev $ sudo pip3 install bluepy |
GitHubにあるサンプルblescan.pyをエディタに読み込み、scan.pyの名前で保存します。
$ sudo python3 scan.py |
で、アドバタイジングしているBLEペリフェラルを探します。見つけてきました。Device Addrをメモしておきます。
上記のscan.pyでデバイスのアドレスがわかりました。なので、アドレスで直接コネクトします。見つからなかったときのエラー処理は記述していません。
●14セグメントLED
次の記事で、コントローラHT16K33を搭載した14セグメントLEDを利用しています。
Raspberry Pi 4 + Python3入門 <STEP1> (6) 7セグメントLED HT16K33 その1 QUAD ALPHANUMERIC 4桁
Raspberry Pi 4 + Python3入門 <STEP1> (7) 7セグメントLED HT16K33 その2 BME280のデータ表示
「Raspberry Pi ZERO用ユニバーサル基板」と「ピンソケット (メス) 2×20 (40P)」は秋月電子通商から、「0.54" 4 bit Digital LED Display Module I2C Interface For 14 Segments」はebayで、ラズパイ「Raspberry Pi Zero WH」はスイッチサイエンスから入手しました。
表示部分をライブラリにしました。LED14seg2.py
import smbus, time
i2c = smbus.SMBus(1)
HT18K33_address = 0x70
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))
●測定と表示
Device Addrで接続します。湿度と温度のそれぞれのキャラUUIDでインスタンスを作り、readした値をLEDに表示しました。
SHT31-SMART-GADGETから送られてくるデータは浮動小数点形式の4バイト(バイト列)です。struct.unpack()で実数に戻します。
from bluepy import btle
import struct
import smbus, time
import LED14seg2 as LED14
bus = smbus.SMBus(1)
humi_Service_UUID = "00001234-b38d-4985-720e-0f993a68ee41"
humi_Characteristic_UUID = "00001235-b38d-4985-720e-0f993a68ee41"
temp_Service_UUID = "00002234-b38d-4985-720e-0f993a68ee41"
temp_Characteristic_UUID = "00002235-b38d-4985-720e-0f993a68ee41"
deviceAddr = "E1:25:47:F0:93:2C"
readHumi = []
readTemp = []
peri = btle.Peripheral()
peri.connect(deviceAddr, btle.ADDR_TYPE_RANDOM)
print('connect')
humiInformation = peri.getCharacteristics(uuid=humi_Characteristic_UUID)[0]
tempInformation = peri.getCharacteristics(uuid=temp_Characteristic_UUID)[0]
while 1:
readHumi = humiInformation.read()
humi = struct.unpack('<f', readHumi)[0]
readTemp = tempInformation.read()
temp = struct.unpack('<f', readTemp)[0]
s = 'temp=' + str(round(temp,1)) + ', humidity=' + str(round(humi,1))
print(s)
LED14.clear()
LED14.disp14seg(str(round(temp,1)))
time.sleep(3.14)
LED14.clear()
LED14.disp14seg(str(round(humi,1)))
time.sleep(3.14)
peri.disconnect()
実行中の様子です。この14セグメントLEDは、最初の2桁が赤色で、残りが緑色をしています。