Reading and writing vendor-specific BLE characteristic values

52 views Asked by At

I have tried several tools to programmatically read and write BLE characteristic values. I am having difficulty with all that I have tried.

I used the Python bleak libary on a Raspberry Pi 4B running Raspbian Debian GNU/Linux 11 (bullseye), using the internal BLE chip. Here's my code:

import asyncio
from bleak import BleakScanner, BleakClient
import sys


async def main():
    #devices = await BleakScanner.discover(timeout=20)
    d = await BleakScanner.find_device_by_address("XX:0D:XX:F1:XX:FC", timeout=20)            
    try:
        if d.address == "XX:0D:XX:F1:XX:FC":
            async with BleakClient(d, timeout=10) as client:
                res = await client.pair(protection_level=None)
                print(res)

                x = client.is_connected
                print("Connected: {0}".format(x))

                thisCharacteristic = svc.get_characteristic("XXXXXXXX-1234-XXXX-1234-56789XXXXXX")
                # frame = bytearray()
                # frame.append(0x04)


                value = bytes(await client.read_gatt_char(thisCharacteristic))

                frame = bytearray()
                frame.append(value[0] + 1)

                await client.write_gatt_char(thisCharacteristic, frame)

                for service in client.services:
                    print("[Service] {0}: {1}".format(service.uuid, service.description))
                    for char in service.characteristics:
                        if "read" in char.properties:
                            try:
                                value = bytes(await client.read_gatt_char(char.uuid))
                            except Exception as e:
                                value = str(e).encode()
                        else:
                            value = None
                        print(
                            "\t[Characteristic] {0}: ({1}) | Name: {2}, Value: {3} ".format(
                                char.uuid, ",".join(char.properties), char.description, value))
                await client.disconnect()
                await client.unpair()

    except:
        e = sys.exc_info()[0]
        print(e)

        
if __name__ == "__main__":
    asyncio.run(main())

This code runs well sometimes, verifying that I can write a value to a characteristic and read values of characterisitcs. Sometimes it has an exception while trying to connect (async with BleakClient(d, timeout=10) as client:). The exception is <class 'bleak.exc.BleakDBusError'>. After this exception occurs, I can sometimes execute the code successfully (no exception), but other times it has the exception every execution until I reboot the Raspberry Pi.

As this communication process is to occur in a manufacturing environment, I am concerned about this solution.

Prior to working with the Raspberry Pi, I tried to use the Bluetooth Framework (BTFramework) library on a Windows 10 computer, communicating through a BlueGiga BLED112 BLE adapter. At one point I was able to use the demo program for .NET (GattClient) to perform these GATT tasks (reading and writing characteristic values), but lately I have been unable to set the correct options to get it to work.

I looked at using the Nordic nRF Python library (nRF Pynrfjprog) on Windows 10, with a Nordic nRF52840-Dongle. I never found a set of functions for GATT in this library.

Can someone help me understand how to get the bleak code to work reliably (no DBus exception), or give guidance on any tool that will provide stable communication with a BLE device?

0

There are 0 answers