arduino remote programming with the bluetooth mate (RN-42)

I went downtown today to grab a tea with Behdad and pick up some electronics for a fun weekend project: a Mini Arduino Pro and a Bluetooth Mate. It turns out that although these two components are designed to work together, they don’t work very *well* together. I’m writing this so that anyone else who tries to plug these two devices into each other can save some time.

[[ Some background for those unfamiliar with the way the Arduino is programmed: The Arduino contains a bootloader that runs for the first moment after the device is powered on or reset. It’s possible to communicate with this bootloader using a serial protocol during this time. After the timeout, the software that you loaded onto the board takes over. The tricky part is the timing of sending your code while the bootloader is running. To help with this, the reset pin on the Arduino is wired to a pullup and a capacitor that connects to the DTR input. This means that pulling the DTR active (low) is enough to briefly pulse the reset line (until the pullup recharges the capacitor). This causes the Arduino to reset when a serial connection is made which helps ensure that the computer sending the code over will find a bootloader on the other side. ]]

The Bluetooth Mate (made by Sparkfun) attempts to come close to the pinout of a standard FTDI cable (for compatibility with various Arduino boards that pair with this cable). Unfortunately, it falls short in a major way: where the DTR pin is supposed to be there is instead a RTS output. This wouldn’t be such a big deal (since both are often turned on at the same time anyway) except that the RTS pin is wired through to the local UART for the RN-42 rather than the signal from the host computer.

This means two things. The first is that if your Arduino is sending data to the serial port faster than it can be transmitted out over Bluetooth, the RN-42 will attempt hardware flow control by dropping the RTS line, causing the reset signal to pulse. Your board will reboot in the middle of whatever it was doing.

Possibly worse is that the host is prevented from signalling the start of the programming sequence which pretty much makes programming over Bluetooth impossible unless your timing at manually pressing the reset switch is very good.

Fortunately, the hardware flow control signals are available as output pins on the RN-42 itself and the problem is merely that they aren’t wired through to the pin header. The RN-42 datasheet lists pins 33 and 34 as “PIO10” and “PIO11”. It also incorrectly labels them as “Input to RN42 with weak pulldown”, so it’s best to ignore that part if you’re reading the datasheet.

The RN-42 AT Command Set reference linked from the Sparkfun product page mentions in Sections 6.1 and 6.2 that PIO10 and PIO11 can be used to output the host DTR and RTS if the device is in DUN-DCE mode. It also mentions that the DTR signal is active high, which is a problem for us, because the DTR pin needs to be pulled low in order to cause the Arduino to reset.

Fortunately the RTS pin is active low and is active at the same time as the DTR when programming so using RTS will work okay. It’s not a perfect solution because it’s possible that the host computer could attempt hardware flow control and accidentally reset the board instead but that’s unlikely as long as your software can keep up.

A more correct solution would probably involve using a transistor to flip the DTR signal. There’s a FET on the board (Q2 in the schematic) that’s used to raise the RTS signal from 3.3V to 5V. Since it’s quite likely that you don’t want to use that line anymore, cutting some traces, removing the input pullup resistor and soldering on some new connections (DTR to gate, ground to source) would be enough to repurpose it, and as a bonus it’s even already connected to the correct output pin. I didn’t do this because I didn’t want to make too many modifications to my board.

One last note: the Arduino I used is a 16MHz atmega328. After some trial and error I was able to determine that it likes to be programmed at 57600 instead of the more usual 115200 baud.

All that said, here’s the way to get a Mini Arduino Pro working with a Bluetooth Mate:

  1. despite both boards having a pin header with 6 positions, solder only a 5-pin connector on the Bluetooth Mate (skipping the RTS pin)
  2. solder a lead on to pin 33 of the RN-42 module (see picture) and plug that into the DTR input on the Arduino board instead
  3. enable the RTS pinout by setting the RN-42 to DUN-DCE mode: enter command mode (‘$$$‘ within 60 seconds of power on) and send ‘S~,1
  4. change the baud rate of the RN-42 to 57600: ‘SU57.6‘ in command mode

After all of that it should now be possible to program the board over Bluetooth and the board should stop spontaneously resetting itself when sending large amounts of data.

On the software side of things, the “official” Arduino IDE seems to have some pretty serious problems when dealing with Bluetooth devices. It seems to enjoy opening all the serial ports on your computer every time you click on the menubar(!) which causes the entire application to freeze as the kernel attempts to establish the Bluetooth rfcomm connection. Programming is also problematic since the IDE claims that the device is already in use (and when you check which process is using it, is the IDE itself). Using avrdude directly is a good substitute. In order to do that, pair with the device (pin is 1234) and then:

  1. rfcomm bind 0 aa:bb:cc:dd:ee:ff
  2. avrdude -v -patmega328p -carduino -P/dev/rfcomm0 -b57600 (programming commands here)
    1. If you happen across this page and find that I’ve made a mistake somewhere, please comment below so that I can fix it.