如何在树莓派上通过bluepy库查询指定BLE信标设备是否在周边
方案结论
可以直接遍历目标信标地址列表逐一校验设备是否在范围内,无需执行全量扫描。这种方案在目标设备数量较少的场景下,总耗时比全量扫描低50%以上,完全匹配你的需求。
具体实现方法
bluepy 提供两种实现路径,你可以根据自己的信标类型选择:
1. 连接校验法(适合可连接型信标)
通过尝试和目标MAC地址建立BLE连接判断设备是否在线,耗时最短,单设备校验耗时通常不超过2秒:
from bluepy import btle # 替换为你的目标信标MAC地址列表 TARGET_MAC_LIST = ["AA:BB:CC:11:22:33", "DD:EE:FF:44:55:66"] # 连接超时时间,单位秒,建议设2~3秒即可 CONN_TIMEOUT = 2 # 地址类型:公共地址填btle.ADDR_TYPE_PUBLIC,随机静态地址填btle.ADDR_TYPE_RANDOM ADDR_TYPE = btle.ADDR_TYPE_PUBLIC detected = [] for mac in TARGET_MAC_LIST: try: dev = btle.Peripheral(mac, addrType=ADDR_TYPE, timeout=CONN_TIMEOUT) detected.append(mac) # 校验成功立刻断开,避免占用连接资源 dev.disconnect() except btle.BTLEDisconnectError: # 连接超时即判定为不在范围内 continue print("当前可检测到的信标:", detected)
2. 定向扫描过滤法(适合不可连接的广播型信标)
如果你的信标是不可连接的纯广播类型,不用等全量扫描结束,可以在扫描过程中实时匹配目标地址,提前终止扫描:
from bluepy import btle import time TARGET_MAC_LIST = ["AA:BB:CC:11:22:33", "DD:EE:FF:44:55:66"] # 最大扫描时长,单位秒,无需设置太长,3秒足够覆盖大部分广播间隔 MAX_SCAN_SEC = 3 # MAC地址统一转大写避免大小写匹配问题 target_upper = [m.upper() for m in TARGET_MAC_LIST] scanner = btle.Scanner() scanner.start() detected = set() for _ in range(MAX_SCAN_SEC): for dev in scanner.getDevices(): dev_mac = dev.addr.upper() if dev_mac in target_upper and dev_mac not in detected: print(f"检测到目标信标:{dev_mac},信号强度:{dev.rssi}dBm") detected.add(dev_mac) # 所有目标都检测到可提前退出,无需等到最大时长 if len(detected) == len(target_upper): break time.sleep(1) scanner.stop()
注意事项
- 首先确认你的信标MAC地址类型,如果是随机静态地址一定要修改
ADDR_TYPE参数,否则会出现设备在范围内也连接失败的误判 - 如果同时校验的目标设备超过5个,更推荐用定向扫描过滤的方案,总耗时比串行逐个连接更短
- 校验期间不要同时运行其他BLE连接任务,避免树莓派蓝牙适配器资源不足导致校验准确率下降
内容的提问来源于stack exchange,提问作者PatrickM
相关产品推荐
相关产品推荐

