Windows 11企业版下使用Python Bleak库读取BLE广播包丢包排查
BLE广播包丢包原因分析
核心原因拆解
扫描周期与广播周期不匹配
你当前代码设置单次扫描时长为1秒,而设备每5秒广播一次。扫描窗口和设备广播时刻极易错开,比如设备在第3秒广播,但你的扫描仅覆盖0-1秒、2-3秒这类1秒窗口,一旦错过广播触发点就会丢包。单次扫描的间隔空白期
BleakScanner.discover()是单次扫描,扫描结束后返回结果,再进入下一次循环。两次扫描之间存在系统调度、代码执行带来的不可控间隔,这段时间内设备的广播包会被完全遗漏。Windows BLE栈的底层限制
Windows系统对BLE扫描有资源节流机制,尤其是后台运行时,会限制扫描频率和窗口大小;此外系统可能对广播包做过滤或聚合处理,误判部分包为无效数据而丢弃。代码逻辑的固有缺陷
代码依赖单次扫描的结果遍历设备,没有持续监听的机制,无法覆盖所有广播时间点;found变量未实际参与逻辑控制,对丢包问题无改善作用。
优化方案
改用持续回调扫描模式
放弃单次discover(),使用Bleak的回调监听机制,全程无间隔捕获广播包:
from bleak import BleakScanner, ScanMode import datetime import asyncio ble_address = "DEVICE MAC ADDRESS" def detection_callback(device, advertisement_data): if device.address == ble_address: print(f"{datetime.datetime.now()}: {advertisement_data}") if 1318 in advertisement_data.manufacturer_data: data = advertisement_data.manufacturer_data[1318] print([hex(x) for x in list(data)]) async def run(): # 低延迟扫描模式,减少Windows系统节流影响 scanner = BleakScanner(detection_callback=detection_callback, scan_mode=ScanMode.LOW_LATENCY) await scanner.start() # 持续运行,可根据需求添加停止逻辑 while True: await asyncio.sleep(1) asyncio.run(run())
其他辅助调整
- 若坚持用单次扫描,将扫描时长设为≥5秒(设备广播周期),但会导致每次扫描阻塞5秒,效率远低于回调模式。
- 确保BLE适配器与设备距离足够近,避免信号弱导致的物理丢包。
内容的提问来源于stack exchange,提问作者Akash Guru
相关产品推荐
相关产品推荐

