如何解决BluePy 频繁 BLE 在 Raspberry Pi4 和 ESP32 之间断开连接 -蓝牙
我(和其他人一样)在 RPi4 中央(客户端)和 ESP32 BLE 外设(服务器)之间有多次断开连接。使用 Android 手机上的“nRF Connect”应用程序,与 ESP32 的连接非常可靠。但是,RPi4 - ESP32 BLE 通信非常不稳定。这一发现意味着故障出在 RPi 和/或代码上。最初的 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 我相信有一个基于 Bluez 5.47 版的 bluepy-helper
模块,它落后于 RPi 现在使用的版本。可能值得尝试不同的库,看看问题是否仍然存在。
以下是直接使用 pydbus 为 python D-Bus 绑定使用 BlueZ D-Bus API 读取特征的示例:
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)
您从支持通知中读取的特征是否?如果是这样,那么这是使用蓝牙链接的更有效方式。上面的 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()
,
最近,我也遇到了和你一样的问题。但刚才我可能解决了这个问题。我在 raspberry 4 上测试了两种蓝牙低库。其中一种是 bluepy enter link description here,另一个是惨淡的enter link description here。
起初,我只是在 raspberry 4 上运行了具有以上两个库的代码,它有一个较旧的 raspios。 除了我曾经在它上面禁用蓝牙,因为我不得不使用它的 UART 进行通信。 代码不起作用。它因断开连接问题而失败或没有反应。
当我对这些问题没有任何想法时,我会去地址 enter link description here 并下载“带有桌面和推荐软件的 Raspberry Pi OS”。我在SD卡中烧录OS,将其插入Raspberry 4并调试上述两个库的代码。它们运行正常。我可以无异常地持续接收通知数据。
所以,我认为这些问题是由于低功耗蓝牙和 UART 之间的一些冲突造成的。 虽然我删除了操作系统的 config.txt enter link description here 中的行,但我这样做是为了禁用 ble 并使用 uart。操作系统可能没有恢复到原始状态,或者我忘记了我做过的其他一些操作。因为我是初学者,才知道这种操作系统。
这就是我所做的。我还将 SD 卡插入 Raspberry 3 B+。它也有效。
希望对你有帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。