Maximum BlueSMirF.

July 26, 2013
If you are using a Roving Networks RN-42 (e.g. SparkFun's BlueSMiRF) and need to get anywhere the maximum throughput (~23KB/s), you must use hardware flow control on the UART interface.

Until I started working at Ford on the OpenXC Platform, most embedded concepts were new to me. I had used the Arduino quite bit, but didn’t go much beyond the capabilities of the Arduino libraries.

When I started work to evolve the first OpenXC prototypes into a more robust firmware for the chipKIT (VI firmware), I learned that backing these useful Serial interfaces on the Arduino is something called UART.

Fast-forward a few months, and I’m adding Bluetooth support to the vehicle interface using the BlueSMiRF module from SparkFun. This is a really useful breakout board for the RN-42 that can be very quickly wired up to one of the UART interfaces on an embedded board to make it instantly wireless (using Bluetooth SPP).

Here’s where things got confusing: there’s a lot of data pouring out of a car, so I needed to squeeze every bit of performance out of the RN-42 possible. The RN-42 datasheet (PDF) reports that the maximum data rate is 3Mbps and it supports baud rates up to 921Kbps. After a little tweaking it’s possible to run UART on the chipKIT Max32 way beyond 115200, so you’re ready to pump data into the RN-42 at the limit of 921Kbps.

Except…it really doesn’t work well. The chipKIT happily dumped data at 921Kbps onto the RN-42’s UART Rx/Tx lines, but not all of the data made it through the Bluetooth interface to an Android tablet. After a few seconds, the transfer completely stopped and the RN-42 would become unresponsive - I couldn’t even get back to the command mode (i.e. the $$$ mode) to check the settings.

After a few e-mails with helpful Roving Networks engineers, I discovered my first mistake - too used to the typical Arduino situation, where the data rate is low and things “just work”, I only attached Rx, Tx, 3.3v and ground to the BlueSMiRF and not “those other two” pins - RTS and CTS.

Hardware Flow Control

Those two pins are for hardware flow control, which in addition to some software support on the micro, turn out to be critical for pushing high data rates on UART. The RTS and CTS pins are used by the sender and receiver to throttle the data stream when necessary to keep buffers from overflowing. Without that, the RN-42 is overwhelmed by the amount of traffic and starts dropping data. I wasn’t able to get a good explanation for why it eventually becomes unresponsive, but a decent guess is a bug in the firwmare that leads to an unrecoverable error state (fixed by restarting the module).

Once I enabled hardware flow control, the data stream became immediately much more reliable and the RN-42 never crashed again. However, I did discover one other limitation: even with flow control, the throughput over Bluetooth never approaches anywhere near this theoretical max data rate of 3Mbps. I confirmed with the engineers that the rate is only possible if you run the Bluetooth stack on your micro, and not the RN-42 (at which point…why did you buy the RN-42 with such a price premium, anyway?). The actual maximum throughput over Bluetooth SPP for the BlueSMiRF/RN-42 is about 23KB/s from my experience. As a result, there’s really no reason to use a baud rate higher than 230400 (any data beyond that rate will just be dropped on the floor by the RN-42).

Compared to the theoretical Bluetooth maximum, you do take a hit with the RN-42; for mine and many other applications, I think it’s worth the penalty because it means your micro doesn’t need to run a Bluetooth stack of its own (speaking of which, anyone know of a good open source Bluetooth stack?).