shin_med_kyoto
@shin_med_kyoto

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【python】miaomiao (Smart Reader for Freestyle Libre) とのBLE 通信において、 「bytearraey(b'o')」

解決したいこと

miaomiao (Smart Reader for Freestyle Libre) という、リブレセンサーの値を拾うデバイスがあります。そのデバイスはBLE通信により、値をアプリに送信します。
pycharmにて、BLE通信を行う、python programを書きました。
uuidはNordic UART TX の特性uuid"6e400003-b5a3-f393-e0a9-e50e24dcca9e" を扱いました。

結果として、Connected to D8:DE:61:CC:0B:B4
Value for 6e400003-b5a3-f393-e0a9-e50e24dcca9e: bytearray(b'o')
となりました。
'o'以外の情報を受け取らないので、miaomiaoによるデータが送信されていないのかと感じました。

初心者で、質問の方法や用語の使い方等が不適切なども教えて欲しいです。

発生している問題・エラー

Connected to D8:DE:61:CC:0B:B4
Value for 6e400003-b5a3-f393-e0a9-e50e24dcca9e: bytearray(b'o')

python

async def read_characteristic(address, char_uuid):
    async with BleakClient(address) as client:
        if await client.is_connected():
            print(f"Connected to {address}")
            try:
                value = await client.read_gatt_char(char_uuid)
                print(f"Value for {char_uuid}: {value}")
            except Exception as e:
                print(f"Error: {e}")
        else:
            print(f"Failed to connect to {address}")

if __name__ == "__main__":
    address = "D8:DE:61:CC:0B:B4"  # BLE address
    char_uuid = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"  #  UUID of Nordic UART TX

    loop = asyncio.get_event_loop()
    loop.run_until_complete(read_characteristic(address, char_uuid))

自分で試したこと

以下の原因を考えました。

1.デバイスがデータを送信していない
→bytearray(b'o') である以上、受け取っているのではないかと思いました。
しかし、血糖値0は変だと思いました。

2:選択したUUIDが不適切: 使用しているUUIDが、期待するデータを提供する特性のものでない可能性
→uuidのプロパティを調べたところ、
6e400001-b5a3-f393-e0a9-e50e24dcca9e: Nordic UART Service:
["['write-without-response', 'write'],
6e400002-b5a3-f393-e0a9-e50e24dcca9e",
"['notify'],6e400003-b5a3-f393-e0a9-e50e24dcca9e"]

3.待機時間が不足: asyncio.sleep(10)は、通知を待つために10秒間待機している、この時間が短すぎる可能性→10分に設定してみたが、効果なし。

0

2Answer

Nordic純正のスマホアプリで受信してみたらどうでしょうか。
このアプリで受信できるならば、Pythonプログラムの問題ですし、
このアプリでも受信できないなら、デバイス(miaomiao)側の問題だと切り分けができます。

2Like

