Tinkering with Raspberry (and other things)

Bluetooth Serial Communication with HC-05


Adding bluetooth support for a mouse or keyboard is easy with the Raspberry Pi. Things go a different route as soon as you’re trying to communicate with other electronic gadgets. There are numerous howtos and instructables out there that do serial communication via bluetooth. But all of them (at least those I have read) use bluetooth modules connected to the serial port of the Raspberry Pi. I had a similar solution at first, but then I accidentally connected one of my bluetooth modules the wrong way and fried it…  Here’s a picture of it. Before frying it, I added a sticker (“S” for Slave) that is now burned, too.


In the lower right is the voltage regulator that literally exploded. However, these specific modules are cool for tinkering, as they allow TTL (5V) levels!

The HC-05 modules are very clever pieces of hardware, as they translate incoming bluetooth communication to serial data. So once configured this gives the tinkerer the possibility to achieve serial communication over bluetooth. The HC-05 acts transparently, meaning that you just communicate with the serial port it is connected to and the module then sends/receives via bluetooth.

To be able to continue tinkering with communications I gave the “Bluetooth USB Dongle” with Raspberry Pi alternative a second chance. Weeks ago I have not been able to get bluetooth running using a serial communication protocol. In fact, I was not even able to pair any of my computers and the Raspberry Pi.

My plan is to modify my LED sign to wireless communications. As a proof-of-concept I am going to use my Raspberry Pi – with attached bluetooth USB dongle – to communicate with a HC-05 bluetooth module connected to an Arduino.

To quote from “The Big Bang Theory”: “Everything is better with bluetooth!”

As I mentioned, I was not able to pair any of my computers with the bluetooth dongle on a Raspberry Pi. So I am going to use a bluetooth module with an Arduino to check connection, pairing and communications. So this tutorial will start with the Arduino part, explaining the set-up and use of the HC-05 bluetooth module. The second part covers the installation and configuration of bluetooth on the Raspberry Pi. Finally, I will show you how to implement a communication protocol with handshaking between the Arduino and the Raspberry Pi. So let’s start.

The HC-05 bluetooth module

These modules are very cheap to buy. If you feel adventurous, order them direct from China… The actual module is the green board that sits on the breakout board in my model. The pure HC-05 will only work on 3.3V levels, not with 5V-TTL-levels. So one would need level shifters (again). The board I ordered has a voltage regulator and some 1k Ohm resistors (the SMD types labeled “102”) on the signal lines. This is in fact the simplest and cheapest form of protecting a 3.3V circuit against 5V. Take a look at the front and back:


The connections and their purpose:

  • KEY: if set to HIGH module goes into command mode for configuration – only 3.3V input!
  • RXD: the RXD signal line – 5V safe
  • TXD: the TXD signal line – 5V safe
  • 5.0: connection for 5V supply voltage
  • 3.3: connection for 3.3V supply voltage
  • GND: Ground

Be aware that the module must be connected to either 3.3V or 5V. The complete technical data and all supported commands can be found at Itead’s blog or from Roger Schaefer’s

Module Set Up

Before being able to use the modules they need to be configured. A breadboard and some wires would be extremely helpful! I am going to use an Arduino loaded with a sketch that simply reads from one serial port and transmits this data to the other serial port. Here’s the sketch:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
  // Open serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only


  // set the data rate for the SoftwareSerial port

  // for HC-05 use 38400 when poerwing with KEY/STATE set to HIGH on power on

void loop() // run over and over
  if (mySerial.available())
  if (Serial.available())

Connect the module to the Arduino as follows:

HC-05 module ------ Arduino
    GND      ------   GND
    3.3      do not connect
    5.0      ------    5V
    RXD      ------    D11
    TXD      ------    D10
    KEY      do not connect

On my breadboard I additionally run a wire from 3.3 to an empty row and another wire from KEY to another empty row. Now to enter command mode I just need to connect those two wires. Here’s a (rather bad) picture of my breadboard wiring:


The wires from top to bottom:

RED    ----  KEY (free spot on board)
ORANGE ----  RXD D11 Arduino
BLUE   ----  TXD D10 Arduino
ORANGE ----  5V Arduino
YELLOW ----  3.3V (free spot on board to short with red wire later)
GREEN  ----  GND Arduino

