简体   繁体   English

在iOS中向外部蓝牙设备写入> 20个字节

[英]Writing >20 bytes to an external Bluetooth device in iOS

I have an external device that communicates via Bluetooth with an iPhone Application that has support for iOS6+ . 我有一个外部设备通过蓝牙与支持iOS6 +iPhone应用程序进行通信

The problem is that I need to write more than 20 bytes to a characteristic and from what I've read and tried this is not possible using BLE . 问题是我需要写一个超过20个字节的特性,从我读过的东西开始,尝试使用BLE是不可能的。

Here is a basic structure of my method: 这是我的方法的基本结构:

NSData * payload = ... //53 bytes, last 2 bytes CRC
[peripheral writeValue:payload forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

The error I get when sending >20 bytes is CBErrorOperationCancelled (code 5) and CBErrorConnectionTimeout (code 6). 发送> 20个字节时得到的错误是CBErrorOperationCancelled (代码5)和CBErrorConnectionTimeout (代码6)。 I believe this is normal. 我相信这很正常。

I divided the data in chunks of 20 bytes (example here: https://github.com/RedBearLab/iOS/issues/8 ) and the data is not written well on the device: 我将数据分成20个字节的块 (例如: https//github.com/RedBearLab/iOS/issues/8 )并且数据在设备上写得不好:

NSData * chunk1 = ... //first 20 bytes
NSData * chunk2 = ... //next 20 bytes
...
NSData * chunkN = ... //remaining bytes + CRC from whole data

[peripheral writeValue:chunk1 forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
[peripheral writeValue:chunk2 forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
...
[peripheral writeValue:chunkN forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

I think the external device treats each byte array, not the whole data. 我认为外部设备处理每个字节数组,而不是整个数据。

Also, I tried to split the payload data in chunks of 18 bytes and append the CRC to each chunk of bytes I send. 此外,我尝试将有效负载数据分成18个字节的块, 并将CRC附加到我发送的每个字节块。 This got me the same result as in appending CRC to the last chunk of data. 这得到了与将CRC附加到最后一块数据相同的结果。

In the Android version of the application the whole data is sent, so I know that the device can read >20 bytes on a single command. Android版本的应用程序中,整个数据都被发送,所以我知道设备可以在一个命令上读取> 20个字节

My questions are: 我的问题是:

  1. Is it possible to send the whole data in chunks to the external device without modifying the peripherals hardware / software? 是否可以将整个数据以块的形式发送到外部设备而无需修改外围设备的硬件/软件?

  2. Is there a flag / signal byte in the first chunk of data that notifies the device the length of the whole message? 第一个数据块中是否有一个标志/信号字节,通知设备整个消息的长度?

  3. I've read that in iOS 7 is possible to send a larger byte array. 我已经读过在iOS 7中可以发送更大的字节数组。 If I make support for iOS 7+ will it solve my problem? 如果我支持iOS 7+它会解决我的问题吗?

  4. What alternatives do I have to CB? CB有哪些替代方案?

Any help will be appreciated. 任何帮助将不胜感激。 Many thanks! 非常感谢!

EDIT 编辑

When I try sending data in chunks like in the BTLE sample I get the following response: 当我尝试像BTLE示例中的块一样发送数据时,我得到以下响应:

// NSLog - data that is written on the peripheral
// Chunk 1 : <2047d001 0f002000 315b0011 b4425543 41524553>
// Chunk 2 : <54202020 20202020 20202020 20202020 20202020>
// Chunk 3 : <20202020 2009059b 56210988 b9b50408 02c7123d>

// Write to peripheral
[self.twCurrentPeripheral writeValue:chunk1 forCharacteristic:self.twCharacteristic type:CBCharacteristicWriteWithoutResponse];
[self.twCurrentPeripheral writeValue:chunk2 forCharacteristic:self.twCharacteristic type:CBCharacteristicWriteWithoutResponse];
[self.twCurrentPeripheral writeValue:chunk3 forCharacteristic:self.twCharacteristic type:CBCharacteristicWriteWithResponse];

// NSLog - Response from peripheral
// Data update char : <20470000 04d00101 00ab42>
// Data update char : <204700>
// Data update char : <0004d001 0100ab42>
// Data update char : <204700>
// Data update char : <0504d001 032c6bcf>

The correct response should be (like in the Android version): 应该是正确的响应(如在Android版本中):

// Response <20470000 04d00101 00ab42>
// Response <20470000 04d00105 006786>

You need to send the data in 20 bytes chanks. 您需要以20个字节的信号发送数据。 Each packet should be at the size of 20 bytes. 每个数据包的大小应为20个字节。 The other side (the BLE central) should accept the packets and save them until he gets all the packets he was waiting for. 另一方(BLE中心)应该接受数据包并保存它们直到他获得他正在等待的所有数据包。 For this to happen you will have to create some kind of protocol: Sending the type of message then the length of the message in bytes and the centeral should read this header and then save the "length" bytes he is waiting for in this message and then parse the entire data. 为此,您必须创建某种协议:发送消息类型然后以字节为单位的消息长度和中心应读取此标头,然后保存他在此消息中等待的“长度”字节然后解析整个数据。

Note that IOS might fail sending some of the packets when there are many packets to send very fast, so when calling 请注意,当有很多数据包发送速度非常快时,IOS可能无法发送一些数据包,因此在调用时

 success = [self.peripheral updateValue:chunk forCharacteristic:myChar onSubscribedCentrals:nil];

success will tell you if the send was successful, if it was not you need to resend this packet. 成功将告诉您发送是否成功,如果不是,您需要重新发送此数据包。 in that case you should implement the IOS BLE protocol CBPeripheralManagerDelegate 在这种情况下,您应该实现IOS BLE协议CBPeripheralManagerDelegate

and at the method peripheralManagerIsReadyToUpdateSubscribers you should retry sending the same packet again. 在方法peripheralManagerIsReadyToUpdateSubscribers您应该重试再次发送相同的数据包。

You need to chunk the data in 20 byte length pieces, you got that part right. 你需要以20个字节长度的块来分块数据,你得到了那个部分。 If you use the "write with response" method, then before sending the next piece of data, you should wait for the peripheral:didWriteValueForCharacteristic:error: callback to happen on your peripheral delegate before sending the next piece. 如果你使用“write with response”方法,那么在发送下一段数据之前,你应该等待peripheral:didWriteValueForCharacteristic:error:在发送下一段之前在你的外围代表上发生回调。 In case of "write without response", you should wait before sending out the next chunk. 在“无响应写入”的情况下,您应该在发送下一个块之前等待。 The stuff you add in the in the writeValue call will be buffered. 您在writeValue调用中添加的内容将被缓冲。 If the buffer is full, then your call will be dropped. 如果缓冲区已满,则您的呼叫将被删除。

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

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