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.setForegroundScanPeriod1000ms 更改为 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 交替

AltBeacon getDistance() 函数与信标定位距离估计

在 Swift 中匹配数据类型

使用 altBeacon 库在 Android 中未显示所有信标