Now for a first start connect the red and yellow wire on the breadboard, power the Arduino and upload the sketch. Don’t forget to edit the baud rate setting. When the KEY-pin is HIGH on startup, the module switches to 38400 baud, no matter what baud rate was set for communication. Open the Serial Monitor from the Arduino IDE, set it to send”Both NL and CR” and type “AT”. If you get nothing or an error, the HC-05 is not yet initialized. Wait and type “AT” again. You now should get an “OK” as response. If nothing happens at all, ie no response at all, check the baud rate set in the Arduino sketch.

The following are the most important commands needed to get the HC-05 module going. The commands follow typical AT-syntax. That means with “AT+cmdname?” you query the parameter from cmdname, with “AT+cmd=xxxx” you set the parameter to xxx.

AT+NAME    get/set name
AT+ADDR?   get address of module (xxxx:xx:xxxxxx). This is the MAC address, write it down.
AT+UART    get/set communication parameters in format: baudrate, stopbits, parity. 
           Set to 9600,1,0 with AT+UART=9600,1,0
AT+ROLE    get/set role. 0=SLAVE, 1=MASTER. Set to SLAVE

For the screenshot I just queried the parameters (they were set already):


In command mode every line sent needs to be terminated by NL+CR (“\n\r”), otherwise the module will be sending the response indefinitely until it has received another command.

During my experiments I discovered that I could enter command mode after powering up by just setting the KEY line to HIGH. The module would then switch to command mode using the baud rate set for communication. Upon disconnecting the KEY line I was able to use the module for normal communications without a restart. This is contrary to what they say in the manual. I do not know why this works for me. If you have difficulties connecting to the modem after command mode was left, just switch the module off and on again.

Raspberry Pi setup

On the Raspberry Pi side I was finally able to get bluetooth going with an ordinary USB bluetooth dongle. And this was pure coincidence, as I had tried this before and spent days not making any progress. One reason for this is that bluetooth support for Linux is not well documented. In fact, it is not documented at all. Everything you find on the internet refers to version 3 of the bluetooth modules, the current version is 4, they changed almost everything and did not document it. Read this blogpost for more details.

The first step is to install bluetooth support for the Raspberry Pi. These packages will install myriads of other stuff, so plan on spending some time before the terminal. I have not yet figured out which packages could be safely purged after installation. So here we go:

sudo apt-get install bluetooth bluez-utils

After everything is installed plug in your Bluetooth USB dongle. I used a KeySonic dongle that came with a bluetooth keyboard. Then check with lsusb if the device gets recognized. You should get something like this:

Bildschirmfoto 2013-11-20 um 15.02.40

Switch on the Arduino with the HC-05 connected and the sketch from above loaded. It’s time to scan for devices from the Raspberry side of things. Type in hcitool scan and this should get you:

Bildschirmfoto 2013-11-20 um 15.05.59

This is the name and the MAC address of the device we configured from the Arduino. Now every manual on the internet begins referring to the sdptool command to discover services and channels. This is not needed. You may also read something about editing configuration files to add support for the SPP protocol and so on. This is not needed, in fact it didn’t work for me at all. So this time I deliberately skipped these steps.

The only configuration file that needs editing is the rfcomm.conf file, where we will add a permanent connection to the module we just discovered. I’m using nano as an editor here. Type in

sudo cp /etc/bluetooth/rfcomm.conf rfcomm.conf.orig
sudo nano /etc/bluetooth/rfcomm.conf

The first line just copies the file we are editing. In case things do not work out one can always revert back. Edit the rfcomm.conf file that it looks like this: Just change the address to the address of your HC-05 module and set the comment to whatever you like.

