21

关于电气工程 Stackexchange 的后续问题

我想在短时间内重复写入低功耗蓝牙特性的值(作为一个可能的用例,想象一下鼠标)。

  • 128 位 UUID 的特征是20 字节长。因此,它可以写在单个 Low Energy 事务中。
  • 写入以 50 Hz 的速率发生,即每 20ms写入一次。
  • 因此,写入20 * 50 * 8 = 8 kbit/s 。
  • 我正在使用无响应的命令/写入模式来写入特征。因此,属性层上不会发生任何确认。
  • 未连接其他蓝牙或蓝牙低功耗设备。没有通过 WLAN 执行任何操作。在测试期间不会读取或写入其他特征。

我通过从 iPhone 4S 发送包含序列号的数据包来测试程序。每发送一个数据包后,序列号就加一。

在接收端,使用包含CSR1000 BLE 芯片的可编程开发板接收数据包并将接收到的序列号打印到串行连接。

我的问题如下:

  • 一段时间后,数据包开始被丢弃。前约 100 个数据包在 50 Hz 下工作正常。从那时起,数据包开始被丢弃。

               0x00 - 0x46   received
                0x47, 0x48   missing
    0x49, 0x4a, 0x4b, 0x4c   received
                      0x4d   missing
    0x4e, 0x4f, 0x50, 0x51   received
                      0x52   missing
    0x53, 0x54, 0x55, 0x56   received
                      0x57   missing
    ...
    

    大多数情况下,一包四个数据包可以很好地传输(很少,只有 2 个数据包)。然后,1-7 个数据包丢失。

    当我减小特征值大小时,问题仍然存在。

    当我以 100Hz 而不是 50Hz 写入时,情况是一样的 - 只是在大约 35 个数据包之后开始发生丢包,并且在四个数据包的成功传输之间丢弃了 5-7 个数据包。

    对于丢失的数据包,无论写入频率如何,最终的传输速率约为 5 kbit/s。这显然低于蓝牙低功耗技术上应该可行的约 305 kbit/s。

  • 当我从开发板向 iPhone 4S 发送数据包时,问题也出现在相反的方向。同样,5 kbit/s 是我得到的最大值。通知机制用于这种情况。同样,属性层上不会发生任何确认。

  • 当我尝试同时向两个方向发送时,事情开始恶化到我必须重置开发板和 iPhone 4S 的地步。

问题:

  • 这可能是开发板上使用的蓝牙低功耗芯片的问题吗?

    如果是,为什么问题也会出现在相反的方向,即 iPhone 充当接收器?

    市面上有支持高频访问特性的开发板吗?

  • 问题的根源可能是什么?

    除了假设之外,还请尝试参考蓝牙规范/演示幻灯片/文章的部分内容。

市场上有蓝牙低功耗鼠标。鼠标的典型轮询速率为 125 Hz,并且必须至少发送两个 16 字节的值以及每个滴答的额外 HID 开销。因此,我的问题的解决方案应该是可用的。

更新

LE 连接完成事件蓝牙规范版本 4.0 Vol 2 Part E 第 7.7.65.1 节中进行了描述。我收到以下不同连接参数的值:

Parameter               Value      Description
--------------------------------------------------
Conn_Interval           0x0054     Time =  105 ms
Conn_Latency            0x0000     Time =    0 ms
Supervision_Timeout     0x00fc     Time = 2520 ms
Master_Clock_Accuracy     0x05              50 ppm
4

3 回答 3

15

发布连接参数更新解决了该问题并将吞吐量从 5 kbit/s 提高到~33 kbit/s。然而,这仍然低于预期的~305 kbit/s。

Conn_Interval = 0x000f = 18.75 ms
Conn_Latency  = 0x0000
Supervision_Timeout = 0x00fc

有什么方法可以达到完整的 ~305 kbit/s?

关于电气工程 Stackexchange 的后续问题

烧掉一个TSI,等一个月就可以得到苹果的回复。

基本上,他们说这种行为是在 iOS 5.1 中设计的。这在某种程度上是有道理的,因为他们不希望您的应用程序的性能取决于另一个应用程序是使用蓝牙还是 W​​iFi。

根据工程师的评论 - 在 iOS 5.1 下,在连接间隔期间应该有 6 对通知,即 6*packetSize*1000/interval 。这应该转换为最大约 55kbps(最小间隔为 20 毫秒,数据包大小为 23 字节)。由于 iPhone 和 iPad 都在 BT classic、BT LE 和 WiFi 之间共享天线,我们决定限制每个间隔的对数并设置最小间隔。

iOS LE 被设计为低功耗传输。对于更高的吞吐量,BT 经典是一种更好的传输方法。

回到我身边——根据上面工程师的评论,如果希望达到 200 kbs 的吞吐量,经典蓝牙就是答案。但是,如果希望在 iPhone 上使用应用程序,我可以理解这不是简单的更改 - 经典 BT 需要 MFI 许可。

于 2012-04-30T11:29:24.827 回答
2

主要问题似乎是您正在使用的芯片上的缓冲区问题。来自核心规范,第 3 卷,F 部分,3.3.2:

对于没有响应 PDU 的通知,没有流量控制,可以随时发送通知。

不需要响应的命令没有任何流控制。注意:服务器可以被命令淹没,更高层的规范可以定义如何防止这种情况发生。

接收到但由于缓冲区溢出或其他原因无法处理的命令和通知应被丢弃。因此,这些 PDU 必须被认为是不可靠的。

于 2012-04-27T21:12:46.743 回答
2

当数据包被丢弃时,您看到的是由于 iPhone 端(我认为很可能)或主机端的缓冲区溢出。从 iOS 11.2 开始,Apple 提供了一种机制,允许您在写入下一个数据包之前检查缓冲区是否准备好;canSendWriteWithoutResponse:

如果您等到 canSendWriteWithoutResponse 为真后再写入数据包,则保证已将交付放入接收缓冲区,但不保证已处理(未确认)。另一件可能有帮助的事情是协商一个大于 20 的 MTU。Apple 支持 MTU 为 185B,最高为 251(扩展数据长度,即 EDL)。通过将数据包分块为 MTU-3 大小,每个连接间隔的数据包 ==(MTU-3) x 1。@185B MTU,24 ms 连接间隔我的吞吐量约为 48kbps,没有丢包。当从设备向 iPhone 发送数据时,该端的 SDK 将需要等效于“canSendWriteWithoutResponse”,在我使用 SiLabs 硬件/SDK 的情况下,它确实具有例如

```

 do {
     result = gecko_cmd_gatt_server_send_characteristic_notification(
              0xFF,
              evt->data.evt_gatt_server_attribute_value.attribute,
              chunk.length,
     [chunk bytes])->result;
 } while(result == bg_err_out_of_memory); 
  //retry until buffer is empty and ready for more 
 //then update the offset
 offset += thisChunkSize;

```

这是来自苹果的视频和 .pdf 文件,解释了不同的 BLE 技术和预期速度。MTU + 连接间隔用于确定最大吞吐量。48kbps 应该很容易实现,96kbps 甚至更高一点是可能的。

核心蓝牙的新功能

video: https://devstreaming-cdn.apple.com/videos/wwdc/2017/712jqzhsxoww3zn/712/712_hd_whats_new_in_core_bluetooth.mp4?dl=1
pdf: https://devstreaming-cdn.apple.com/videos/wwdc/2017/712jqzhsxoww3zn/712/712_whats_new_in_core_bluetooth.pdf 
于 2018-07-09T20:59:07.587 回答