Jan 7, 2014

HC-05 Bluetooth link of 2 Arduino

In my first Arduino bluetooth experiment, I made an automatic connection between 2 Arduino using BlueSmirf modules. Based on the popularity of that post, it seems that many people are trying to do the same.

On the down side, many of the visitors are looking for a solution using the HC-05 (or other HC-XX type) modules with an AT command interface. I planned to eventually use this type of device but never got around to doing it for every bad reason imaginable including procrastination. This delay was clearly unacceptable for Lyman (one of my readers) who decided to send me 2 extra modules he could spare.

On a side note, this kind soul only has 2 followers on Twitter. Please help me fix this grievous situation.

After playing a bit with my new toy, here's what I've got:


In this first simple example, the code sets the module to be either Master or Slave, connects to one hard-coded address and starts the communication loop. While connected, the Master sends 1s and 0s to the slave who is using this 'command' to switch an LED on or off.

You can get the code on this Git repo.

Breadboard diagram (without the reset connection)

The biggest problem was to figure out how to reset the module programmatically. The [not so good] documentation explains how this can be done by cycling the power but the bluetooth chip has a reset pin that is supposed to do the same trick. I have the code to use the reset pin which I got from this blog post and I will test it soon.

On the HC-05 modules I received, the reset pin is not connected which 'forced' me into making a little hack that can barely be noticed...


The next step will be to recreate the same query and auto-connect loop that I did with the BlueSmirf. It should be straight forward since I've already tested all the necessary AT commands successfully.

Edit 1: Get some tips about using HC-05 in this video I made
Edit 2: I have a new post describing the automatic bind of 2 HC-05 module without having to write code.

