raspberry pi - Python: Bluetooth receiving issues with ubluetooth and bleak (between Pico and Pi 5) - Stack Overflow

admin2025-05-02  1

I'm in desperate need of help for an issue with the bluetooth connection between a Raspberry Pi Pico W (using MicroPython) and a Raspberry Pi 5 (running OS Lite - terminal). Using full Python and Bluetooth Low Energy, I am trying to:

  1. Connect both to each other using the other's MAC address and characteristic UUID
  2. Send a message from the Pico over Bluetooth
  3. Receive the message on the Pi 5 and print it on the REPL.

However, right now the Pico says it has advertised, connected to Pi 5, and sent the 'Hello, World!' message. However, on the Pi 5 it says it has connected to the Pico, but has it isn't receiving any messages. Take a look.

Pico Code (ubluetooth)

import ubluetooth
import time

SERVICE_UUID = "afc061de-096a-41c0-92a1-0c0ad71d5686"
CHAR_UUID = "a2ef971e-8c08-4bbf-9f77-ada7ca40c98e"

_IRQ_CENTRAL_CONNECT = 1
_IRQ_CENTRAL_DISCONNECT = 2

class BLEPeripheral:
    def __init__(self):
        self.ble = ubluetooth.BLE()
        self.ble.active(True)
        self.ble.irq(self.ble_irq)
        self.connected = False
        self.conn_handle = None
        self.char_handle = None

    def ble_irq(self, event, data):
        if event == _IRQ_CENTRAL_CONNECT:
            self.connected = True
            self.conn_handle = data[0]
            print(f"Central connected with handle: {self.conn_handle}")
            self.send_message("Hello World")

        elif event == _IRQ_CENTRAL_DISCONNECT:
            self.connected = False
            self.conn_handle = None
            print("Central disconnected")
            self.start_advertising()

    def start_advertising(self):
        name = "PicoW-BLE"
        name_bytes = name.encode("utf-8")
        adv_data = bytearray([0x02, 0x01, 0x06]) + bytearray([len(name_bytes) + 1, 0x09]) + name_bytes
        self.ble.gap_advertise(100000, adv_data)
        print("Started advertising")

    def register_services(self):
        service = (ubluetooth.UUID(SERVICE_UUID), ((ubluetooth.UUID(CHAR_UUID), ubluetooth.FLAG_READ | ubluetooth.FLAG_NOTIFY),))
        handles = self.ble.gatts_register_services((service,))
        self.char_handle = handles[0][0]
        print(f"Registered services with char_handle: {self.char_handle}")

    def send_message(self, message):
        if self.connected and self.conn_handle is not None:
            print(f"Sending message: {message}")
            try:
                self.ble.gatts_notify(self.conn_handle, self.char_handle, message.encode("utf-8"))
                print("Message sent successfully")
            except Exception as e:
                print(f"Error sending message: {e}")
        else:
            print("Not connected, cannot send message.")


# Main program
def main():
    ble_peripheral = BLEPeripheral()
    ble_peripheral.register_services()
    ble_peripheral.start_advertising()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Stopping BLE...")
        ble_peripheral.ble.active(False)

# Run the program
main()

Output:

Registered services with char_handle: 9
Started advertising
Central connected with handle: 64
Sending message: Hello World
Message sent successfully
Central disconnected

Raspberry Pi 5 code (bleak):

                                                                                                
import asyncio
from bleak import BleakClient

PICO_MAC = "28:CD:C1:0B:6D:EA"  # Replace with your Pico W's MAC address
CHAR_UUID = "a2ef971e-8c08-4bbf-9f77-ada7ca40c98e"

async def main():
    def notification_handler(sender, data):
        """Callback for handling incoming notifications."""
        print(f"Received notification from {sender}: {data.decode('utf-8')}")

    async with BleakClient(PICO_MAC) as client:
        print("Connected to Pico W")

        # Check if the characteristic exists and supports notifications
        service = await client.get_services()
        characteristic_found = False

        for service in service:
            for char in service.characteristics:
                if char.uuid == CHAR_UUID:
                    characteristic_found = True
                    print(f"Characteristic {CHAR_UUID} found and supports: {char.properties}")

        if not characteristic_found:
            print(f"Characteristic {CHAR_UUID} not found. Please check the UUID.")
            return

        # Subscribe to notifications
        print("Subscribing to notifications...")
        await client.start_notify(CHAR_UUID, notification_handler)

        # Keep connection alive and listen for notifications
        try:
            print("Waiting for notifications...")
            await asyncio.sleep(30)  # Wait for 30 seconds to receive notifications
        except asyncio.CancelledError:
            print("Notification wait canceled.")

        # Unsubscribe from notifications
        print("Unsubscribing from notifications...")
        await client.stop_notify(CHAR_UUID)

    print("Disconnected from Pico W")

asyncio.run(main())

Output:

Connected to Pico W
Characteristic a2ef971e-8c08-4bbf-9f77-ada7ca40c98e found and supports: ['read', 'notify']
Subscribing to notifications...
Waiting for notifications...
Unsubscribing from notifications...
Disconnected from Pico W

As you can see, the Pi 5 is unable to receive the message, even though the Pico says it has already sent it.

I know that they are able to establish a connection using the MAC address of the Pico W, however even when the Pico says it sent a message, the message hasn't been received on the Pi 5.

Thanks.

转载请注明原文地址:http://www.anycun.com/QandA/1746115910a91889.html