HC-05 Bluetooth with Arduino

Some time ago, I bought a couple of HC-05 Bluetooth modules.  They use the CSR Bluecore 04-External single chip Bluetooth system.  ITead Studio has a great little datasheet for the HC-05.

I wanted to be able to configure the device from the Arduino programatically, but according to the documentation you need to power cycle the chip to get it into AT mode (the mode necessary to send AT commands to the module).  Instead, I have found that you can achieve the same result by simple pulling the RESETB pin low for more than 5ms.  In my code below, I have a function enterATMode() that raises PIO11 HIGH, then resets the module so that it will accept AT commands.  Once I have finished setting the device up correctly with AT commands, I pull PIO11 LOW and then reset the device again, using the function enterComMode.

I list the pin connections in the DEFINES at the beginning of each code block.

HC-05 Slave Mode with Arduino:


/*
Copyright Chris Samuelson 2012
*/

#include <SoftwareSerial.h> //Software Serial Port
#define RxD 6
#define TxD 7
#define Reset 5
#define PIO11 8
#define Led 13
#define RTS 4

SoftwareSerial blueToothSerial(RxD,TxD);

void setup()
{
 Serial.begin(9600);
 pinMode(RxD, INPUT);
 pinMode(TxD, OUTPUT);
 pinMode(Led, OUTPUT);
 pinMode(PIO11, OUTPUT);
 digitalWrite(PIO11, HIGH);
 pinMode(Reset, OUTPUT);
 digitalWrite(Reset, LOW);
 pinMode(RTS, INPUT);
 setupBlueToothConnection();
}

void loop()
{
 char recvChar;
 boolean rtsStatus = true;
 while(1){
 if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
 recvChar = blueToothSerial.read();
 if(recvChar == 'a'){
 digitalWrite(Led, HIGH);
 }
 if(recvChar == 'b'){
 digitalWrite(Led, LOW);
 }
 Serial.print(recvChar);
 }
 if(Serial.available()){//check if there's any data sent from the local serial terminal, you can add the other applications here
 recvChar = Serial.read();
 blueToothSerial.print(recvChar);
 }
 }
}

void setupBlueToothConnection()
{
 enterATMode();
 sendATCommand();
 sendATCommand("UART=57600,0,0");
 sendATCommand("ROLE=0");
 sendATCommand("PSWD=4567");
 sendATCommand("CMODE=1");
}

void resetBT()
{
 digitalWrite(Reset, LOW);
 delay(2000);
 digitalWrite(Reset, HIGH);
}

void enterComMode()
{
 blueToothSerial.flush();
 delay(500);
 digitalWrite(PIO11, LOW);
 resetBT();
 delay(500);
 blueToothSerial.begin(57600);
}

void enterATMode()
{
 blueToothSerial.flush();
 delay(500);
 digitalWrite(PIO11, HIGH);
 resetBT();
 delay(500);
 blueToothSerial.begin(38400);

}

void sendATCommand(char *command)
{
 blueToothSerial.print("AT");
 if(strlen(command) > 1){
 blueToothSerial.print("+");
 blueToothSerial.print(command);
 delay(100);
 }
 blueToothSerial.print("\r\n");
}

void sendATCommand()
{
 blueToothSerial.print("AT\r\n");
 delay(100);
}

HC-05 Master Mode

/*
Copyright Chris Samuelson 2012</pre>
*/

#include <SoftwareSerial.h> //Software Serial Port
#define RxD 6
#define TxD 7
#define Reset 5
#define PIO11 8
#define Led 13
#define RTS 4

SoftwareSerial blueToothSerial(RxD,TxD);

void setup()
{
 Serial.begin(9600);
 pinMode(RxD, INPUT);
 pinMode(TxD, OUTPUT);
 pinMode(Led, OUTPUT);
 pinMode(PIO11, OUTPUT);
 digitalWrite(PIO11, HIGH);
 pinMode(Reset, OUTPUT);
 digitalWrite(Reset, LOW);
 pinMode(RTS, INPUT);
 setupBlueToothConnection();
}

