CircuitPython 10行プログラミング Step8 (8) BLE streamで温湿度のペリフェラル

 マイコン・ボードSeeed XIAO BLE SenseのI2Cバスに、温湿度センサAHT20を接続します。そしてペリフェラルにします。

AHT20のおもなスペック

 10kΩのプルアップ抵抗が実装されています。

 データシート

  • 電源電圧  2.0~5.5V
  • 湿度 確度±2%RH、分解能0.024%RH
  • 温度 確度±0.3℃、分解能0.01℃
  • インターフェース I2C(0~400kHz)
  • スレーブ・アドレス 0x38(固定)

接続

I2Cスキャンでアドレスを確認

 I2Cバスは、4番(A4 D4;SDA)端子と5番(A5 D5;SCL)端子です。


from board import *
from busio import I2C
import busio
import digitalio
import board
from adafruit_lsm6ds.lsm6ds3trc import LSM6DS3TRC
import time

imupwr = digitalio.DigitalInOut(board.IMU_PWR)
imupwr.direction = digitalio.Direction.OUTPUT
imupwr.value = True
time.sleep(0.1)
#i2c = busio.I2C(board.IMU_SCL, board.IMU_SDA)
i2c = I2C(board.SCL,board.SDA)

while not i2c.try_lock():
    pass

print([hex(i) for i in i2c.scan()])
i2c.deinit()

 i2c = I2C(board.SCL,board.SDA)を有効にすると、外部につながったI2Cデバイスを探してきます。

 実行すると、0x38に見つけました。

AHT20のデータを読み出す

 CIRCUITPYドライブのlibへ、ダウンロードしたファイルの中のlibに入っているライブラリadafruit_ahtx0.mpyをコピーします。

 examplesにはいっているプログラムahtx0_simpletest.pyをcode.pyにコピーしで保存します。実行中の様子です。

BLEのプログラムと合体

 streamを使ってプログラムを作ります。今回、センサの値は二つあるので、SensorServiceクラスで温度用と湿度用の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 | Characteristic.NOTIFY,
    )

    sensorsH = StreamOut(
        uuid=VendorUUID("528ff74b-fdb8-444c-9c64-3dd5da4135ae"),
properties=Characteristic.READ | Characteristic.NOTIFY, ) def __init__(self, service=None): super().__init__(service=service) self.connectable = True

 次は、code.pyのプログラムです。文字で送る事例と実数(IEEE754 単精度浮動小数点数の形式:binary32)の2通りがあります。


# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

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

# Create BLE radio, custom service, and advertisement.
ble = BLERadio()
sService = SensorService()
advertisement = ProvideServicesAdvertisement(sService)
ble.name = "AHT20 Humidity&Temperature"

# Create sensor object, communicating over the board's default I2C bus
i2c = board.I2C()  # uses board.SCL and board.SDA
sensor = adafruit_ahtx0.AHTx0(i2c)

while True:
    print("Advertise services")
    ble.stop_advertising()  # you need to do this to stop any persistent old advertisement
    ble.start_advertising(advertisement)

    print("Waiting for connection...")
    while not ble.connected:
        pass
    ble.stop_advertising()
    print("Connected")
    while ble.connected:
        print("\nTemperature: %0.1f C" % sensor.temperature)
        print("Humidity: %0.1f %%" % sensor.relative_humidity)
        sendTemperature = sService.sensorsT
        #sendTemperature.write(str(sensor.temperature))  # string
        sendTemperature.write(struct.pack('>f', sensor.temperature))  # float
        sendHumidity = sService.sensorsH
        #sendHumidity.write(str(sensor.relative_humidity))  # string
        sendHumidity.write(struct.pack('>f', sensor.relative_humidity))  # float
        time.sleep(3)

    print("Disconnected")

 sendTemperature.write(struct.pack('>f', sensor.temperature)) # floatを生かしたときのセントラル側の受信画面です。

 実数への変換はこちらのサイトで行っています。

 

  sendTemperature.write(str(sensor.temperature)) # stringを生かしたときです。

 Muの実行中の画面です。