简体   繁体   English

Xamarin蓝牙数据接收延迟

[英]xamarin bluetooth data receive delay

I have my xamarin app running on android. 我的xamarin应用程序在android上运行。 It connects to a custom device through bluetooth using SPP. 它使用SPP通过蓝牙连接到自定义设备。 The App issues commands and the device responds with about 260 bytes. 应用程序发出命令,并且设备以大约260个字节作为响应。

My problem is that there appears to be a large delay between data being sent by the device and that data being available to my app through the socket. 我的问题是,设备发送的数据与通过套接字对我的应用可用的数据之间似乎存在很大的延迟。 This results in the throughput of the connection being very low. 这导致连接的吞吐量非常低。

Scope image here: https://imgur.com/a/gBPaWHJ 范围图片在这里: https : //imgur.com/a/gBPaWHJ

In the image, the yellow trace is the data being sent to the device, the blue is the response. 在图像中,黄色迹线是发送到设备的数据,蓝色迹线是响应。 As you can see, the device responds immediately after the command is sent. 如您所见,设备在发送命令后立即响应。 I have measured the peroid from the start of a command to the end of the response to be 12ms. 我已经测量了从命令开始到响应结束的周期为12ms。

In the code, I measured the time between the app receiving the last byte of a response to the the sending of the next command. 在代码中,我测量了应用程序收到响应的最后一个字节与发送下一个命令之间的时间。 The time was always 0 or 1ms. 时间始终为0或1毫秒。 This is not what the scope is telling me, there is a clear 92ms period between the end of a response and the sending of the next command. 这不是示波器要告诉我的,在响应结束和发送下一个命令之间有一个清晰的92ms周期。

I also measured the time between the line of code that sends data, and the first byte of the response being received, it always takes 50 to 80ms. 我还测量了发送数据的代码行与接收到响应的第一个字节之间的时间,该时间通常为50到80ms。 This here is the problem. 这是问题所在。

I have been through my code and there are no delays or timers that prevent a command being sent. 我已经检查过我的代码,没有延迟或计时器阻止发送命令。 If it has received a full resonse, it will send a request for data straight away. 如果收到了完整的回应,它将立即发送数据请求。

I have a System.Threading.Thread which loops around handling the sending and receiving of data. 我有一个System.Threading.Thread,它循环处理数据的发送和接收。 I have timed this loop and it always takes less than 3ms to complete (mostly it is 0ms). 我已经为这个循环计时了,它总是用不到3毫秒的时间来完成(大多数情况下是0毫秒)。 This shows there is no delay in my loop causing this. 这表明在我的循环中没有引起延迟的原因。 I wouldnt expect any delay as we're only talking about 260 bytes of data to read and process. 我不希望有任何延迟,因为我们只谈论260个字节的数据进行读取和处理。

Is there something in Xamarin Android that might cause a delay between data arriving at the tablet over bluetooth and data being available to my app. Xamarin Android中是否存在某些东西,可能会导致通过蓝牙到达平板电脑的数据与可用于我的应用程序之间的延迟。 Perhaps something is only updating the BluetoothSocket every 100ms? 也许是每100毫秒才更新一次BluetoothSocket吗? I want those empty gaps on my scope to be gone. 我希望消除我的示波器上的那些空白。

In general, the factors that affect Bluetooth transmission are as follows: Connection Interval / number of frames sent per Connection Event / length of each frame of data , and an operation type (not considered at this time). 通常,影响蓝牙传输的因素如下: 连接间隔 / 每个连接事件发送的帧数 / 每个数据帧的长度以及操作类型 (目前不考虑)。

According to the optimal value supported by the Android protocol, you can set the Connection Interval to 7.5ms , and the data size of each frame is 20 bytes . 根据Android协议支持的最佳值,可以将“连接间隔”设置为7.5ms ,每帧的数据大小为20个字节

If you need to send 260 bytes of data, then the time required for the calculation is 97.5ms . 如果您需要发送260个字节的数据,则计算所需的时间为97.5ms Sometimes it may involve fluctuations in the stability of the Bluetooth connection, which takes about 100ms . 有时可能涉及蓝牙连接稳定性的波动,大约需要100毫秒

  1. why is it limited to 20 bytes? 为什么限制为20个字节?

The core spec defines the default MTU of the ATT to be 23 bytes. 核心规范将ATT的默认MTU定义为23个字节。 After removing one byte of the ATT opcode and the ATT handle2 bytes, the remaining 20 bytes are reserved for the GATT. 删除ATT操作码的一个字节和ATT handle2个字节后,剩余的20个字节将保留给GATT。 Considering that some Bluetooth smart devices are weak and don't dare to use memory space too much, the core spec requires that each device must support an MTU of 23. At the beginning of the connection between the two devices, everyone is like a new friend, I don't know the other party's fine, so strictly follow the routine, that is, send up to 20 bytes at a time, which is the most insurance. 考虑到某些蓝牙智能设备较弱并且不敢过多使用内存空间,因此核心规范要求每个设备必须支持23的MTU。在两个设备之间的连接开始时,每个人都像新的一样。朋友,我不知道对方的罚款,因此请严格遵循例程,即一次最多发送20个字节,这是最保险的做法。

  1. How to break through 20? 如何突破20?

Since the maximum length of the ATT is 512 bytes, it is sufficient to change the MTU of the transmitted ATT. 由于ATT的最大长度为512字节,因此足以更改发送的ATT的MTU。 On Android (API 21), the interface for changing the ATT MTU is: 在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

If your peripheral application changes the MTU and succeeds, then this callback will also be called. 如果您的外围应用程序更改了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
    }
}

After that, you can happily send the length of the supportedMTU data. 之后,您可以愉快地发送受支持的MTU数据的长度。

So this is actually not related to xamarin, this is just a limitation imposed by Android. 因此,这实际上与xamarin无关,这只是Android施加的限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM