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

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-