CO2センサを使う⑥Windows10でBLEセントラル

 Windows10(21H1)をセントラルにし、Arduino Nano RP2040 Connectのペリフェラルにつなぎます。Pythonのbleakライブラリを利用します。執筆時点で、0.12.0 (2021-06-19)でした。

ライブラリのインストール

 コマンドプロンプトを立ち上げます。

pip3 install bleak

動作確認scan

 Scan/Discoverのページにある、


import asyncio
from bleak import BleakScanner

async def run():
    devices = await BleakScanner.discover()
    for d in devices:
        print(d)

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

をscan.pyで保存します。実行すると、RP2060ボードが見えます。アドレスを保存します。

C:\Users\xxxx\Desktop\works>python3 scan.py
4B:AB:4F:67:0C:49: Microsoft (b'\x01\t \x02sz\x878\x8cS\xd1\xd0k\xf1\x10B\xdc\xd4\xf9\x02\xbc\xb8\x92\x9d
\xbe\t\x7f')
84:CC:A8:2E:1F:5E: RP2060_SCD30_float
D6:D3:6E:EF:4B:A2: Nordic Semiconductor ASA (b'\xd6\xd3n\xefK\xa2')

プログラム

 アドレスの一致でデバイスを見つけます。送られてくるIEEE-754の4桁のバイト・アレイは、struct.unpack('<f',で実数の戻します。


import struct
import asyncio
from bleak import BleakClient

address = "84:CC:A8:2E:1F:5E"
CO2_UUID = "F000AA31-0451-4000-B000-000000000000"
Temperature_UUID = "F000AA32-0451-4000-B000-000000000000"
Humidity_UUID = "F000AA33-0451-4000-B000-000000000000"

async def run(address):
    async with BleakClient(address) as client:
        data_CO2 = await client.read_gatt_char(CO2_UUID)
        data_Temperature = await client.read_gatt_char(Temperature_UUID)
        data_Humidity = await client.read_gatt_char(Humidity_UUID)
        
        CO2 = data_CO2[0:]
        Temperature = data_Temperature[0:]
        Humidity = data_Humidity[0:]
        
        CO2 = struct.unpack('<f', CO2)[0]
        Temperature = struct.unpack('<f', Temperature)[0]
        Humidity = struct.unpack('<f', Humidity)[0]
        
        print("{0:.2f}ppm  {1:.1f}`C  {2:d}%".format(CO2, Temperature, int(Humidity)))
        
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address))

 実行結果です。

複数回測定してグラフを描く

 グラフ用のライブラリをインストールします。

pip3 install matplotlib


import struct
import asyncio
from bleak import BleakClient
import time
import matplotlib.pyplot as plt

address = "84:CC:A8:2E:1F:5E"
CO2_UUID = "F000AA31-0451-4000-B000-000000000000"
Temperature_UUID = "F000AA32-0451-4000-B000-000000000000"
Humidity_UUID = "F000AA33-0451-4000-B000-000000000000"

async def run(address):
    async with BleakClient(address) as client:
        count = 20
        CO2_g=[]
        Temperature_g=[]
        Humidity_g=[]
        x_g=[]
        
        for x in range(1,count):
            data_CO2 = await client.read_gatt_char(CO2_UUID)
            data_Temperature = await client.read_gatt_char(Temperature_UUID)
            data_Humidity = await client.read_gatt_char(Humidity_UUID)
        
            CO2 = data_CO2[0:]
            Temperature = data_Temperature[0:]
            Humidity = data_Humidity[0:]
        
            CO2 = struct.unpack('<f', CO2)[0]
            Temperature = struct.unpack('<f', Temperature)[0]
            Humidity = struct.unpack('<f', Humidity)[0]
        
            print("{0:.2f}ppm  {1:.1f}`C  {2:d}%".format(CO2, Temperature, int(Humidity)))
        
            CO2_g.append(CO2)
            Temperature_g.append(Temperature)
            Humidity_g.append(Humidity)
            x_g.append(x)
            
            time.sleep(0.2)

        plt.plot(x_g, CO2_g, label="CO2")
        plt.xlabel("time")
        plt.ylabel("CO2 [ppm]")
        plt.grid()
        plt.plot(x_g, Temperature_g, marker = "v", color = "red", label="Temperature")
        plt.plot(x_g, Humidity_g, marker = "o", color = "green", label="Humidity")
        plt.show()
        
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address))

 実行結果です。

examples/service_explorer.py

 サンプルservice_explorer.pyを動かしました。Characteristic およびそのDescriptionも取得できています。

Connected: True
[Service] 00001800-0000-1000-8000-00805f9b34fb (Handle: 1): Generic Access Profile
[Characteristic] 00002a00-0000-1000-8000-00805f9b34fb (Handle: 2): Device Name (read), Value: b'RP2060_CO2_BLE'
[Characteristic] 00002a01-0000-1000-8000-00805f9b34fb (Handle: 4): Appearance (read), Value: b'\x00\x00'
[Service] 00001801-0000-1000-8000-00805f9b34fb (Handle: 6): Generic Attribute Profile
[Characteristic] 00002a05-0000-1000-8000-00805f9b34fb (Handle: 7): Service Changed (indicate), Value: None
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 9): Client Characteristic Configuration) | Value: b'\x02\x00'
[Service] f000aa30-0451-4000-b000-000000000000 (Handle: 10): Unknown
[Characteristic] f000aa31-0451-4000-b000-000000000000 (Handle: 11): Unknown (read,notify), Value:b'\xcf\x88\x08D'
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 13): Client Characteristic Configuration) | Value: b'\x00\x00'
[Descriptor] 00002901-0000-1000-8000-00805f9b34fb (Handle: 14): Characteristic User Description) | Value: b'CO2;ppm IEEE-754 format'
[Characteristic] f000aa32-0451-4000-b000-000000000000 (Handle: 15): Unknown (read,notify), Value:b'\xe0L\xe8A'
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 17): Client Characteristic Configuration) | Value: b'\x00\x00'
[Descriptor] 00002901-0000-1000-8000-00805f9b34fb (Handle: 18): Characteristic User Description) | Value: b'\xe6\xb8\xa9\xe5\xba\xa6;`C'
[Characteristic] f000aa33-0451-4000-b000-000000000000 (Handle: 19): Unknown (read,notify), Value:b'\xa0M_B'
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 21): Client Characteristic Configuration) | Value: b'\x00\x00'
[Descriptor] 00002901-0000-1000-8000-00805f9b34fb (Handle: 22): Characteristic User Description) | Value: b'\xe6\xb9\xbf\xe5\xba\xa6;%'

前へ

CO2センサを使う⑤nano 33 BLE senseでBLEセントラル

次へ

CO2センサを使う⑦AdafruitのSCD-30ボードをESP32につなぐ