Inexpensively Program Your Arduino via Bluetooth

Updated 11-26-2017

Video Overview of this Article

I like working with Arduino boards as a quick way to prototype the odd gadget, or the occasional gizmo, but having to program them via USB cables can be a pain.  So, I decided to investigate ways to do this wirelessly.  There are off the shelf solutions to this problem, such as the official Arduino BT (Bluetooth) board (now, apparently, discontinued), or the wonderful Bluefruit EZ-Link module from Adafruit, but I wanted to see what was possible using one of the really cheap (~$4) Bluetooth modules you can get on eBay.  One such device is often labeled the HC-05 module, of which (caution) there are many variations, but more on that in a moment.  I wound up purchasing a pair of modules that look like this:

Click for larger view

NEW 11-26-2017: If your HC-05 module is labelled with arrows on the back I suggest that you ignore them, as they're more confusing than helpful.  For example, in the photo above, you can see that the STATE pin has an arrow pointing toward the pin, which might suggest to you that this is an input pin.  It's not.  Neither is the RXD pin an output.  If you think of the arrows as pointing toward the circuitry on the other side of the PCB rather than toward the pins, then the arrows make sense.  However, for clarity, here's a table that shows the correct I/O directions for the pins:

Each HC-05 "module" is actually built from a component Bluetooth board that's been mounted onto another PCB on which is added a 3.3 volt regulator, an LED, a pushbutton and several other passive components.  The module came with no documentation, but I was able to reverse engineer the following, approximate schematic:

Click for larger view

Unfortunately, there are a great variety of modules on the market that all look roughly similar to the modules I purchased.  There seem to be two main variants.  One is based on an HC-05 Bluetooth module.  This version supports an extended set of AT commands that allow it to reprogrammed to act as ether a Bluetooth Master, or Slave, as well as configure other features, such as the default baud rate.  The other variant is based on an HC-06 module.  This kind can only act as a Bluetooth Slave and requires a different method to configure it with AT commands.  I tried a few of the HC-06 variants, but found them frustrating to use, so I don't recommend using them, especially as they're usually not any cheaper.  However, it can be tricky to identify what you're buying, as HC-06 modules are sometimes identified as HC-05 modules.  So, here are a few things to look for when trying to purchases the HC-05 variant:

Also, be careful that you don't inadvertently purchase a blank carrier PCB, as some vendors sell these and a quick look at the photo may show something that looks similar to the back side of the module pictured above, but that does not have a Bluetooth module soldered onto the other side.

Using the HC-05

As delivered, the module can be hooked up to 5 volts for power and can be paired with a bluetooth-equipped computer to provide a serial link that's preprogrammed to operate at 9600 bps, 1 stop bit with no parity.  The module works as a transparent serial link the moment it's powered up.  However, if you press and hold down the pushbutton switch as the module is powered on, you can place it into a special mode where it runs at 38400 bps, and accepts and responds to AT-type serial commands.  I connected a 5 volt, FTDI-type USB to Serial adapter to the module according to the following diagram to reprogram my module:

Click for Larger View

NEW 11-26-2017: See the section at the bottom of this page on how you can also order an adapter board to implement the programming connections shown above.

Next, I put the module into programming mode by holding down the pushbutton on the HC-05 module as I powered up the assembly.  In response, the LED on the HC-05 module will begin to blink on and off very slowly.  Then, I used the Arduino IDE's Serial Monitor function to send commands to the module (select the FTDI as if it were an Arduino board and set Serial Monitor 38400 baud) one at a time and set to send "Both NL & CR".  Here's the sequence I sent (blue) and the response I received back (green):

AT+UART=57600,0,0

OK

Note: you can verify the baud rate change by typing the following command and check for the indicated response:

AT+UART

+UART:57600,0,0

OK

This reprograms the power on baud rate (does not change baud rate in programming mode) to the rate typically used by the Arduino boot loader (note: this varies from one Arduino to another, so verify the rate your Arduino uses first!)  However, here's a quick guide to help you match the needed baud rate to the particular Arduino board you're using (Updated 11-29-2017):

Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328P 57600

Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P 57600

Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 19200

Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 19200

