我的xamarin应用程序正在android上运行。它使用SPP通过蓝牙连接到自定义设备。该应用程序发出命令,并且设备响应约260个字节。
我的问题是,设备发送的数据与通过套接字可供我的应用程序使用的数据之间似乎存在很大的延迟。这导致连接的吞吐量非常低。
此处的范围图像:https://imgur.com/a/gBPaWHJ
在图像中,黄色迹线是发送到设备的数据,蓝色迹线是响应。如您所见,设备在发送命令后立即响应。从命令开始到响应结束,我测量的周期为12ms。
在代码中,我测量了应用程序收到响应的最后一个字节与发送下一个命令之间的时间。时间始终为0或1毫秒。这不是示波器要告诉我的,在响应结束和发送下一个命令之间有一个明显的92ms周期。
我还测量了发送数据的代码行与接收到响应的第一个字节之间的时间,该时间通常为50到80ms。这是问题所在。
我已经检查过我的代码,没有延迟或计时器阻止发送命令。如果收到了完整的回应,它将立即发送数据请求。
我有一个System.Threading.Thread,它循环处理数据的发送和接收。我已经为这个循环计时了,它总是用不到3毫秒的时间来完成(大多数情况下是0毫秒)。这表明在我的循环中没有引起延迟的原因。我不希望有任何延迟,因为我们只谈论读取和处理的260字节数据。
Xamarin Android中是否存在某些东西,可能会导致通过蓝牙到达平板电脑的数据与我的应用可用的数据之间存在延迟。也许是每100毫秒才更新一次BluetoothSocket吗?我希望消除示波器上的空白。
答案 0 :(得分:-1)
通常,影响蓝牙传输的因素如下:连接间隔 / 每个连接事件发送的帧数 / 每帧数据的长度和 操作类型 (目前不考虑)。
根据Android协议支持的最佳值,您可以将连接间隔设置为 7.5ms ,并且每帧的数据大小为 20字节。< / p>
如果您需要发送 260字节的数据,则计算所需的时间为 97.5ms 。有时可能涉及蓝牙连接稳定性的波动,大约需要 100毫秒。
核心规范将ATT的默认MTU定义为23个字节。删除ATT操作码的一个字节和ATT handle2个字节后,剩余的20个字节将保留给GATT。 考虑到某些蓝牙智能设备较弱并且不敢过多使用内存空间,因此核心规格要求每个设备必须支持23的MTU。 在两个设备之间开始连接时,每个人都像一个新朋友,我不知道对方的罚款,因此请严格遵循例程,即一次最多发送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
}
}
之后,您可以愉快地发送受支持的MTU数据的长度。
因此,这实际上与xamarin无关,这只是Android施加的限制。