RN42蓝牙在流数据的几秒钟内在iOS上断开连接

时间:2013-10-31 15:57:49

标签: ios bluetooth nsstream external-accessory nsinputstream

我一直在尝试使用RN-42通过蓝牙2.1从设备读取数据。该设备与iPhone或iPad Mini配对,数据短暂流式传输,但iOS& BT模块在几秒钟内(小于10)断开连接(取消配对)。该设备输出的数据为5-10kB / s,完全符合蓝牙规范。我还注意到的一点是,当我运行函数NSInputStream,[NSInputStream read:maxLength:]时,返回的字节数总是158或更少。应用程序和硬件不会崩溃,但蓝牙只是取消配对。

即使断开连接,设备仍然会向RN42发送数据,从而降低了电子设备出现问题的可能性。此设置在Android设备上也可以完美运行。我可以在没有任何断开连接或崩溃的情况下流式传输数据。

我尝试过的事情......

  • 遵循Apple提供的外部附件示例EADemo。
  • 纯粹使用运行循环而不是轮询。
  • 按照本文中的建议将流放在后台线程上。
  • 删除所有NSLog以帮助提高性能。
  • 以调试和发布模式编译。

有一点可行的是减慢数据传输速度(即小于5kB / s),因为它允许iOS和BT模块在断开连接之前保持连接并传输更长的数据。

#define EAD_INPUT_BUFFER_SIZE 1024

/**
 * Stream delegate
 */
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    switch (eventCode) {
[... other cases ...]

        case NSStreamEventHasBytesAvailable:
        {            
            uint8_t buf[EAD_INPUT_BUFFER_SIZE];
            unsigned int len = 0;
            len = [(NSInputStream *)aStream read:buf maxLength:EAD_INPUT_BUFFER_SIZE];

            if(len) {
                // Read successful, process data
            } else {
                // Fail
            }     
            break;
        }
        default:
            break;
    }
}

/**
 * Stream delegate with polling (for better or worse)
 */
    [...]
        case NSStreamEventHasBytesAvailable:
        {            
            while ([[_session inputStream] hasBytesAvailable])
            {
                // Read the data
                NSInteger bytesRead = [[_session inputStream] read:_buf maxLength:EAD_INPUT_BUFFER_SIZE];

                if (bytesRead > 0) {
                    // Read successful, process data

                } else if (bytesRead == 0) {
                    // End of buffer reached
                    return;

                } else if (bytesRead == -1) {
                    // Failed to read
                    return;
                }
            }
            break;
    [...]

1 个答案:

答案 0 :(得分:5)

我和Microchip(收购Roving Networks的公司,他们是RN42的原始制造商)的人谈过这类问题,似乎有一个不幸的小“特征”没有记录RN42手册中的任何地方。

当RN42用于与iOS设备通信时,它的通信速度不能超过2.5-3kB / s ...如果它用于与Android或计算机或其他任何设备通信,它可以35kB / s的速度传输(超过SPP)。

造成这种情况的原因是RN42中的芯片功率不足,无法处理BT设备所需格式的BT堆栈和重新打包字节(iAP协议)。

他们建议使用以下选项:

  1. 切换到使用WiFi模块。
  2. 在您的微控制器上实施iAP协议并使用vanilla RN42传输数据(理论上应该以35kB / s的速度返回)。
  3. 缓冲设备上的数据,然后以较慢的速率将其发回。
  4. 使用vanilla RN42和其中一个实现iAP堆栈的PIC设备。
  5. 我有礼貌的第五个建议......找一个新的Apple支持的蓝牙模块。

    此外,使用4线UART通信应有助于崩溃。