Arduino Yún                                         57600

Arduino/Genuino Uno                                115200

Arduino Duemilanove or Diecimila w/ ATmega328P         57600

Arduino Duemilanove or Diecimila w/ ATmega168         19200

Arduino Nano w/ ATmega328P                         57600

Arduino Nano w/ ATmega168                         19200

Arduino/Genuino Mega w/ ATmega2560                115200

Arduino Mega w/ ATmega1280                         57600

Arduino Mega ADK                                115200

Arduino Leonardo                                 57600

Arduino Leonardo ETH                                 57600

Arduino/Genuino Micro                                 57600

Arduino Esplora                                         57600

Arduino Mini                                        115200

Arduino Mini w/ ATmega168                         19200

Arduino Ethernet                                115200

Arduino Fio                                         57600

Arduino BT                                         19200

LilyPad Arduino                                         57600

LilyPad Arduino w/ ATmega168                         19200

Arduino NG or older                                 19200

Arduino Robot Control                                 57600

Arduino Robot Motor                                 57600

Arduino Yún Mini                                 57600

Arduino Industrial 101                                 57600

Linino One                                         57600

Arduino Uno WiFi                                115200

Optiboot (upgrade to the Arduino bootloader)           115200

I also decided to reprogram the pairing password from the default value of 1234 to 0000, which is the default used by Bluetooth on OS X.  You can do this using this command:

AT+PSWD=0000

OK

And, if you have multiple HC-05 modules and want to tell them apart, you can use this command to rename the module.  I chose to name my pair of modules HC-05A and HC-05B, like this:

AT+NAME=HC-05A

OK

Once the commands are complete, power cycle the HC-05 and you should find that the changes you've made have persisted and that the module will now run at this new baud rate and using the new password code and name (if set.)

One More Trick Needed

The final bit of magic needed to make this work is to add a circuit that emulates the RESET the Arduino normally gets from the FTDI serial chip (or equivalent.)  This RESET signal is driven by the DTR signal from the FTDI chip and is used to put the Arduino into programming mode by briefly pulling the ATMega processors RESET line LOW by using a 10K resistor and a 0.1uF capacitor as an RC differentiator circuit.  When the DTR line goes low, it momentarily pulls the RESET line low before the 10K resistor pulls it high again as it charges the capacitor.  Without this LOW-going RESET signal, the Arduino will never engage the boot loader and you will not be able to upload code.  Here's a typical example of the circuit used to generate the low-going RESET signal from the DTR input:

Click for Larger View

The HC-05 module exports a signal called STATE that goes HIGH whenever the serial link becomes active, but we need a low-going signal to trip the Arduino's RESET line.  This can be accomplished by means of a simple, transistor-based inverter circuit.  The design I came up with to do this also adds an RC differentiator circuit to the input of the transistor, so the transistor's collector should be connected directly to the Arduino's RESET pin.

Click for Larger View

Note: none of the components in this circuit are especially critical.  You can probably use just about any NPN transistor you might have handy and you can vary the value of the resistor, or capacitor by a fairly wide range and still have a suit that works.  In essence, the circuit works like a differentiator and converts the rising edge of the STATE pulse into a LOW-going pulse that lasts for a duration set by the RC network formed by the resistor and capacitor. 

Finally, to put all this to practical use and connect the HC-05 module with this new RESET circuit to the Arduino, simply connect everything together, like this:

Click for larger view

The exact locations of the pins on the Arduino will vary depending on the type of Arduino board used, but the essential connections are shown above.  The 2K and 3K resistors shift the 5 volt logic level of the TX signal from the Arduino down to the 3.3 volt logic level used by the HC-05.  The circuit also includes a buffer between the HC-05's Tx pin and the Arduino's Rx pin.  This is needed when the Arduino you're using has an on-board USB to Serial convertor.  In this case, the Rx and Tx on the Arduino's processor chip are connected to the USB Serial Adapter chip through 1K resistors.  Adding the buffer boosts the weak, 3.3 volt Tx signal from the HC-05 making it strong enough to over power the signal coming from the USB Serial Adapter.  You can use nearly any type of CMOS-based buffer for this.  Good candidates are the 74HC4050, or CD4050B.  Or, for a compact solution, the SN74LVC1G17DBVR.

