4

I've been trying to read data from a device via Bluetooth 2.1 using an RN-42. The device pairs to an iPhone or iPad Mini, and data is streamed across briefly, but the iOS & BT module disconnect (unpair) within seconds (less than 10). The device is outputting data 5-10kB/s, so well within Bluetooth’s spec. Something that I’ve also noticed is that when I run the function NSInputStream, [NSInputStream read: maxLength:], the number of bytes returned is always 158 or less. The app and hardware don’t crash, but the Bluetooth just unpairs.

The device is still sending data to the RN42 even after the disconnect, which reduces the likelihood of a problem on the electronics side. This setup also works perfectly fine on Android devices. I can stream data without any disconnects or crashes.

Things I’ve tried...

  • followed the External Accessory example, EADemo, provided by Apple.
  • purely using the run-loop instead of polling.
  • putting the stream on a background thread as suggested in this post.
  • removing all NSLogs to help with performance.
  • compiled in debug and release modes.

One thing which sort of works is slowing down the data transfer (i.e. less than 5kB/s), as that allows the iOS and BT module to stay connected and transfer data longer before disconnecting.

#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;
    [...]
Rami Alhamad
  • 281
  • 1
  • 3
  • 9

1 Answers1

5

I've spoken with guys at Microchip (the company that bought Roving Networks, who were the original makers of the RN42) about this type of problem, and it seems that there is an unfortunate little "feature" that is not documented anywhere in the RN42 manuals.

When the RN42 is used to communicate with an iOS device, it cannot communicate faster than 2.5-3kB/s... If it's used to communicate with an Android or computer or anything else, it can transfer at 35kB/s (over SPP).

The reason for this is an under-powered chip in the RN42, which can't handle both the BT stack AND re-packaging bytes in the format an iOS device needs (iAP protocol).

They recommend the following options:

  1. Switch to using a WiFi module.
  2. Implement the iAP protocol on your microcontroller and use a vanilla RN42 to transfer data (which should theoretically be back at 35kB/s).
  3. Buffer data on your device, and send it back at the slower rate.
  4. Use a vanilla RN42, and one of their PIC devices which implements the iAP stack.

I have a polite 5th suggestion... Find a new Apple-supported Bluetooth module.

Additionally, using 4-wire UART communication should help with the crashes.

SJoshi
  • 1,866
  • 24
  • 47
  • did you find another Apple-supported Bluetooth module? I need it too – 4ntoine Feb 25 '15 at 08:23
  • @4ntoine Try the AmpedRF options. They have a good collection of BLE and BT modules. – SJoshi Feb 25 '15 at 15:41
  • Seems to be what i need. But it also seems they don't sell them to regular users? – 4ntoine Feb 26 '15 at 03:59
  • If this is a hobby project that you're buying a few for? Probably not. If this is 1k < x < 10k units, they will. ST Micro white labels their BT33 as an SPBT2632, but with crappier firmware - works well enough. Alternatively, I think Arrow is an AmpedRF distributor, so that could be an option. – SJoshi Feb 26 '15 at 04:07
  • This is hobby project (iOS App project) but it requires some hardware solutions that app users should be able to do themselves or buy in the store. So i expect to find or develop myself (and users should be able to upload it to BT module without extra charges) Bt module firmware or just find suitable bt module. I'm not going to develop new hardware, but software only – 4ntoine Feb 26 '15 at 06:24
  • Okay, just an FYI if you didn't know, but to use Bluetooth classic with iOS, you need an MFI module - and Apple doesn't really give those away easily. – SJoshi Feb 26 '15 at 13:39
  • yes, i'd be happy to find MFi-certified BT 2.1 module under $10 which i can buy in store – 4ntoine Feb 26 '15 at 17:49
  • Any update on another MFi-certified Bluetooth module? – Arenzel Aug 25 '17 at 16:58
  • @Arnlen I haven't used Bluetooth Classic in a while - stick with BLE 5.0 - and you'll have better support across the board (no MFI) – SJoshi Oct 15 '17 at 07:18