BluePy Raspberry Pi4 和 ESP32 之间的 BLE 频繁断开连接 -(蓝牙)

BluePy Frequent BLE Disconnects between Raspberry Pi4 and ESP32 - (Bluetooth)

我(和其他人一样)在 RPi4 中央(客户端)和 ESP32 BLE 外设(服务器)之间有多个断开连接。在 android phone 上使用“nRF Connect”应用程序,与 ESP32 的连接是可靠的。然而,RPi4 - ESP32 BLE 通信非常不稳定。这一发现表明故障出在 RPi and/or 代码上。初始 BLE 连接如实发生,但在随机数次成功读取(通常为 1-50 次读取)后连接不可避免地断开。我在 RPI4 上使用带有新 Raspbian 图像的 BluePy 1.3.0。我附上了框架代码和随机数次成功读取后产生的错误消息。

    import time
    from bluepy.btle import Peripheral

    peripheral_address = "8c:aa:b5:85:20:1e"
    service_uuid =  "537e7010-9928-4595-89dc-46b495862dc6"
    characteristic_uuid = "3778ceab-0974-4eb0-9da5-26c3a69cc742" # Read from peripheral

    p = Peripheral(peripheral_address, "public") #random does not work!!
    Service=p.getServiceByUUID(service_uuid)
    Characterization=Service.getCharacteristics(characteristic_uuid)[0]
    print("Got characterization")

    time.sleep(1)

    while True:
        value = Characterization.read()
        print(value)
        time.sleep(0.1)

Traceback (most recent call last):
  File "/home/pi/Desktop/BLETest/bleRead.py", line 16, in <module>
    value = Characterization.read()
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 197, in read
    return self.peripheral.readCharacteristic(self.valHandle)
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 530, in readCharacteristic
    resp = self._getResp('rd')
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 407, in _getResp
    resp = self._waitResp(wantType + ['ntfy', 'ind'], timeout)
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 362, in _waitResp
    raise BTLEDisconnectError("Device disconnected", resp)
bluepy.btle.BTLEDisconnectError: Device disconnected

注意:到目前为止,添加代码以捕获断开连接异常未成功,导致重新连接所需的时间引发了额外的错误和数据丢失。

我很想听听任何与 RPi 客户端进行可靠 BLE 通信的人的意见?任何和所有的帮助表示赞赏。谢谢。

可能有很多事情,但我会调查几个领域。

首先,正如您从该线程中看到的那样,目前 RPi 上的蓝牙固件发生了一些变化: https://github.com/RPi-Distro/firmware-nonfree/issues/8

所以我会检查你是否 up to date 与那些。

BluePy 我相信有一个 bluepy-helper 模块,它基于 Bluez 版本 5.47,它落后于 RPi 现在使用的版本。可能值得尝试不同的库,看看问题是否仍然存在。

下面是一个使用 BlueZ D-Bus API 直接使用 pydbus 为 python D-Bus 绑定读取特征的示例:

from time import sleep
import pydbus
from gi.repository import GLib

peripheral_address = "8C:AA:B5:85:20:1E"
service_uuid =  "537e7010-9928-4595-89dc-46b495862dc6"
characteristic_uuid = "3778ceab-0974-4eb0-9da5-26c3a69cc742" # Read from peripheral

# DBus object paths
BLUEZ_SERVICE = 'org.bluez'
ADAPTER_PATH = '/org/bluez/hci0'
device_path = f"{ADAPTER_PATH}/dev_{peripheral_address.replace(':', '_')}"

# setup dbus
bus = pydbus.SystemBus()
mngr = bus.get(BLUEZ_SERVICE, '/')
adapter = bus.get(BLUEZ_SERVICE, ADAPTER_PATH) 
device = bus.get(BLUEZ_SERVICE, device_path)

device.Connect()

while not device.ServicesResolved:
    sleep(0.5)

def get_characteristic_path(dev_path, uuid):
    """Look up DBus path for characteristic UUID"""
    mng_objs = mngr.GetManagedObjects()
    for path in mng_objs:
        chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
        if path.startswith(dev_path) and chr_uuid == uuid.casefold():
           return path

# Characteristic DBus information
char_path = get_characteristic_path(device._path, characteristic_uuid)
characterization = bus.get(BLUEZ_SERVICE, char_path)

# Read characteristic without event loop notifications
while True:
    print(characterization.ReadValue({}))
    time.sleep(0.1)

您正在阅读的特征是否支持通知?如果是,那么这是使用蓝牙的更有效方式 link。上面的while循环可以替换为:

# Enable eventloop for notifications
def notify_handler(iface, prop_changed, prop_removed):
    """Notify event handler for characteristic"""
    if 'Value' in prop_changed:
        new_value = prop_changed['Value']
        print(f"Received: {new_value}")


mainloop = GLib.MainLoop()
characterization.onPropertiesChanged = notify_handler
characterization.StartNotify()
try:
    mainloop.run()
except KeyboardInterrupt:
    mainloop.quit()
    characterization.StopNotify()
    device.Disconnect()

最近,我也遇到了和你一样的问题。但是刚才我可能解决了这个 problem.I 在树莓派 4 上测试两种低蓝牙库。其中一个是 bluepy enter link description here, the other is bleak enter link description here.

起初,我只是 运行 在 raspberry 4 上用以上两个库编写代码,它有一个较旧的 raspios。 此外,我曾经禁用蓝牙,因为我不得不使用它的 UART 进行通信。 这些代码不起作用。它因断开连接问题而失败或挂起而没有任何反应。

当我对这些问题没有想法时,我就去地址enter link description here下载'Raspberry Pi OS with desktop and recommended software'。我把OS烧录到SD卡里,插到树莓4上调试上面两个库的代码。他们 运行 正确。我可以连续接收通知数据,没有任何异常。

所以,我认为这些问题是由于Bluetooth-low-energy和UART之间的一些冲突造成的。 虽然我删除了 OS 的 config.txt enter link description here 中的行,但我这样做是为了破坏 ble 并使用 uart。 OS 可能没有回到原来的状态,或者我忘记了我做过的一些其他操作。因为我是初学者才知道这种OS.

这就是我所做的一切。我还将 SD 卡插入 Raspberry 3 B+。它也有效。

希望对您有所帮助。