You'll then need to perform a pairing operation between the HC-05 and your computer before you can select and use the bluetooth serial port in the Arduino IDE.  Once paired, you should be able to select the HC-05 from the Arduino IDE's "Port" menu.  Once selected, you should be able to click "Upload" to compile and upload new code as long as the HC-05 and it's connected Arduino remain powered up.  One caution, however.  I recommend that you unpair the HC-05 when you're done using it, as leaving the HC-05 paired with a computer when the HC-05 if powered off will generally cause all programs thats can for USB serial ports, to start up very slowly, as they have to time out while looking or paired ports that are not currently available.

A Slightly Simpler Approach for an Arduino that uses an FTDI Adapter for Programming

After testing the above circuit, I decided to use OSH park to build a small PCB that can act like an FTDI serial adapter and plug into processor boards like the Arduino Mini, or Pro Mini (5 volt versions) that have a port where you normally connect an FTDI USB Serial Adapter in order to program it.  This design replaces the transistor, 10K resistor and the .01uF capacitor with a SN74LVC1G14DBVR Schmitt inverter in an SOT-23-5 package and the same two, 2K and 3K resistors as in the above circuit for 5V to 3.3V level conversion.  Note: this circuit is designed to only work with an Arduino, such as the Pro Mini, that has a FTDI connector to connect to an external FTDI USB adapter for programing.  Here's the schematic:

Clock for larger view

If you're familiar with working with surface mount parts, the PCB is easy to assemble and requires on a pair of 6 pin, right angle headers to complete.  Here's a photo of the assembled PCB connected to a 5 Volt Arduino Pro Mini:

Click or larger view

Caution: Reversed FTDI Pinout

Be careful to correctly identify the orientation of the FTDI pinout on the Arduino Pro Mini PCB you're using, as some of them the pins in one order and other have them in the reverse order.  The following show this using a Sparkfun Pro MIni as compared to a Chinese-mased clone Pro Mini I purchased on eBay.  I'm actually not sure which pin order is correct as, if you search for "Arduino Pro Mini pinout" you'll see many different versions shown.  I've labelled the pins on the adapter board to make it easier to connect the correct pins.  Just be aware that you may need to flip the adapter board over to properly connect with some versions of the Pro Mini.

Click for Larger View

If you'd like to build this HC-05 adapter for the Pro Mini, the PCB can be ordered from OSH Park by clicking here.  A set of 3 PCBs will cost you $1.80.  The other parts can be ordered from Mouser, or Digi-Key, but be sure to get the SOT-23-5 version of the SN74LVC1G14DBVR Schmitt inverter.  The two resistors are 0603 (Imperial) / 1608 (Metric) surface mount resistors.  I recommend using thick film, 1% resistors, as they're cheap and available from many different manufactures and don't stress about exact values.  Anything close to 2K and 3K will work fine.  And, of course, please read the above text to understand how to purchase a compatible HC-05 module and program it to the proper baud rate.

HC-05 To FTDI Programming Adapter

NEW 11-26-2017: For convenience I decided to create a simple adapter board for connecting an un-programmed HC-05 to an FTDI Serial Adapter instead of using jumper wires as shown in the video.  This adapter does nothing more than to reroute the signal so you can more easily connect the HC-05 to an FTDI Adapter in order to do the one-time setup needed to configure the HC-05's baud rate and other parameters.  Here's a phot that show the assembled adapter being used for this purpose:

Click for larger view

If you'd like to build one, you can order the PCB from OSH Park for about $1.80 for three of the boards.  Or, you could just wire up an equivalent adapter using perf board.