xamarin蓝牙数据接收延迟
Posted
技术标签:
【中文标题】xamarin蓝牙数据接收延迟【英文标题】:xamarin bluetooth data receive delay 【发布时间】:2018-12-11 14:56:11 【问题描述】:我的 xamarin 应用程序在 android 上运行。它使用 SPP 通过蓝牙连接到自定义设备。 App 发出命令,设备以大约 260 字节响应。
我的问题是设备发送的数据与通过套接字对我的应用程序可用的数据之间似乎存在很大延迟。这会导致连接的吞吐量非常低。
此处的范围图片:https://imgur.com/a/gBPaWHJ
在图像中,黄色迹线是发送到设备的数据,蓝色是响应。如您所见,设备在命令发送后立即响应。我测量了从命令开始到响应结束的周期为 12 毫秒。
在代码中,我测量了应用程序接收到响应的最后一个字节到发送下一个命令之间的时间。时间总是 0 或 1ms。这不是示波器告诉我的,在响应结束和发送下一个命令之间有一个明确的 92 毫秒时间段。
我还测量了从发送数据的代码行到收到响应的第一个字节之间的时间,通常需要 50 到 80 毫秒。这就是问题所在。
我已经完成了我的代码,并且没有延迟或计时器阻止发送命令。如果收到完整的响应,它将立即发送数据请求。
我有一个 System.Threading.Thread 循环处理数据的发送和接收。我已经为这个循环计时,它总是需要不到 3 毫秒才能完成(大部分是 0 毫秒)。这表明我的循环没有延迟导致这种情况。我不希望有任何延迟,因为我们只谈论要读取和处理 260 字节的数据。
Xamarin Android 中是否存在可能导致数据通过蓝牙到达平板电脑与我的应用程序可用数据之间的延迟。也许有些东西只是每 100 毫秒更新一次蓝牙套接字?我希望我的示波器上的那些空白消失。
【问题讨论】:
就我个人而言,我非常怀疑这对 Xamarin 有什么影响...但我不知道您的代码以及您在其中做什么...要证明它是 Xamarin“问题”,请写一个在本机 Java/Kotlin 中测试项目以进行怀疑检查。使用不同的设备进行测试也是一个好主意。 我在不同的安卓设备上检查,延迟上升到 150 到 200 毫秒。 您的数据包大小符合标准。 L2CAP MTU,所以这不是问题。我首先要怀疑的是您的代码,当然,在双线程发送/接收基于串行的 SPP 例程中,您应该能够最大限度地利用带宽,总带宽当然很低,但延迟应该很低(默认 MTU 约为 650 字节) 我已经对代码进行了计时,没有发现问题。大部分代码是我自己的 .net 标准库。我已经通过串行电缆在 winforms 应用程序上运行它,没有问题。该库包含并使用一个接口,因此连接的性质无关紧要,蓝牙,串行等......重要的是您可以读取单个字节。此外,MTU 问题会在示波器上看到。发送数据所需的时间会增加。从图中可以看出,260bytes的传输已经及时完成了。 【参考方案1】:总的来说,影响蓝牙传输的因素如下:连接间隔 / 每个连接事件发送的帧数 / 每帧数据的长度,以及一个操作类型(目前不考虑)。
根据Android协议支持的最优值,可以将Connection Interval设置为7.5ms,每帧数据大小20字节。
如果需要发送260字节的数据,那么计算所需时间为97.5ms。有时可能会涉及到蓝牙连接稳定性的波动,大约需要100ms。
-
为什么限制为 20 个字节?
核心规范将 ATT 的默认 MTU 定义为 23 字节。去掉一个字节的 ATT 操作码和 ATT 句柄 2 个字节后,剩下的 20 个字节保留给 GATT。 考虑到部分蓝牙智能设备性能较弱,不敢过多占用内存空间,核心规范要求每台设备必须支持23的MTU。 两台设备连接之初,大家都像新朋友一样,不知道对方好不好,所以严格按照套路,也就是一次最多发送20个字节,这样最多保险。
-
如何突破20?
由于 ATT 的最大长度为 512 字节,因此更改传输的 ATT 的 MTU 就足够了。在 Android (API 21) 上,更改 ATT MTU 的接口是:
public boolean requestMtu (int mtu)
#Added in API level 21
#Request an MTU size used for a given connection.
#When performing a write request operation (write without response), the data sent is truncated to the MTU size. This function may be used to request a larger MTU size to be able to send more data at once.
#A onMtuChanged(BluetoothGatt, int, int) callback will indicate whether this operation was successful.
#Requires BLUETOOTH permission.
#Returns true, if the new MTU value has been requested successfully
如果你的外设应用改变了 MTU 并且成功了,那么这个回调也会被调用。
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status)
super.onMtuChanged(gatt, mtu, status);
if (status == BluetoothGatt.GATT_SUCCESS)
this.supportedMTU = mtu;//local var to record MTU size
之后就可以愉快的发送supportedMTU数据的长度了。
所以这实际上与xamarin无关,这只是Android强加的限制。
【讨论】:
我不确定我是否理解。这将如何导致数据到达平板电脑和应用程序可用之间的延迟? 建议您可以测试通过较少的数据(20字节)。如果想要通过更多的数据和低延迟,您需要修改代码编译自定义移动android系统。以上是关于xamarin蓝牙数据接收延迟的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms:如何在 Xamarin.Forms 跨平台项目中开发具有蓝牙连接的应用程序?