void loop()
{
 char recvChar;
 boolean rtsStatus = true;
 while(1){
 blueToothSerial.print("a");
 delay(500);
 blueToothSerial.print("b");
 delay(500);
 if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
 recvChar = blueToothSerial.read();
 if(recvChar == 'a'){
 digitalWrite(Led, HIGH);
 }
 if(recvChar == 'b'){
 digitalWrite(Led, LOW);
 }
 Serial.print(recvChar);
 }
 if(Serial.available()){//check if there's any data sent from the local serial terminal, you can add the other applications here
 recvChar = Serial.read();
 blueToothSerial.print(recvChar);
 }
 if(digitalRead(RTS)){
 if(!rtsStatus){
 rtsStatus = true;
 Serial.print("rts changed true");
 }
 }else{
 if(rtsStatus){
 rtsStatus = false;
 Serial.print("rts changed false");
 }
 }
 }
}

void setupBlueToothConnection()
{
 enterATMode();
 sendATCommand();
 sentATCommand("UART=57600,0,0");
 sendATCommand("ROLE=1");
 sendATCommand("PSWD=0000");
 sendATCommand("PAIR=0018,e4,0c680a");
 sendATCommand("BIND=0018,e4,0c680a");
 sendATCommand("CMODE=0");
 enterComMode();
}

void resetBT()
{
 digitalWrite(Reset, LOW);
 delay(2000);
 digitalWrite(Reset, HIGH);
}

void enterComMode()
{
 blueToothSerial.flush();
 delay(500);
 digitalWrite(PIO11, LOW);
 resetBT();
 delay(500);
 blueToothSerial.begin(57600);
}

void enterATMode()
{
 blueToothSerial.flush();
 delay(500);
 digitalWrite(PIO11, HIGH);
 resetBT();
 delay(500);
 blueToothSerial.begin(38400);

}

void sendATCommand(char *command)
{
 blueToothSerial.print("AT");
 if(strlen(command) > 1){
 blueToothSerial.print("+");
 blueToothSerial.print(command);
 delay(100);
 }
 blueToothSerial.print("\r\n");
}

void sendATCommand()
{
 blueToothSerial.print("AT\r\n");
 delay(100);
}
<pre>

10 Responses

  1. Kostas February 8, 2013 / 8:22 am

    Hi Rous,

    Very helpfull post, i wonder why you use the RTS pin, and how it helps in slave and master role.
    Also it would be great if you post a schematic so i can see the connection between HC-05 and Arduino.

    Thank you
    Kostas

  2. ahmed February 15, 2013 / 3:26 pm

    great work
    but i noticed that you didn’t use enterComMode() for slave configuration??why??

  3. Xris March 10, 2013 / 1:28 pm

    Thanks for sharing this piece of code and information. I am preparing for my bluetooth project while waiting for the hc-05 to arrive from Hong Kong.

    Greetings.

  4. Joe Wronski June 22, 2013 / 2:40 pm

    The documentation for HC-05 is ambiguous with statements that don’t make sense and some are plain wrong. One vendor published “Can set the parameters and query information via the AT command mode by pulling up 34 feet.” And I’m surprised I can’t make sense of the pair and bind commands sent in the master mode code? The doc linked to says “pair” takes an address and a timeout, yet we have “sendATCommand(“PAIR=0018,e4,0c680a”);” Same parameters for the bind command yet this should be just an address.

    • bilingual techie July 26, 2013 / 1:54 pm

      “feet” here can be a mistranslation for “pin”. That is, “pull up pin 34″

  5. rahul August 11, 2013 / 4:27 pm

    can u add a video ….. this code is not working… i am sending ‘AT’ command in the serial monitor of Arduino…..but it is not displaying any o/p…..

  6. mahesh kumar November 19, 2013 / 3:54 am

    my blue tooth module have only four pins Tx,Rx,vcc,GND and change over switch between normal mode and AT mode. How to set the PIO11 high and low, how to activate the reset from low to high,high to low

  7. gaver January 2, 2014 / 12:50 am

    Can multiple smart phones pair with the HC-05? as in Piconet type of network?
    If so- is there any special commands that have to be sent to HC-05 instructing it to pair with a phone attempting a connection?

    Or is is possible to have the phone send a “key” that t he HC-05 will recognize and facilitate an autonomous connection?

    Thanks for your help and for publishing your findings.

    GP

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>