初めてのRaspberry Pi BLEプログラミング (4) BME280①温度
前回、CPUの温度を送るペリフェラルを作りました。ここからは、MEMSセンサのBME280をつないで実験を進めます。BME280の接続は、次の記事を参照してください。
初めてのBLE (11) Raspberry Piでペリフェラル③BME280に対応
次に、AdafruitのBME280のライブラリをインストールします。
sudo pip3 install adafruit-circuitpython-bme280
プログラムを作ります。動作確認なので温度だけを読み出します。
import board import busio import adafruit_bme280 i2c = busio.I2C(board.SCL, board.SDA) bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76) print("\nTemperature: %0.1f C" % bme280.temperature)
実行結果です。問題なく動いているようです。
●修正;BatteryLevelCharacteristic.py
前回Characteristic(キャラ)を記述したBatteryLevelCharacteristic.pyでは、CPU温度を送るように記述しました。これを上記のBME280の温度に変更します。また、ファイル名をBME280Characteristic.pyに変更します。
from pybleno import * import array import board import busio import adafruit_bme280 class BME280Characteristic(Characteristic): def __init__(self): Characteristic.__init__(self, { 'uuid': '12345678-1234-5678-1234-56789abcdef7', 'properties': ['read'], 'value': None }) def onReadRequest(self, offset, callback): i2c = busio.I2C(board.SCL, board.SDA) bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, 0x76) callback(Characteristic.RESULT_SUCCESS, array.array('B', [int(bme280.temperature)]))
UUIDは、独自の文字列です。
●修正;BatteryService.py
Serviceを記述したBatteryService.pyのファイル名をBME280Service.pyに変更し、内容は、上記のキャラを指定します。UUIDは、独自の文字列です。
from pybleno import * from BME280Characteristic import * class BME280Service(BlenoPrimaryService): def __init__(self): BlenoPrimaryService.__init__(self, { 'uuid': '12345678-1234-5678-1234-56789abcdef0', 'characteristics': [ BME280Characteristic() ]})
●修正;main.py
14行目bleno.startAdvertising('BME280-t', で、Local Nameを変更しました。あと、呼び出すサービスの名前を修正しました。
from pybleno import * import sys import signal from BME280Service import * bleno = Bleno() primaryService = BME280Service(); def onStateChange(state): print('on -> stateChange: ' + state); if (state == 'poweredOn'): bleno.startAdvertising('BME280-t', [primaryService.uuid]); else: bleno.stopAdvertising(); bleno.on('stateChange', onStateChange) def onAdvertisingStart(error): print('on -> advertisingStart: ' + ('error ' + error if error else 'success')); if not error: def on_setServiceError(error): print('setServices: %s' % ('error ' + error if error else 'success')) bleno.setServices([ primaryService ], on_setServiceError) bleno.on('advertisingStart', onAdvertisingStart) bleno.start() print ('Hit to disconnect') if (sys.version_info > (3, 0)): input() else: raw_input() bleno.stopAdvertising() bleno.disconnect() print ('terminated.') sys.exit(1)
実行します。温度(整数)が読み取れました。
今度は実数で送ります。BME280Characteristic.pyの最後の行で、温度をint()で整数にしていたところをstruct.pack('>f'で、32ビットの浮動小数点形式に変換します。0x41d03b9aのようなバイト列になっているので、list()で[0x41, 0xd0, 0x3b, 0x9a]のようにリスト形式にします。これは、arrayの配列と同じなので、1byteが四つになって送られます。
callback(Characteristic.RESULT_SUCCESS, array.array('B', list(struct.pack('>f', (bme280.temperature))) ))
実行結果です。0x410xd00x3b0x9a=0x41d03b9aは、26.0291です。