49 comments:

  1. Could you please post a circuit diagram that is easier to see than the picture? Also, how do you set one of the Arduinos to master? Is there a pin to set HIGH?

    ReplyDelete
    Replies
    1. I've added the breadboard diagram. You can set the master through the code by setting the gIsMaster variable to 1.

      Delete
  2. I'm curious why the Rx and Tx wires are flipped. Are the pins mislabeled on the HC 05? I would think that they would logically connect Rx to Rx and Tx to Tx.

    ReplyDelete
    Replies
    1. I thought perhaps that the pinouts differ on different breakout boards. Mine board is labeled "bt_versions 1.3 hf-mcu" and has pinout [Key 5V GND Tx Rx Sate.]

      Delete
    2. I can see how you would see it that way since Gnd links to Gnd, 5v to 5v and Key to Key. The Rx/Tx wires though are a different thing. Using a metaphor, imagine that we are having a conversation my mouth(Tx) would talk to your ear(Rx) while my ear would listen to your mouth. This is why Tx connects to Rx and vice versa.

      Delete
  3. The blog says that the master connects to one hard coded address. Where is the address field that I can change in the code? Do I need to define the addresses of the slave and master modules or do they connect to any available partner?

    ReplyDelete
    Replies
    1. The address is in the LINK call ( BTSerial.println("AT+LINK=13,3,191407"); ). You simply have to change the value after the '=' with the MAC address of your slave device. The format for the 12 character MAC address parameter is XXXX,XX,XXXXXX with no leading '0' for each part. In my case my slave device address is 001303191407 so I input it as 13,3,191407. This code can only link to the one address that you put in the LINK command but it is possible to scan for available devices and connect to one of them.

      Delete
    2. I am trying to connect the master to one of tow slaves based on a pre-determined variable. However both slaves connect to the master using the default code. When i change the MAC address of in the code to match the Bluetooth address of one of the modules, both modules still connect. Is there any other variable that could be affecting the connection?

      Delete
    3. Are you saying that your Master is connected to two Slaves at the same time? I never tried that since I only have tow modules.

      Delete
    4. Thats not what I mean, I worded that poorly. What i am trying to say is that the master will connect to either of the two slave modules, but only one at a time. changing the MAC address in the code does nothing to the way the modules connect.

      Delete
    5. Are you sure the code is running on both the Master and the Slave? Maybe you should add some debug prints using the Serial port and monitor the process step by step.

      Delete
  4. The code is running great on my Arduino Unos. However, I'd like to run the HC-05 on a pair of Arduino Pro Micros that use the atmega32u4 chip. After changing the pin assignments and uploading the sketch to the Pro Micro, code is functioning, for the most part, but it appears that the HC-05 isn't looking for other devices to pair with. A connected buzzer alarms after a ten second timeout if a connection is not established. Also, the LED on the HC-05 is illuminated much more dimly than when connected to the Uno.

    Are you aware of any differences between the atmega32u4 and the atmega328 that would require a change in the code? Perhaps a change in the baud rate?

    Here's a copy of the master code (run on a Pro Micro): http://pastebin.com/qM1BxuVj
    Here's a copy of the slave code (run on an Uno): http://pastebin.com/d3tniB5a

    ReplyDelete
  5. I could be power related. Are you powering the HC-05 using the 3.3v pin? As for the dim LED, maybe you have the wrong resistor since the Pro-Micro runs on 3.3v and not 5v.

    ReplyDelete
  6. Phillipe,
    I'm working on a project equal to the "BlueTooth link with auto-detect & connect" for a job, using a pair of 05-HC. I'm using their posts to begin with.

    Come on, finish this post to help his friends here in Brazil :)

    congratulations for your blog.

    Thanks

    ReplyDelete
    Replies
    1. Thanks for reading. I haven't done the auto detect with HC modules yet but it should work with the same steps that I used in the BlueSmirf project. The main difference is that, for the HC module, you would have to use the "AT-INQ" command instead of the "I,5" I used with BlueSmirf.

      Delete
  7. Hi,
    Thank you for this great tutorial. I wonder if I can read integer data instead of char from bluetooth connection. I do not want to use char to integer converter function (like parseInt) because it slows down arduino and makes interaction unintuitive.
    I want to read more than one sensor data at once and send it to other arduino in realtime to process it and send it back to first arduino.
    How can I do that? I would be happy if you show me a way to follow.
    Thanks!

    ReplyDelete
    Replies
    1. You could simply cast the char directly into an int (ex: anIntVar = (int)aCharVar; ). That way you don't need to use 'converter' functions.

      Delete
    2. The bluetooth can send and receive 1 byte data at a time. How to send values inherited from sensor which is between 0-1023? Is not there a way in bluetooth communication system to send it as integers instead of characters? Should I first cast it as char, send it and cast it as integer again by the receiver?

      Delete
    3. You then have to transform your value into 'char' chunks so that it can be sent on the serial port. Here's a bit of code that transform an in into two 'char' and put them back together again. This is only using bit shift and mask and should not slow down your processing.

      unsigned char charVar1 = 0;
      unsigned char charVar2 = 0;
      int valueIn = 965; //Value to be sent

      //Break the int value into two 8bits parts
      charVar1 = (valueIn >> 8) & 0x00FF;
      charVar2 = valueIn & 0x00FF;

      //...Sending the 2 characters through serial...

      //Reconstitute the int value from the two characters
      int valueOut = charVar1;
      valueOut = valueOut << 8;
      valueOut = valueOut | charVar2;
      //At this point, valueOut contains the same value as valueIn

      Delete
  8. Hi!
    Thank You for showing me this blog.
    Does this code helps only to connect to Bluetooth whose address is specified in the code.
    Also please explain me about BtSetCmdMode() procedure?
    I want to create a Piconet using Bluetooths, for which it is great if you could help me with auto-detect feature.

    ReplyDelete
  9. Also, Can you please post the circuit diagram. The picture is more confusing in connecting the pin 8 viz the RESET pin and the LEDs.

    ReplyDelete
    Replies
    1. You should also check out this video I made about HC-05 http://youtu.be/3zORXBq7a5g

      Delete
  10. Hi !
    I have two HC-05, one master and one slave and when I power them up the LED flickers every second which means I think that they are connected. I would like to command a servo with a joystick via bluetooth so I was wondering if you had a code that could send a data from master to slave.

    Thanks !

    ReplyDelete
  11. The code I'm sharing on git (https://github.com/pcantin/bt2bt_HCa) does in facts send, from the master to the slave, alternately a '1' and a '0'. For your project you could use this code and modify it to send a char value to the client and use this to position the servo.
    With the arduino Servo library, you can send angle values between 0 to 180 to the servo. A single char can handle values from 0 to 255 so you will have no problem.

    ReplyDelete
    Replies
    1. Ok so I looked at your code and I don't understand if I am supposed to put it on the Arduino where I connected my master or the one where I connected my slave... And also what I am supposed to code on the other one ?

      Delete
  12. Wait I think I got it !
    The variable gIsMaster, I have to put it on 1 on the master device and on 0 on the slave device... Is that it ?
    Also, to get the mac adress, do I have to use AT+ADDR? or AT+BIND? ?

    ReplyDelete
    Replies
    1. You got it. Yes the "AT+ADDR?" command will return the bluetooth module mac address.

      Delete
    2. Are the pin assignments different for the Arduino Mega ? I mean do I still use 10 & 11 for the Rx and Tx ?
      Thank you so much for your time and your answers by the way ! I've been looking for a way to connect those two together for days I couldn't find anything on the internet !

      Delete
    3. You can use [almost] any pins you want but make sure you also set the values of gRxPin and gTxPin.

      Delete
  13. An do I have to change the i_isMaster variable also ?

    ReplyDelete
    Replies
    1. It get set by the parameter passed to the BtSetupRole() call. In this test code it is set to 1 when gIsMaster equals1 (This is not my prettiest code... so feel free to clean it up).

      Delete
  14. Hey ! Sorry to bother you again.
    I don't understand which function between print, printIn and write send the data from the master to the slave and then should I use read to read it ?

    ReplyDelete
    Replies
    1. Oops I missed this question so here is my super late answer: The send the data from the master (as in the sample code: BTSerial.print("1");) use the print() function. On the slave use the BTSerial.read(); function to get each character. With this HC-05 code, the println() function is only used when interacting with the BT module settings using the AT commands.

      Delete
  15. Hi , can you please guide me as i am having trouble. PRoblem domain is i want to connect to arduino's using HC 05 but but the problem is the receiver is receiving garbage values. ... help me please ASAP

    ReplyDelete
  16. Amir, It seems that many people are having this problem and I did too at the beginning. From my experience it's link to the setting of the communication speed, I'll probably make a video to explain how I trace and fix this kind of bugs since it is not straight forward to explain.

    ReplyDelete
  17. well Mr Cantin thanks for your quick response let me try it then i'll get back to you .

    ReplyDelete
  18. Hi,
    Thank you for your tutorial, I have some questions about how to make the link between the two HC-06.
    what is the part in your code that allows the master to link to the other Bluetooth module
    slave?
    I don't understand why it is necessary to send master adress to the slave. When I use a smartphone to link with the slave (with android applications), the bluetooth module (slave) don't need to know the master adress!?

    In the following master code I give the adress link of the second Bluetooth module, but it doesn't work, can you explain me?

    #include //Software Serial Port
    #define RxD 6 //Pin 10 pour RX (pin0=serial) vert
    #define TxD 5 //Pin 11 pour TX, on peut changer noir
    SoftwareSerial BTSerie(RxD,TxD);

    void setup()
    {
    Serial.begin(9600); //115200 si on veut
    delay(500);
    Serial.println("Bonjour - Pret pour les commandes AT");

    pinMode(RxD, INPUT);
    pinMode(TxD, OUTPUT);
    BTSerie.begin(9600); //57600
    delay(1000);
    BTSerie.println("AT+ROLE=1");
    Serial.println("Set as Master");
    delay(1000);
    BTSerie.println("AT+CMODE=1");
    delay(1000);
    BTSerie.println("AT+INIT");
    Serial.println("AT command: AT+INIT");
    delay(1000);
    BTSerie.println("AT+LINK=13,12,032251"); //command to link to slave adress
    Serial.println("AT command: AT+LINK=");
    delay(1000);



    }
    void loop()
    {
    char recvChar;

    if (BTSerie.available()) {
    recvChar = BTSerie.read();
    Serial.print(recvChar);
    }
    // Serial.write(blueToothSerial.read());
    if (Serial.available()) {
    recvChar = Serial.read();
    BTSerie.write(recvChar);
    }
    }

    ReplyDelete
    Replies
    1. - The actual link command is the following one" BTSerial.println("AT+LINK=13,3,191407"); "

      - The master must have the Slave address to link to it. When you connect to your BT module with your phone, the phone is the Master. The phone scan for available Slaves, get the BT module's address and initiate the connection.

      - In your code you are not switching between command mode and communication mode. In my sample you'll see that I switch between command mode (BtSetCmdMode(1);) and communication mode (BtSetCmdMode(0);). Both modes have different com speed and switching between the two (in this example) requires a hard reset of the module which is performed by the BtReset(); call.

      Delete
  19. Hey.

    My question is if the module can scan all possible address in the vicinity and connect to any of it? I've established a master and multiple slaves, but hard coded the address in the master which i want to avoid. Can the master scan addresses and connect to any? Is there any AT command to do so? Also, I'm using MSP430 and not using enregia. I'm using CCS IDE. So, any help would be good.
    Thanks in advance.

    ReplyDelete
    Replies
    1. I've hard coded each of the slaves' address in the master, which i don't want to do if i'm building a network of variable number of slaves. So, does HC 05 have that option of scanning devices? Like the bluetooth module in a phone?

      Delete
    2. Yes by using the "AT+INQ" command. This command will return a series of results as it finds other bluetooth modules. the returning values look like this: "+INQ:1234:56:0,1F1F,FFC1" where the first parameter (in this case 1234:56:0) is the address that was found. You can use this address to initiate the link using the AT+LINK command.

      I have done something similar using Bluesmirf (http://phillipecantin.blogspot.ca/2012/01/arduino-bluetooth-link.html) and the same logic can be used to auto-connect two HC-05

      Delete
  20. I need to connect my HC05 as master with an HC06 as slave on another arduino at 115200 baud rate. Would it be possible?
    The HC06 is already configured. I have managed to change the name and baud rate of the HC05 but when I've tried the commands below, AT+INIT and subsequent commands give me no response, not even an error. If I switch off and put the module in command mode again, the first three commands give me "OK" but AT+INIT and what follows give me no response. AT+iINIT sets the LED on the HC-05 blinking faster but no response on Serial Monitor.

    AT
    OK
    AT+CMODE=0
    OK
    AT+ROLE=1
    OK
    AT+INIT
    OK
    AT+INQ
    +INQ:4D65:4D:CA6612,5A0204,7FFF
    OK
    AT+BIND=4D65,4D,CA6612
    OK
    AT+PAIR=4D65,4D,CA6612,30
    OK

    ReplyDelete
    Replies
    1. You should check this last post I just made (http://phillipecantin.blogspot.ca/2014/08/hc-05-bluetooth-link-with-zero-code.html) it will help you get this to work

      Delete
  21. Hi Mr.Phillipe,

    I wanna ask how can I light a led instantly after my two hc-05 is connected. I mean I don't need to send 0 and 1 every time.It just needs to automatically power on a led. I don't know how to start writing my arduino code with this function. please help me.

    ReplyDelete
  22. Hi Mr.Cantin,

    Thank you for the tutorial. Im able to connect the hc05s to arduino and dump the code although i have an issue regarding the connection between master and slave. Everytime i upload the code , the led on hc05 blinks for every 2 seconds which i understand is that the module has entered at-command mode, but im not able to get the link between the master and slave .
    Could you please help me sort this issue

    Thank You
    Arun

    ReplyDelete
  23. You have two options: #1 would be to go back over the code and find at which steps it stops working. This would help us find the problem. #2 you could use the auto-link procedure I have described in this other post: http://phillipecantin.blogspot.ca/2014/08/hc-05-bluetooth-link-with-zero-code.html

    ReplyDelete
  24. Hi.... Could you help me with something? I want to pair a master RN-42 module with a slave HC-05 module? How can it be done?

    ReplyDelete