# RFCOMM configuration file.
rfcomm0 {
 # Automatically bind the device at startup
 bind yes;
# Bluetooth address of the device
 device 98:D3:31:b0:80:6C;
# RFCOMM channel for the connection
 channel 1;
# Description of the connection
 comment "LS-ONE";

The HC-05 modules come with a passkey configured. The default PIN is “1234” and can be set using the “AT+PIN=xxxx” command. To enable us to automatically connect to the module, this pin needs to be written to a file called “pincodes” that is located under “/var/lib/bluetooth/xx:xx:xx:xx:xx:xx/”, where xx… is the MAC address of the bluetooth dongle plugged into the Raspberry Pi.

The easiest way to edit this file is to use the “echo” command to append a line to the file:

sudo echo "98:D3:31:B0:80:6C 1234" >> /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/pincodes

Just type in until right after “bluetooth/” and then use the shell’s autocomplete feature by pressing the TAB key.

Time for a first test. Therefore the bluetooth service needs to be restarted:

sudo /etc/init.d/bluetooth restart

By now a device called /dev/rfcomm0 should have been created. If the Arduino is not running, start it and start the Serial Monitor. As a first test we are going to echo something to the rfcomm0-device. In the raspberry terminal type:

echo "TEST" > /dev/rfcomm0

If everything went well, you should see “TEST” appearing in the Arduino Serial Monitor. If you get any permissions errors try using sudo first. If that succeeds you can add the user pi to the group dialout. The rfcomm0-device is writable for this group, so adding the user to this group gives you write access to the device. To add the user type:

sudo adduser pi dialout

That was easy. But how about reading input? We do a quick test with the cat command. This command reads characters from the given device and echoes them to the terminal:

cat /dev/rfcomm0

Now type something in the Arduino Serial Monitor. It should appear in the Raspberry Pi’s terminal. To end the cat-command, type CTRL+C. Here’s how that should look like:

Bildschirmfoto 2013-11-20 um 15.45.13


The HC-05 module is easy to handle and can be accessed from the Raspberry Pi. If you opt to buy one or more of these modules make sure that you get the “HC-05”, as the “HC-06” can not be switched between Slave and Master mode. The cheapest units can be found (of course) on ebay. Just go to your local ebay page and use the search terms “rs232 bluetooth ttl”. Often there is a dealer nearby where the modules are 1 or 2 bucks more expensive, but postage and packaging is free and you will get your module faster than ordering in China/Hong Kong. I ordered mine from England.

The Raspberry Pi can be used with a cheap bluetooth USB dongle to connect to another bluetooth device. It is possible to use serial communications, thus we can use Python or any other language to communicate. With editing rfcomm.conf and the pincodes file the connection is automatically made whenever a program or script is writing to the rfcomm-device.

And as this post now reaches 2000 words I am going to split it here. The next post will be about establishing/developing an easy protocol for communication. Main goal is to send commands to an Arduino and have the Raspberry Pi wait for the Arduino to be ready to receive more data. All for the greater goal of remotely controlling an LED marquee via bluetooth…


10 thoughts on “Bluetooth Serial Communication with HC-05

  1. Pingback: AM03127 LED marquee + Arduino + Bluetooth = RaspberryPi remote control | MyRaspberryAndMe

  2. the arduino yun has no way to get the “bluetooth” package. but bluez, bluez-utils etc. so i got it working to some extent (hciconfig and hcitool inquire/scan correctly, my android phone connects to the dongle,… but pairing anything with the dongle with “hcitool cc” won’t work… also: many directorys/files you talk about, don’t even exist on the yun: e.g. /init.d/bluetooth or pincodes….sudo echo “98:D3:31:B0:80:6C 1234” >> /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/pincodes… created that file and folder myself but still didn’t help with pairing

    • Correct, Arduinos do not have these packages. The instructions mentioning installing bluez etc. and editing init.d are for the Raspberry Pi! Only the first part of the article is about the Arduino side of things.

  3. Yes, I know. I’m trying to make it happen with an Arduino Yun (has a Linux-side/OpenWrt) and an UNO as the slave (with a HC-05 bluetooth-module)… sadly no one on the whole internet tried to make a usb dongle work properly with the yun. One guy made the yun ibeacon-aware (=basically only inquiring/scanning for other devices) with a dongle , but not actually use the dongle to pair devices… So your raspberry pi – tutorial is basically the best I’ve got

    • Sounds tedious. I don’t even think that building the bluez-stuff from source on the Yun’s Linino-Linux may work. That is (I am going to rant again…) a typical “linux and bluetooth” issue. Those guys that are doing the bluez stuff are just rogue programmers. No documentation, nothing 😦
      I wish you luck with the Yun! As I do not own one, I can’t help you any further. Sorry.

  4. Reblogged this on Finnian_Anderson and commented:
    Great post! Will definitely be using it!

  5. Why do I get this in the Arduino IDE?

    ‘SoftwareSerial’ does not name a type

  6. You could also try and connect the HC-05 module to the pi serial port ( and control the serial using nodejs for example).
    Check this
    Watch out for the 3.3V but as fast as I know the HC-05 RX/TX and the PI are all 3.3V
    This way you can create a virtual serial connect from PI to other HC-05 module connected to an arduino for example
    (PI will be the master and the arduino module will be set as slave)
    to configure the 2 module – you should use th AT commands: