Unfortunately, I don't have any experience with async programming, so it took me quite some time to get my code running on a Raspberry Pi 5 4GB (with bookworm 2025-05-13 OS) to communicate with one BLE device (Raspberry Pi Pico 2W running micropython and ble_simple_peripheral):
import asyncio
from bleak import BleakClient
from bleak.backends.characteristic import BleakGATTCharacteristic
from bleak.backends.device import BLEDevice
UART_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
UART_RX_CHAR_UUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
UART_TX_CHAR_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
async def BLE_send(data):
device="2C:CF:67:D2:CA:2F" # MAC address RasPi Pico2W
def handle_disconnect(_: BleakClient):
print("Disconnected", BleakClient)
# cancelling all tasks effectively ends the program
for task in asyncio.all_tasks():
task.cancel()
def handle_rx(_: BleakGATTCharacteristic, data: bytearray):
print("received:", data)
async with BleakClient(device, disconnected_callback=handle_disconnect) as client:
await client.start_notify(UART_TX_CHAR_UUID, handle_rx)
print("connected")
loop = asyncio.get_running_loop()
nus = client.services.get_service(UART_SERVICE_UUID)
assert nus is not None, "UART service not found"
rx_char = nus.get_characteristic(UART_RX_CHAR_UUID)
assert rx_char is not None, "UART RX characteristic not found"
await client.write_gatt_char(rx_char, data, response=False)
print("sent:", data)
data=b"rb10\n"
try:
asyncio.run(BLE_send(data))
except asyncio.CancelledError:
print("")
pass
This can probably be done much better, but for one device it does what I want it to do.
I now need to communicate with a second (Pi Pico2W) peripheral and - owing to my ignorance - I haven't been able to get this working. I have tried many things, and it would not be efficient to list them all.
Would be great if someone could tell me how the code has to be modified/optimized to communicate with two devices (as synchronous as possible).