【问题标题】:How to send Data via BLE using a for loop如何使用 for 循环通过 BLE 发送数据
【发布时间】:2021-11-29 03:58:03
【问题描述】:

我对 BLE 很陌生,我正在制作一个需要通过 BLE 快速连续传输 Data 对象的应用程序。到目前为止,我已经尝试了一个 for 循环来根据索引更改特征。它成功地改变了第一个值的特征,但在其余部分失败了。我目前正在开发一个 POC,其代码如下所示。

guard let characteristic = self.transferCharacteristic else { return }

for x in "Hello there" {
    let data = Data("\(x)".data(using: .utf8)!)
    let didSend = self.peripheralManager.updateValue(data, for: characteristic, onSubscribedCentrals: nil)
    if didSend {
        print("Sent: \(x)")
    } else {
        print("Couldn't send: \(x)")
    }
}

这个的输出是,

Sent: H
Couldn't send: e
Couldn't send: l
Couldn't send: l
.
.
.
Couldn't send: e
Couldn't send: r
Couldn't send: e

我怎样才能实现我想要的? 有没有更好的办法?

我知道事务只有几毫秒,但不知道如何在可能的情况下将特征更改与事务速度同步。

提前谢谢你。

【问题讨论】:

  • 我可能不太了解您的问题,但对我来说这听起来像是一个竞争条件。当您应该串联调用时,您实际上是在并行调用它们。在您获得第 4 项的结果之前,无法发送第 5 项。这是否正确?
  • 我不确定 CoreBluetooth 是否在不同的线程上运行,但我可以向您保证,我不会并行更新特性。我在程序中只有必要的 CB 委托方法、一些变量(外设、外设管理器和特征)和一个 for 循环,用于更新“Hello there”中每个字母的一个特征
  • 啊,对不起,我确实误解了你的问题。

标签: ios swift bluetooth-lowenergy core-bluetooth


【解决方案1】:

如果您收到此调用的错误消息,则需要存储其余数据包并等待peripheralManagerIsReady(toUpdateSubscribers:) 被调用。然后,您可以将其他更改排队,直到它再次返回 false。你不能在不处理背压的情况下循环执行此操作。

根据您的用例,您可能会发现在管理器准备好之前丢弃中间数据包会更好,或者您可以将它们排队,或者如果丢弃太多,您可能会返回错误,或许多其他策略。哪种背压策略有意义取决于您的问题。

不要忘记,您也有可能随时断开连接。 BLE 是一种可靠的传输方式,因此您永远不会收到乱序的数据包、跳过或损坏的数据包,但这并不意味着数据包会被传递。

也就是说,这是发送大量数据的一种非常低效的方式。通常,您应该将数据包组合成块(最多 maximumUpdateValueLength)并以更少的写入发送它们。发送数据包有很多开销。成为可靠的交通工具需要付出巨大的代价。

【讨论】:

  • 谢谢,这很完美。这只是一个测试 BLE 写入的 POC,这就是我使用字符串的原因。然而在实际产品中,大UInt8 数组将根据中心maximumUpdateValueLength 被分块成字节数组@
猜你喜欢
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
相关资源
最近更新 更多