altbeacon 以 10Hz 连续检测信标 RSSI 值
Posted
技术标签:
【中文标题】altbeacon 以 10Hz 连续检测信标 RSSI 值【英文标题】:altbeacon detection of beacon RSSI values continuously at 10Hz 【发布时间】:2020-02-20 10:32:24 【问题描述】:我创建了一个 android (java) 应用程序,它使用 altbeacon 库 (github page) 通过蓝牙模块检测信标。
信标配置有 Eddystone UID、广播间隔为100ms
的协议和强传输功率级别 (10dBm
)。
我希望能够以10Hz
(即100ms)的频率检测信标的RSSI
值。
我已经准备了一个实现altbeacon库的服务,相关部分如下图:
mBeaconManager = BeaconManager.getInstanceForApplication(this);
beaconRegion = new Region("beacon_region", null, null, null);
// use Eddystone protocol
mBeaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
mBeaconManager.setAndroidLScanningDisabled(true);
mBeaconManager.setForegroundScanPeriod(100l); // scan frequency
mBeaconManager.setForegroundBetweenScanPeriod(0);
我看到信标并获得 RSSI 值的回调 didRangeBeaconsInRegion
是这样的:
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region)
Log.i(BeaconDataCollectorService.class.getSimpleName(), String.format("Found %s beacons in range", beacons.size()));
我的问题是什么? 运行应用程序,我注意到在 didRangeBeaconsInRegion 中,我经常看不到所有信标。
我运行了几秒钟的数据收集,将获得的数据创建为 csv 格式,您可以看到我经常有 0(表示未检测到信标);我把这个csv的分享放到pastebin(https://pastebin.com/zkUZC5R4)
如何通过始终能够检测到所有信标来提高扫描频率?
使用的altbeacon版本:
implementation 'org.altbeacon:android-beacon-library:2.16.3'
Android 版本:9
谢谢
【问题讨论】:
【参考方案1】:不幸的是,该库并非设计用于执行此操作,因为测距 API 是根据 ios 等效模型建模的,它以固定间隔提供聚合检测,而不是在单个数据包到达时访问它们。
在如此短的扫描周期内经常检测到 0 个信标的主要原因是因为扫描每 100 毫秒打开和关闭一次,启动和停止需要 10 毫秒左右。这样就很有可能错过检测。
这是个好消息:如果库在同一扫描周期内检测到两个信标数据包,那么它将停止关闭扫描,您的检测率将会提高。但是要让它在 100 毫秒内检测到两个信标,您的信标以标称 10Hz 的频率进行广告几乎是不可能的。
您可以尝试的一件事是将扫描周期设置为 1 秒。在您在 10 秒左右检测到有限数量的信标后,您很有可能在一个扫描周期内检测到两个信标,然后您可以切换到 100 毫秒的扫描周期并获得更高的检测率。
您永远不会获得 100% 的检测率,原因有两个:
由于碰撞和无线电噪声,并非所有传输的信标数据包都被接收。在近距离时,通常为 80-90%。
“BLE 广告商不会定期发布广告。 他们会随机发送数据包以避免冲突。标称的 10Hz 发射器可能在单个数据包之间有 70 毫秒到 140 毫秒之间的任何时间,因此对于 100 毫秒的固定扫描周期,有时会有 0、1 或 2 个有资格接收的打包程序。
如果您确实需要在每次检测时获取回调,您可以尝试在 BeaconManager 中设置 NonBeaconBleScanCallback,然后调用 BeaconManager.clearBeaconParsers()
。这将导致所有信标检测在检测到时立即发送到该回调。然后,您必须构造一个新的 BeaconParser 以在该回调中使用,以从原始数据包中解码信标。使用beaconParser.parse(...)
【讨论】:
谢谢@davidgyoung。我试图在 10 秒后将mBeaconManager.setForegroundScanPeriod
从 1000ms
更改为 100ms
但似乎在运行时您无法更改扫描值。我还尝试设置300ms
的扫描,100ms
发射的信标应该已经全部捕获,但即便如此我也无法检测到它们
你为什么说“即使这样我也无法检测到它们?”我以为您的问题是它们在 100 毫秒时被间歇性检测到?它真的在 300ms 时根本检测不到吗?两点:(1)如果您在 300 毫秒内根本无法检测到它们,则说明有问题。尝试使用像 BeaconScope 这样的现成信标检测器(也使用这个库),并让它说你的信标正在做你认为他们正在做的事情。 (2) 可以通过调用beaconManager.updateScanPeriods()
来强制扫描周期生效
我尝试将信标发射频率设置为100ms
,而从库中我将扫描频率设置为300ms
。以这种方式(理论上)我应该总是能够检测到每个300ms
由信标发出的数据包吗?但这不会发生,因为即使使用这种配置,我也经常有 0(即,如果我有 3 个信标,我通常只在回调中检测到 2 个)。
同样,您永远无法检测到 100% 的传输数据包。如果您尝试使用 BeaconScope 应用程序,它会使用 1 秒的扫描间隔和不停止的扫描告诉您每秒接收数据包的速率。这将告诉您大致可以实现的目标。但请记住,在 10 Hz 传输时,总会有大约 100 毫秒的周期,其中信标确实不传输任何数据包,因为传输速率并不完全规则。同样,在任何 300 毫秒周期内,信标可能只传输一个数据包,并且有 10-20% 的机会不会收到任何数据包。以上是关于altbeacon 以 10Hz 连续检测信标 RSSI 值的主要内容,如果未能解决你的问题,请参考以下文章
iOS 下 altBeacons 上的 Major 和 Minor
如何使用 android-beacon-library (altbeacon) 正确停止扫描信标
AltBeacon:didExitRegion 和 didEnterRegion 交替