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+。它也有效。
希望对您有所帮助。
我(和其他人一样)在 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+。它也有效。
希望对您有所帮助。