CircuitPython 10行プログラミング Step8 (9) BLE streamで温湿度のセントラル

 前回マイコン・ボードSeeed XIAO BLE SenseのI2Cバスに、温湿度センサAHT20を接続しペリフェラルにしました。ここでは、センサの乗っていないSeeed XIAO BLEをセントラルにします。

SensorServiceクラス

 温度と湿度を読み取るstreamのcharacteristics UUIDを用意します。

 次のプログラムをSwitchBot.pyで保存します。


# SPDX-FileCopyrightText: 2020 Mark Raleson
# SPDX-License-Identifier: MIT

from adafruit_ble.uuid import VendorUUID
from adafruit_ble.services import Service
from adafruit_ble.characteristics import Characteristic
from adafruit_ble.characteristics.stream import StreamIn
from adafruit_ble.characteristics.stream import StreamOut


class SensorService(Service):

    uuid = VendorUUID("51ad213f-e568-4e35-84e4-67af89c79ef0")

    sensorsT = StreamOut(
        uuid=VendorUUID("e077bdec-f18b-4944-9e9e-8b3a815162b4"),
        properties=Characteristic.READ,
    )

    sensorsH = StreamOut(
        uuid=VendorUUID("528ff74b-fdb8-444c-9c64-3dd5da4135ae"),
        properties=Characteristic.READ,
    )

    def __init__(self, service=None):
        super().__init__(service=service)
        self.connectable = True

プログラム

 ペリフェラルはテキストで温度と湿度を送っている状態で動いています。

 start_scanで、アドバタイジングしているペリフェラルを見つけ、その中のservice UUIDがSensorService(Service)なのを見つけたらconnectします。

 そのserviceのなかの温度characteristics UUIDなるsensorsT、同様に湿度sensorsHのオブジェクトをreadします。b'26.123'のようなデータが読み取れるのですが、うまく数値部分だけを取り出せなかったので、スライスで無理やり読んでいます。室温付近でないと、おかしな値になります。


# SPDX-FileCopyrightText: 2020 Mark Raleson
# SPDX-License-Identifier: MIT

from SwitchBot import SensorService
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
import time
import struct

ble = BLERadio()
connection = None

while True:
    if not connection:
        print("Scanning")
        for adv in ble.start_scan(ProvideServicesAdvertisement):
            addr = adv.address
            s = ProvideServicesAdvertisement.matches
            #address = str(addr)[9:26]
            #print(address, adv)
            if SensorService in adv.services:
                connection = ble.connect(adv)
                print("Connected")
                break
            print("")
        ble.stop_scan()
        print("stopped scan")
        if connection and connection.connected:
            service = connection[SensorService]
            RT = service.sensorsT
            RH = service.sensorsH
            while connection.connected:
                print("Temp: ", str(RT.read())[2:6], "`C")
                print("Humi: ", str(RH.read())[2:6], "%")
                print("")
                time.sleep(3)

 実行中の様子です。

ペリフェラルを実数にすると

 前回のように、セントラルRSL10 Bluetooth Low Energy Explorerでは、実数をうまく読んでいましたが、streamでは正常な時もありますが、多くは長さが不定のデータを読んできました。

 どうもstreamで実数をreadするのは適していないように思えます。