Comments

  1. @shin_med_kyoto

    Questioner

    ありがとうございます!試してみます!

  2. @shin_med_kyoto

    Questioner

    試してみた所、
    nRF connect では
    Updated Value of Characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E to F080 0F01 81E6 F080 0901 C80C F180 FE00 C808 F180 F900 C800 F180 F800 C8FC F080 F800 C804 F180 FA00 C804 F180 5101 C828 F080 4C01 C888 F080 4D01 C8AC F080 4E01 C8C0 F080 4F01 C8D0 F080 7B35 0000 F22C 0004 BC0E 5351 1407 9680 5A00 EDA6 148C 1AC8 0460 F969 29A2 0800 0445 23.

    という値になりました。デバイスに問題はなさそうです....
    やっぱりプログラミングコードなんですかね。

  3. 専用のアプリが用意されているようですが、これを利用されてはどうでしょうか。

  4. notifyキャラクタリスティックで受信しているので、正しいと思いますが、

    Updated Value of Characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E to F080 0F01 81E6 F080 0901 C80C F180 FE00 C808 F180 F900 C800 F180 F800 C8FC F080 F800 C804 F180 FA00 C804 F180 5101 C828 F080 4C01 C888 F080 4D01 C8AC F080 4E01 C8C0 F080 4F01 C8D0 F080 7B35 0000 F22C 0004 BC0E 5351 1407 9680 5A00 EDA6 148C 1AC8 0460 F969 29A2 0800 0445 23.

    value = await client.read_gatt_char(char_uuid)で、1バイトしか受信していないのが変です。
    0x67g とか 0x6Foが見当たりませんが、どこの1バイトを受信しているのでしょうかね?

  5. @shin_med_kyoto

    Questioner

    コメントありがとうございます!!
    そうなのですよね....1byteしか受信できておらず....
    受信したグルコース濃度を自作数理モデルの入力値に使いたくて...
    なので、スマホでしか扱えない公式アプリ以外の方法を模索しているんです。。。

  6. 原因がわかりました。

    notifyキャラクタリスティックは、read_gatt_char()ではなくて、start_notify()で受信する必要がありました。下記コードで受信できると思います。

    import asyncio
    from bleak import BleakClient
    
    def notification_handler(sender, data: bytearray):
        print(data)
    
    async def run(address, char_uuid, loop):
        async with BleakClient(address, loop=loop) as client:
            if await client.is_connected():
                print(f"Connected to {address}")
                await client.start_notify(char_uuid, notification_handler)
    
                while True:
                    await asyncio.sleep(1)
            else:
                print(f"Failed to connect to {address}")
    
    
    if __name__ == "__main__":
        address = "D8:DE:61:CC:0B:B4"  # BLE address
        char_uuid = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"  #  UUID of Nordic UART TX
        loop = asyncio.get_event_loop()
        loop.run_until_complete(run(address, char_uuid, loop))
    
  7. @shin_med_kyoto

    Questioner

    ありがとうございます!試してみます!

    notifyキャラクタリスティックは、read_gatt_char()ではなくて、start_notify()で受信する必要がありました。

    ↑は、どこのwebサイトで調べたか、教えていただくことは可能ですか?

  8. どこのwebサイトで調べたか、教えていただくことは可能ですか?

    miaomiaoデバイスを所有していないので、手持ちのマイコンでBLEペリフェラルを実装して、質問に掲示されたコードをMacで実行させたところ、read_gatt_char()でエラーとなったのがきっかけで、

    bleak notifyのキーワードでググって、いくつかのサイトのコードを眺めていて、気が付きました。

    bleakは初めてだったので、グーグル先生の力を借りました。

  9. @shin_med_kyoto

    Questioner

    すみません返信遅くなりました!!
    ありがとうございます!!

  10. 上手く受信できましたか?
    もし解決であれば、当Q&Aをクローズしてください。

  11. @shin_med_kyoto

    Questioner

    すみません。。。
    やっぱりうまくいかなかったです。
    Connected to D8:DE:61:CC:0B:B4
    までは現れたのですが、そこからずっと値を取得しないです。。。

  12. やっぱりうまくいかなかったです。

    動作検証済みのコードを貼ったのですが、それは変ですね。
    @shin_med_kyoto さんの現在のコードを全部貼ってもらえれば確認します。

  13. @shin_med_kyoto

    Questioner

    解決しました!!!
    どうやらtomatoアプリ等でmiaomiaoをバインドしないと、miaomiaoがデータを送信しないようです。nRFconnectの時も、miaomiaoをバインドしていたからのようです!

    沢山考えていただきありがとうございました!!

  14. @shin_med_kyoto

    Questioner

    動作検証済みのコードを貼ったのですが、それは変ですね。

    →おそらくmiaomiaoデバイス特有の操作だったのかな、と思います。
    実際、一度バインド(スマホアプリのtomatoより)した後、スマホを別室におき、pycharmにてpython programを動かしたところ、上手くデータを拾うことができました。

asciiコード表でb'o'(小文字のオー)は「111」ですが、血糖値111mg/dLは返値としてはいかがでしょうか。

1Like

Comments

  1. @shin_med_kyoto

    Questioner

    ありがとうございます!試してみます!

  2. @shin_med_kyoto

    Questioner

    別濃度のグルコース溶液(400ng/dL)で試してみたところ、bytearray(b'g') :103 となりました。グルコース濃度を直接表しているわけではなさそうです.....
    @nak435 さんがアドバイスしてくださったnRFコネクトの表示値とも違うことから、何か異なるデータを受信しているのかもしれないです....

Your answer might help someone💌