ios - RN42 蓝牙在传输数据后几秒内在 iOS 上断开连接

标签 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 以帮助提高性能。
  • 在调试和 Release模式下编译。

其中一种工作是减慢数据传输速度(即低于 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;
    [...]

最佳答案

我已经和 Microchip(收购了 RN42 的原始制造商 Roving Networks 的公司)的人谈过这类问题,似乎有一个不幸的小“功能”没有记录RN42 手册中的任何位置。

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

原因是 RN42 中的芯片功率不足,它无法处理 BT 堆栈和以 iOS 设备所需格式(iAP 协议(protocol))重新打包的字节。

他们推荐以下选项:

  1. 改用 WiFi 模块。
  2. 在您的微 Controller 上实现 iAP 协议(protocol)并使用普通 RN42 传输数据(理论上应该回到 35kB/s)。
  3. 在您的设备上缓冲数据,然后以较慢的速率将其发回。
  4. 使用 vanilla RN42 和他们实现 iAP 堆栈的 PIC 设备之一。

我有礼貌的第 5 个建议……找一个新的 Apple 支持的蓝牙模块。

此外,使用 4 线 UART 通信应该有助于解决崩溃问题。

关于ios - RN42 蓝牙在传输数据后几秒内在 iOS 上断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19711265/

相关文章:

sockets - 如何测试我的远程套接字 NSStream 是否正确打开

iphone - 在使用php上传到服务器之前旋转图像

android - 我如何使用 android,以编程方式向连接的蓝牙设备发送振动命令?

macos - 我应该使用 IOKit 或 DriverKIt(或 HIDDriverKit)为 macOS 中的 USB 或蓝牙多点触控设备编写驱动程序吗?

android - 蓝牙 -> 服务发现失败

ios - 如何在另一个线程上正确打开和关闭 NSStream

Objective-C:逐行读取文件

ios - 无法下载应用程序,此时无法安装应用程序

iphone - 如何在 iOS 5 中访问标签栏 Controller ?

ios - 手动滚动到包含许多 subview 的页面时,带有 UIPageViewControllerTransitionStyleScroll 的 UIPageViewController 滞后