Arduino with HC-05 (ZS-040) Bluetooth module – AT MODE

Updated 19.07.2015
Updated 26.07.2015
Updated 30.10.2015

Update 2016-08-01
The zs-040 breakout boards are now being used for many different modules and you may not have the exact same boards as those shown below. Recently I received some new zs-040 HC06s and HC-05s that have a slightly different daughter board and a very different firmware. On the new HC-05s pin34 has to be pulled HIGH before connecting power to enter AT mode. Bringing pin 34 HIGH after powering the modules has no effect.

 
 

AT mode allows you to interrogate the BT module and to change some of the settings; things like the name, the baud rate, whether or not it operates in slave mode or master mode. When used as a master device AT commands allow you to connect to other Bluetooth slave devices.

There are many slightly different HC-05 modules, the modules I have are marked ZS-040 and have an EN pin rather than a KEY pin. They also have a small button switch just above the EN pin. They are based on the EGBT-045MS Bluetooth module.

Update: I now also have boards marked fc-114. See:
HC-05 FC-114 and HC-06 FC-114. First Look
HC-05 FC-114 and HC-06 FC-114. Part 2 – Basic AT commands
HC-05 FC-114 and HC-06 FC-114. Part 3 – Master Mode and Auto Connect

On the zs-040 modules there are 2 AT modes. I do not know if this is intentional but some commands only work when pin34 is HIGH. Other commands work when pin 34 is either HIGH or LOW. This fooled me for quite a while. For this post I have called the different modes “mini” AT mode and “full” AT mode.

HC-05 zs-040

To activate AT mode on the HC-05 zs-040 modules we can:
– 1. Hold the small button switch closed while powering on the module.
– 2. Set pin 34 HIGH (3.3v) when power on.
– 3. Close the small push button switch after the HC-05 is powered.
– 4. Pull pin 34 HIGH after powering the HC-05.

Method 1.
Enters AT mode with the built in AT mode baud rate of 38400. The baud rate cannot be changed by the user.
This method allows the module to enter AT mode on start but but does not keep pin 34 HIGH and uses the “mini” AT mode.

Method 2.
Enters AT mode with the built in AT mode baud rate of 38400. The baud rate cannot be changed by the user.
If you keep pin 34 HIGH you will enable the “full” AT mode which allows all AT commands to be used.
If you let pin 34 return LOW after power on then “mini” AT mode will be enabled.

Method 3.*
Enters “mini” AT mode using the user defined communication mode baud rate.

Method 4.*
Enters “full” AT mode using the user defined communication mode baud rate.

If pin 34 is kept HIGH then the HC-05 enters the “full” AT mode. If pin 34 is brought HIGH and returned to LOW it will put the module in to “mini” AT mode.

* added 21.07.2015

Method 1 and 2 are good in that you know the baud rate – it will always be 38400. This could be useful if you have modules other people have used or if you forget what communication mode baud rate you have previously set.

Method 3 and 4 adds convenience. You can enter AT mode, make changes and return back to communication mode without switching sketches and messing around with different baud rates.

I use software serial on Arduino pins 2 and 3 to talk to the HC-05. This means I can still use the hardware serial to talk to the serial monitor on a host computer.

 

Entering AT Mode Method 1. Use the button switch

The small push button switch, when closed, connects pin 34 to vcc which allows you to enter AT mode. Close the button switch when powering on the module and you enter AT mode using 38400 baud rate. Once on you can release the button switch, however, releasing the button switch puts the module in to a mini AT mode and some commands will not work. Commands such as AT+NAME?, AT+INQ, AT+RNAME? only work when pin 34 is HIGH. As soon as you release the button switch pin 34 returns LOW. If you want access to the extended commands you can simply close the switch just before issuing the AT command and release the button switch after the command has been sent.

Make the following connections
– BT VCC to Arduiono 5V
– BT GND to Arduino GND
– BT TX to Arduino D2
– BT RX to Arduino D3 through a voltage divider (3.3V)

HC-05 AT Mode Connections to Arduino

Connect the Arduino to the host computer. The LED on the HC-05 should be blinking quickly at about 5 times a second.

With the Arduino on, do the following
– Remove the 5V connection to BT VCC
– Press and hold the button switch on the BT module
– Re-connect BT VCC to 5V (while still pressing the button switch), the LED should come on.
– Release the button switch and the LED should be blinking slowly on/off once every couple of seconds. This indicates AT mode.

The following sketch is used to talk to the BT module. Run the sketch and put the HC-05 in to AT mode.

// Basic Bluetooth sketch HC-05_AT_MODE_01
// Communicate with a HC-05 using the serial monitor
//
// The HC-05 defaults to communication mode when first powered on you will need to manually enter AT mode
// The default baud rate for AT mode is 38400
// See www.martyncurrey.com for details
//
 
 
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
// Connect the HC-05 TX to Arduino pin 2 RX. 
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.
// 
 
char c = ' ';
 
void setup() 
{
    Serial.begin(9600);
    Serial.println("Arduino is ready");
    Serial.println("Remember to select Both NL & CR in the serial monitor");
 
    // HC-05 default serial speed for AT mode is 38400
    BTserial.begin(38400);  
}
 
void loop()
{
 
    // Keep reading from HC-05 and send to Arduino Serial Monitor
    if (BTserial.available())
    {  
        c = BTserial.read();
        Serial.write(c);
    }
 
    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available())
    {
        c =  Serial.read();
        BTserial.write(c);  
    }
 
}

Here is the output on the serial monitor
HC-05 AT Mode_ SerialMonitor_01

The HC-05 expects a new line and a carriage return character at the end of each command so make sure “Both NL & CR” is selected at the bottom of the serial monitor. To confirm you are actually in AT mode, in the serial monitor type “AT” (no quotes) and hit Send. You should get an “OK”.
HC-05 AT Mode_ SerialMonitor_04

 
 

Entering AT Mode Method 2. Using the Arduino to Control the HC-05

In this example the Arduino fully controls the HC-05. The Arduino pin D4 connects to a PNP transistor which is used as a switch to control the power and D5 is connected to the HC-05 pin 34 to control AT mode. Of course you can control the HC-05 manually if you wish.

This used to be my preferred method but I have found that once I have set up a module I seldom change it and it has become more convenient to use the button switch or a temporary connection to pin 34. The benefit of this example is that the Arduino can control the process. Also, certain commands only work when pin 34 is HIGH. Using this method allows you to keep pin 34 HIGH.

Why not power the HC-05 from an Arduino pin?
The HC-05 can draw a maximum of 40mA and although Arduino pins can supply 40mA this is the maximum and not recommended. While it may work if you are only using AT mode and not making connections, the HC-05 uses most current when broadcasting, I would rather be safe than sorry. As such I use the Arduino 5V out to power the HC-05, this can supply up to 200mA and is a much safer option. We still need a regular pin to control the transistor which we are using to switch the power on and off.

With the Arduino turned off make the following connections:
– Arduino D2 to HC-05 TX
– Arduino D3 to HC-05 RX through a voltage divider
– Arduino D4 to HC-05 pin 34 through a voltage divider
– Arduino D5 to PNP transistor base via a 2.2k resistor
– HC-05 GND to common GND
– PNP emitter to +5V
– PNP collector to HC-05 vcc

I am using a 2N3906 PNP transistor because it is what I have. Similar PNP transistors can also be used.

HC-05_02_Breadbaord_1600

HC-05-PNP

HC-05_AT_MODE_02_BreadBoard_ClipCloseup_01_1200
HC-05 with pin 34 connected by a probe clip. You can also simply hold a piece of wire to the pin. For a long term solution you would need to solder a wire to pin 34.

Compile and upload the following sketch

// Basic Bluetooth sketch HC-05_AT_MODE_02b
// Connect the HC-05 module and communicate using the serial monitor
// Arduino automates entering AT mode
//
// The default baud rate for AT mode when pin 34 is HIGH on power on is 38400
// See www.martyncurrey.com for details
//
//
//  Pins
//  Arduino D2 to HC-05 TX
//  Arduino D3 to HC-05 RX via a voltage divider
//  Arduino D4 to HX-05 pin 34 via a voltage divider
//  Arduino D5 to PNP Base via a 2.2k resistor
//  BT VCC to PNP Collector
//  BT GND to GND
//  PNP Emitter to vcc
//
// When a command is entered in to the serial monitor on the computer 
// the Arduino will relay it to the Bluetooth module and display the result.
//
 
const byte BT_POWERPIN = 5;
const byte BT_PIN34_PIN = 4;
 
const boolean ON = LOW;
const boolean OFF = HIGH;
 
boolean BT_POWER = HIGH;  
boolean PIN34_STATE = LOW;
 
boolean NL = true;
char c = ' ';
 
 
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
 
void setup() 
{
    pinMode(BT_POWERPIN, OUTPUT);
    pinMode(BT_PIN34_PIN, OUTPUT);
 
 
    digitalWrite(BT_POWERPIN, OFF);  
    digitalWrite(BT_PIN34_PIN, LOW);
 
 
    Serial.begin(9600);     // communication with the host computer
    //while (!Serial)   { ; }
 
    Serial.println("Arduino Started");
    Serial.println("Basic Bluetooth sketch HC-05_AT_MODE_02b");
 
 
    Serial.println("Serial started at 9600");
    Serial.println(" ");
 
    // Start the software serial - baud rate for AT mode is 38400 
    BTserial.begin(38400);  
    Serial.println("BTserial started at 38400");
    Serial.println(" ");
 
    Serial.println("Enter # to toggle pin34 HIGH/LOW.");
    Serial.println("Enter * to toggle power to the HC-05");
    Serial.println("Remember to bring pin 34 HIGH before powering the HC-05");
    Serial.println("Set Both NL & CR in the serial monitor.");
    Serial.println(" ");    
    Serial.println("Pin 34 is LOW");
    Serial.println("Power is OFF");
    Serial.println(" ");
 
}
 
 
 
void loop()
{
 
    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available())
    {
          c =  Serial.read();
 
          // Echo the user input to the main window. The ">" character indicates the user entered text.
          if (NL) { Serial.print(">");  NL = false; }
          Serial.write(c);
          if (c==10) { NL = true; }        
 
 
          if (c=='*')
          {    
                 Serial.println(""); Serial.print("BT power is ");
                 if (BT_POWER == ON)         { BT_POWER = OFF;  digitalWrite(BT_POWERPIN, OFF);   Serial.println("OFF");    }   
                 else if  (BT_POWER == OFF)  { BT_POWER = ON;   digitalWrite(BT_POWERPIN, ON);    Serial.println("ON");   }     
 
                 if (  (PIN34_STATE == HIGH) && (BT_POWER == ON)  ) { Serial.println("AT mode");  }  
          }
 
          else if (c=='#') 
          {  
                 Serial.println(""); Serial.print("BT pin 34 is ");
                 if (PIN34_STATE == LOW)           { PIN34_STATE = HIGH;  digitalWrite(BT_PIN34_PIN, HIGH);  Serial.println("HIGH");   }   
                 else  if (PIN34_STATE == HIGH)    { PIN34_STATE = LOW;   digitalWrite(BT_PIN34_PIN, LOW);   Serial.println("LOW");    }  
          }
 
          else { BTserial.write(c);  }
 
    }
 
 
 
 
  // Keep reading from the HC-05 and send to the Arduino Serial Monitor
    if (BTserial.available())
    {  
        c = BTserial.read();
        Serial.write(c);
    }
 
 
}

After the sketch has been uploaded, started the Arduino and open the serial monitor at 9600 baud rate. The HC-05 should be off.

HC-05_02_serialMonitor_01

To start the HC-05 in AT mode, bring pin 34 HIGH and then start the BT module.
– Enter “#” (no quotes) to bring pin 34 HIGH
– Enter “*” (no quotes) to turn on the HC-05

HC-05_02_serialMonitor_06

The HC-05 should now be on and in AT mode with the on board LED blinking slowly on/off every couple of seconds.

Enter “AT” (no quotes) and you should get a reply of “OK”.
HC-05_02_serialMonitor_07_AT

It should be fairly simple to extend this example and fully control the HC-05 from your own sketch.

 
 

Entering AT Mode Method 3. Close the small push button switch after the HC-05 is powered.

This method enters the “mini” AT mode using the baud rate defined for communication mode. This means you can use communication mode and enter AT mode without uploading a new sketch but not all commands will work.

Set up the HC-05 as below:
HC-05 AT Mode Connections to Arduino

Upload the following sketch.

// Basic Bluetooth sketch HC-05_02_9600+ECHO
// Connect the HC-05 module and communicate using the serial monitor
//
// The HC-05 defaults to commincation mode when first powered on.
// The default baud rate for communication mode is 9600. Your module may have a different speed.
//
 
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
// Connect the HC-05 TX to Arduino pin 2 RX. 
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.
 
char c = ' ';
 
void setup() 
{
    Serial.begin(9600);
    Serial.println("Arduino is ready");
 
    // HC-05 default serial speed for communication mode is 9600
    BTserial.begin(9600);  
    Serial.println("BTserial started at 9600");
}
 
void loop()
{
    // Keep reading from HC-05 and send to Arduino Serial Monitor
    if (BTserial.available())
    {  
        c = BTserial.read();
        Serial.write(c);
    }
 
    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available())
    {
        c =  Serial.read();
 
        // Copy the serial data back to to the serial monitor. 
        // This makes it easy to follow the commands and replies
        Serial.write(c);
        BTserial.write(c);  
    }
 
}

The HC-05 should be in communication mode with the LED on the HC-05 blinking about 5 times a second. This indicates the module is waiting for a connection or to be paired.

Open the serial monitor.
Press the small button switch.
Release the small button switch.

That’s it. You are now in “mini” AT mode. The LED does not change. It still blinks quickly at 5 times a second.

In the serial monitor enter “AT” (no quotes) and hit Send. You should get an “OK”
HC-05-03_miniATmode

To return to communication mode, enter the “AT+RESET” command.
HC-05-03_miniATmode_02

 
 

Entering AT Mode Method 4. Pull pin 34 HIGH after powering the HC-05.

This method allows you to enter and exit AT mode from within a sketch. This can be handy when you run a set up sketch or when you want the user to be able to make changes. For example change the name of the HC-05. The sketch could ask the user for the new name and then set it without the need to change sketches or any manual operation from the user.

Because pin 34 is being pulled HIGH the HC-05 will enter “full” AT mode and all commands will work.

Make the following connections
– D2 (RX) to HC-05 TX
– D3 (TX) to voltage divider and then HC-05 RX
– D4 to voltage divider and then to pin 34
– HC-05 vcc to 5v
– HC-05 GND to common GND

HC-05-03_miniATmode_03

HC-05_method 4

Upload the following sketch. Once the sketch is uploaded open the serial monitor.

// Basic Bluetooth sketch HC-05_03_AT_MODE_Controlled
// Connect the HC-05 module and communicate using the serial monitor
//
// The HC-05 defaults to communication mode when first powered on.
// The default baud rate for communication mode is 9600. Your module may have a different speed.
// This sketch allows the user to enter AT mode on the HC-05
//
//
// Pins
// D2 (RX) to HC-05 TX
// D3 (TX) to voltage divider and then HC-05 RX
// D4 to voltage divider and then to pin 34
// HC-05 vcc to 5v
// HC-05 GND to common GND
//
 
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
// Connect the HC-05 TX to Arduino pin 2 RX. 
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.
 
char c = ' ';
byte ATmodePin=4;
 
void setup() 
{
    // set up the pin used to turn on AT mode
    pinMode(ATmodePin, OUTPUT); 
    digitalWrite(ATmodePin, LOW); 
 
    // Start the serial monitor
    Serial.begin(9600);
    Serial.println("Arduino is ready");
 
    // HC-05 default serial speed for communication mode is 9600
    BTserial.begin(9600);  
    Serial.println("BTserial started at 9600");
    Serial.println("Type # to enter AT mode");
}
 
void loop()
{
 
    // Keep reading from HC-05 and send to Arduino Serial Monitor
    if (BTserial.available())
    {  
        c = BTserial.read();
        Serial.write(c);
    }
 
    // Keep reading from Arduino Serial Monitor and send to HC-05
    if (Serial.available())
    {
        c =  Serial.read();
 
        if (c=='#')  // enter AT mode
        {
            digitalWrite(ATmodePin, HIGH);
            Serial.print("Entered AT mode. Type $ to exit");
        }
 
        else if (c=='$') // exit AT mode by reseting the HC-05
        {
            digitalWrite(ATmodePin, LOW);
            BTserial.print("AT+RESET\n\r");
            Serial.print("AT+RESET\n\r"); 
        }        
 
        else
        {
              // Copy the serial data back to to the serial monitor. 
              // This makes it easy to follow the commands and replies
              Serial.write(c);
              BTserial.write(c);  
        }
 
    }
 
}

The sketch is similar to the other HC-05 sketches, it copies what is entered in to the serial monitor to the HC-05 and what ever it receives from the HC-05 it sends to the serial monitor. The extra bit is # and $. Entering a “#” (no quotes) puts the HC-05 in to AT mode and entering a “$” (no quotes) returns to communication mode. It returns the HC-05 to communication mode by resetting the module.

To enter AT mode type “#”
To exit AT mode type “$”

HC-05_04_01

You can confirm you are in AT mode by entering “AT” or “AT+VERSION”
HC-05_04_02

To leave At mode type “$” (no quotes)
HC-05_04_04

 
 
 
 

AT commands

The HC-05 expects commands to include a carriage return and newline characters (\r\n). You can add these automatically in the serial monitor by selecting Both NL & CR at the bottom of the window.
Serial Monitor NL & CR
You can also enter them manually in the form AT\r\n. If you forget to add carriage return and newline characters the HC-05 will not respond.

Example commands

AT – simple feedback request. Will return
OK

AT+VERSION – returns the firmware version. In my case it returns
+VERSION:2.0-20100601
OK

AT+STATE – returns the current state of the module
+STATE:INITIALIZED
OK

AT+ROLE – the possible values are ; 0 – Slave, 1 – Master, 2 – Slave-Loop
Returns
+ROLE:0
OK

To change to Master Mode, enter AT+ROLE=1, returns:
OK

AT+UART – returns the baud rate used by the HC-05 in communication mode. The default for the modules I have is 9600.
Returns:
+UART:9600,0,0
OK

To change the baud rate to 38400 – AT+UART=38400,0,0
Returns:
OK

Windows does not support baud rates above 115200. If you accidentally set the baud rate higher than 115200 you will not be able to use communication mode. You should still be able to enter AT mode at 38400 using method 1 or method 2 above and change the communication mode baud rate to something Windows can handle.

AT+NAME
Querying the modules name with AT+NAME? only works in “full” At mode. If you cannot get AT+NAME? to work you need to bring pin34 HIGH.
Changing the modules name with AT+NAME=newname works in “full” AT mode and “mini” AT mode.

What you should get is:
AT+NAME?, returns
+NAME:HC-05
OK
(or something similar depending what your module is called)

Other commands that require pin 34 to be HIGH are AT+INQ and AT+RNAME. This is not a complete list through.

Full list of AT commands

AT commands list

This list is taken from the EGBT-045MS bluetooth module user guide and not all commands may be supported or work straight away. For example AT+NAME? only works when pin 34 is HIGH.

For more information look at the HC-05 user guide or the EGBT-046S/EGBT-045MS user guide

 
 

164 thoughts on “Arduino with HC-05 (ZS-040) Bluetooth module – AT MODE

    • +1 I agree with montassar. I was not able to get all the AT commands until I read this posting. The at+name? was making me nuts. Now, I hold the button and the command works.

      Thanks!

  1. hey, i have this problem, the comunication it’s not going well, it send to me characters like this: ϧ†…. I tried a lot of ways and it’s always the same, :
    AT mode.
    Remember to to set Both NL & CR in the serial monitor.
    BT STATE =
    ««ª ª’•ªFU
    b•´ŠÄ……ϧ†…
    i think it is a problem in the comuniction between the arduino whit my module HC-05 zs404

    • In my case (HC-05, ZS-040) it was solved using code posted by twelti on the site http://forum.arduino.cc/index.php?topic=290847.0
      /*
      AT+ORGL (Restore the factory default state)
      AT+UART=115200,0,0 (Set baud rate to 115200, one stop bit and no parity bit)
      AT+NAME=TinyG
      */
      #include
      #define rxPin 10
      #define txPin 11
      SoftwareSerial mySerial(rxPin, txPin); // RX, TX
      char myChar ;
      void setup() {
      Serial.begin(9600);
      Serial.println(“AT”);
      mySerial.begin(38400);
      mySerial.println(“AT”);
      }
      void loop() {
      while (mySerial.available()) {
      myChar = mySerial.read();
      Serial.print(myChar);
      }
      while (Serial.available()) {
      myChar = Serial.read();
      Serial.print(myChar); //echo
      mySerial.print(myChar);
      }
      }

    • It sounds like you have the wrong baud rate.

      The modules I have use different speeds; AT mode is 38400, and communication mode is 9600.

      // Start the software serial – baud rate for AT mode is 38400
      BTserial.begin(38400);

      Remember there are 2 different serial communications.
      1 – The arduino to the computer at 9600
      2 – The blue tooth module to the Arduino at 38400

      The baud rate shown in the serial monitor is for the communication between Arduino and computer.

  2. this is the last scetch i’m using. i also tried change the baud ratio in the BTserial, i tried whith 1200, 2400, 4800, 9600 etc, but i only have “response” using 38400. I even used the AltsoftSerial library and diden’t work. I check in the net and some other few people has the same problem but no one seems find a solution.

    char serialByte = ‘0’;
    const byte LEDPIN = 13;

    #include
    SoftwareSerial BTserial(10, 11); // RX | TX

    void setup()
    {
    pinMode(LEDPIN, OUTPUT);

    // communication with the host computer
    Serial.begin(9600);

    // Start the software serial – baud rate for AT mode is 38400
    BTserial.begin(38400);

    // LED to show we have started the serial channels
    digitalWrite(LEDPIN, HIGH);

    // Give the user time to enter AT mode
    // wait for the user to enter a ‘1’ to start
    Serial.println(“After entering AT mode, type 1″);
    while (serialByte !=’1′)
    {
    serialByte = Serial.read();
    }

    Serial.println(” “);
    Serial.println(“AT mode.”);
    Serial.println(“Remember to to set Both NL & CR in the serial monitor.”);

    Serial.print(“BT STATE = “);
    BTserial.println(“AT+STATE” );
    Serial.println(” “);
    delay(100);

    }

    void loop()
    {
    // listen for communication from the BT module and then write it to the serial monitor
    if ( BTserial.available() ) { Serial.write( BTserial.read() ); }

    // listen for user input and send it to the HC-05
    if ( Serial.available() ) { BTserial.write( Serial.read() ); }
    }

    and this its what happen when i executed it

    After entering AT mode, type 1

    AT mode.
    Remember to to set Both NL & CR in the serial monitor.
    BT STATE =
    ««ª ª’•ªFE
    b•´ŠÄ……ϧ†…

    • I can’t duplicate the problem. I do get some garbage when I use an incorrect baud rate but it is intermittent. As soon as I use 38400 everything works fine.

      Try different pins, for example use Pin 2 and 3 and reseat all the connections.

    • hey, did you find the solution to the problem? I got the exact same result as yours on my serial monitor. Thanks in advance!

      • The closest I have been to recreating the problem is through using the wrong baud rate.

        Try the different baud rates and note the responses you get. One of then should work but it may not be 38400.

        • Hi Pablo and Fibo,

          I was having the same problem, weird characters from the BT Module. It happend to me before, some libraries won’t work fine with the latest version of the Arduino IDE, I was using v 1.6.

          I tried the very same sketch with the Arduino IDE v 1.0 and it all went perfect. Try to download it from the arduino site.

          Hope this work for you.

  3. Hi, I got two problems with this HC-05 module.
    1. When I type AT+NAME? I got no response. I do not understand why is that so, I got all responses for AT+ROLE? AT+PSWD? but not AT+NAME? Can answer this ?

    2. I can’t search this HC-05 Bluetooth module with my ios devices. I can find it with other android devices but not my iphone or ipad. How to solve ?

    • Updated reply.

      AT+NAME? only works when pin34 is HIGH.
      If using the button switch, close the switch just before sending the command.

      The HC-05 and HC-06 do not work with idevices. Apple products do not support the Bluetooth protocol that the HC-05 /06 units use. If you want to connect to an idevice you will need a BT module that uses BLE / Bluetooth 4.0.

  4. we are using ARDUINO MEGA and we also encountered the same problem after entering “AT” then “1”, the serial monitor respond is “BT STATE”. we tried “38400” and “9600” but didnt get any response.

    but when we used ARDUINO UNO. we got an “OKAY” respond from the serial monitor.

    WHY IS THAT SO?
    we really need to use the ARDUINO MEGA

    any help?

  5. Hello Martyn! Thank you for sharing your work. I have successfully connected my uno with hc05 and due with hc05 too and have paired them using AT+LINK Both the hc05 have started blinking together now i want to transfer data from uno to due I have connected a microphone with uno and here is the receiver code of uno :
    #include
    #define rxPin 11
    #define txPin 10
    SoftwareSerial myserial= SoftwareSerial(rxPin,txPin);
    int analogpin=0;
    void setup(){
    Serial.begin(9600);
    myserial.begin(9600);
    }
    void loop(){

    int b=analogRead(analogpin);
    Serial.println(b);
    delay(1000);
    myserial.write(b);

    }
    And on due i have used this code
    void setup()
    {
    Serial.begin(9600);
    Serial1.begin(9600);
    )
    void loop()
    {
    int a=Serial1.read();
    Serial.println(a);
    }
    But the data appearing on the serial monitor of uno is not going on due .
    Can you please help its urgent

    • Confirm that they are actually talking to each other. You can do this with 2 serial monitors. You can also set one to send test data; for example “1234” every second.

    • hi, how did you paired the two HC 05 bluetooth modules?

      my serial monitor always respond “FAIL” during the “AT+LINK” command.

      i need help thank you:)

    • Hello Alman.
      Did you configure a HC-05 using a Arduino due?

      I am trying to do it but having nothing in response from the module.

      • I haven’t used a Due but it should work with the HC-05 albeit with some changes.

        The Due has 4 hardware serials so you should use one of these for talking to the HC-05 rather than software serial.

        Since the Due is a 3.3v device you do not need the voltage divider on the HC-05 RX pin. Connect the Due TX pin directly to the Due RX pin.

        The HC-05 needs at least 3.6v on the vcc pin to work correctly. I believe the Due has a 5V out pin, use this rather than the 3.3v out pin.

        Have a look at http://www.martyncurrey.com/using-an-arduino-mega-with-a-hc-05-zs-040-at-mode/.
        This is for the mega but uses hardware serial1 and the same as using serial1 on the Due.

  6. Starting the bluetooth module

    AT mode.
    Remember to to set Both NL & CR in the serial monitor.
    Enter AT commands

    BT STATE = +STATE:INITIALIZED
    OK
    ERROR:(16)
    OK
    +INQ:3014:8:190258,1F00,7FFF
    OK
    +RNAME:CARDEA_SLAVE
    OK
    FAIL
    +INQ:3014:8:190258,1F00,7FFF
    OK

    any idea why do we get a “FAIL” response? thank you

    • RNAME requires the mac address of the remote device: See page 10 of the EGBT-046S/EGBT-045MS user guide. You can download the user guide from https://docs.google.com/file/d/0BxdLxDCD6HidSkRaRTVuNERrQjg/edit

      7. Query Remote Bluetooth Device’s Name

      Command
      AT+RNAME?<addr>

      Response
      +NAME:<name>
      OK

      where <name> = Device name
      <addr> = 48 bit bluetooth address
      in NAP,UAP,LAP format

      Example: Query remote Bluetooth device having address = 00:02:72:0A:3C:7F
      Bluetooth address in NA:UAP:LAP format = 0002:72:0A3C7F
      From Host controller:
      AT+RNAME?0002,72,0A3C7F
      EGBT-045MS response if remote device name is “HC-05”
      +NAME:HC-05
      OK
      EGBT-045MS response if remote device name is unresolved
      FAIL

      I have a HC-06 module with the address = 30:14:10:17:11:79
      This means the command = AT+RNAME?3014,10,171179
      and this gets me:
      +RNAME:HC-06_1
      OK

      The HC-06 is name “HC-06_1″

      RNAME only works for me when pin 34 on the HC-05 is HIGH. When pin 34 is LOW or not connected I get nothing, no reply and no error message.

      Are you able to use AT+INQ and AT+RNAME with pin 34 LOW or not connected?
      On the modules I have I have to set pin 34 HIGH before the commands give a reply.

      • the serial monitor responds properly AT+INQ and AT+RNAME, pin 34 is HIGH.
        we only get “FAIL” respond evertytime we use AT+LINK.

        we cannot pair the master and slave module

        • the serial monitor is not responding in AT+INIT, AT+INQ, AT+LINK when we are using the METHOD 1. USE THE BUTTON SWITCH

          any help? thanks

          • You need to keep pin 34 HIGH. Certain commands like AT+INQ etc need pin 34 to be HIGH. If pin 34 is LOW or not connected then the module does not respond (no reply and no error message).

            This means keeping the button switch closed or adding a connection to pin 34 directly. The button switch, when closed, connects pin 34 to +3.3v

            I am going to solder a wire to pin 34 to make switching HIGH/LOW a bit easier to do. A wire connected to the top of the button switch should also work.

            I have updated the guide and the new information may be helpful to you.

  7. Pingback: Connecting 2 Arduinos by Bluetooth using a HC-05 and a HC-06: Easy Method Using CMODE | Martyn Currey

    • I will try to do a write up on this but in the meantime here are the basic steps

      Pin34 on the HC-05 needs to be HIGH for all commands to work.

      1. make sure the baud rates on the HC-05 and the HC-06 are the same
      2. make sure the passwords on the HC-05 and the HC-06 are the same
      3. find the address of the slave module
      4. pair with the slave device
      5. bind the slave device
      6. set the HC-05 to only connect with paired devices
      7. link to the slave device

      1 and 2 are self-explanatory

      3. find the address of the slave module. You can do this using the HC-05:
      Turn on the HC-06. Turn on the HC-05

      On the HC-05 do the following:
      – Clear any previously paired devices – AT+RMAAD
      – Put the HC-05 in Master Mode – AT+ROLE=1
      – After changing the mode you may need to reset the module – AT+RESET
      – Allow the HC-05 to connect to any device – AT+CMODE=0
      – Set inquiry to search for 5 devices and 9 seconds – AT+INQM=0,5,9
      – Initiate the SPP profile – AT+INIT (if SPP is already active you will get an error(17) which you can ignore)
      – Search for other devices – AT+INQ

      This will bring up a list of found devices. One of them should be the HC-06.
      The reply should be in the format +INQ:address,type,signal
      The address will show something like +INQ:15:FF:F3241B,1F00,7FFF

      To use the address in AT commands you need to change the colons into commas. If you get more than one found device you check the names with: AT+RNAME?15,FF,F3241B

      Once you have confirmed you have the correct module and correct address you need to pair it with the HC-05

      4. pair with the slave device – AT+PAIR=<addr>,<timeout>
      e.g. AT+PAIR=15,FF,F3241B,9
      If the HC-05 cannot pair with the HC-06 within 9 seconds you will get an error message.

      5. bind the slave device – AT+BIND=<address>

      6 set the HC-05 to connect to bound devices only – AT+CMODE=1

      7 Link to the slave device – AT+LINK=<address>

      Once set, on start up the HC-05 should automatically connect to the HC-06.

      Let me know how you get on.

  8. Pingback: Connecting 2 Arduinos by Bluetooth using a HC-05 and a HC-06: Pair, Bind, and Link | Martyn Currey

  9. Hello, do you happen to know any way in which an hc-05 would suddenly malfunction (as in not respond to AT commands and serial communication problems)? Or have you heard of any such cases?

    I’ve already gone through several hc-05’s.
    I have absolutely no idea why this happens as there isn’t any commonality between the malfunctioning (it doesn’t happen as a direct result of something – one moment, it works and when I try again later on it just suddenly doesn’t).

    • I haven’t come across this. My modules have been fairly robust – dropped on the floor, connected the wrong way, etc.

      If the LED is working normally then you know the module is still alive?

      Are you using a voltage divider on the RX pin? You can damage the mini Bluetooth module by connecting 5V directly to it.

      • Turns out I was sending 5v signals to BT Rx pin despite connecting 3.3v to the vcc. I guess that was slowly damaging the modules. Hopefully no more of them will die.

        Thank you for the advice!

  10. hi martyn,

    i have read from other source that it is possible to connect 2 slaves to only 1 master module if your bluetooth module supports “multi instance SPP”

    do you have an idea on how to do this? and how to determine if your bluetooth module supports the “multi instance SPP” ?

    thank you :)

    • sorry, I have never done this. It does sound interesting and if possible may be an easy way to create a small network. Not sure when I will get time to investigate though.

  11. Hello,
    Thanks for sharing fine information.
    Instructions for Arduino UNO, it only worked on ports 10-11 9600 x 9600
    I have the HC-05 zs-040 with the button on breakout board over EN Pin.

    First you have to program arduino UNO with the code below, without the data pins plugged otherwise, it does not upload, then you connect data cables to pins 10rx-11 tx with voltage divider and power arduino with the module fully connected, then just open the terminal and push the small button on the module for some seconds, the led continues to flash fast as before ( I didn´t manage to work with it blinking slow) all the commands work, some you have to hold the small button while tapping enter. Hope it throws some light to others with the same problem

    // Basic Bluetooth sketch HC-06_01
    // Connect the Hc-06 module and communicate using the serial monitor
    //
    // The HC-06 defaults to AT mode when first powered on.
    // The default baud rate is 9600
    // The Hc-06 requires all AT commands to be in uppercase. NL+CR should not be added to the command string

    #include
    SoftwareSerial BTserial(10, 11); // RX | TX
    // Connect the HC-06 TX to the Arduino RX on pin 2.
    // Connect the HC-06 RX to the Arduino TX on pin 3 through a voltage divider.
    //

    void setup()
    {
    Serial.begin(9600);
    Serial.println(“Enter AT commands:”);

    // HC-06 default serial speed is 9600
    BTserial.begin(9600);
    }

    void loop()
    {

    // Keep reading from HC-06 and send to Arduino Serial Monitor
    if (BTserial.available())
    {
    Serial.write(BTserial.read());
    }

    // Keep reading from Arduino Serial Monitor and send to HC-06
    if (Serial.available())
    {
    BTserial.write(Serial.read());
    }

    }

  12. Hello,
    I am unable to connect to the AT mode, only the third method worked but the settings are reduced. I have a GW-040 model, used this tutorial to be identical. Does anyone know any specific tutorial for this model (GW-040) or that works.

  13. Hi, I’m trying to connect my zs-040 module with my android phone using the AT+LINK command but the only response i get is FAIL. All other commands are working. what could be the problem with AT+LINK=AA,70,39F04A

    • You didn’t say but I am assuming you have the HC-05.

      I’m not 100% certain but I believe you have to initiate the connection from the phone.

      Are you able to establish a connection from the phone to the BT module when using the phone to initiate the connection?
      If you have the HC-05, does the phone appear when you scan for bluetooth devices using the HC-05?

  14. Pingback: HC-05 and HC-06 zs-040 Bluetooth modules. First Look | Martyn Currey

  15. Pingback: Quick Links | Martyn Currey

  16. Hi Martyn, first of all i wanna tell you it’s great to have all this information about hc 05. Thanks for sharing the information needed. I have a problem and hope you can help me, when sending an AT command, I can only send one at a time, and after that, no value is return, I have to disconnect the VCC from BT and reconnect it to send another AT command, what you think can be the solution ?.

  17. Can you explain what you mean by one at a time. Do you mean the first command works but the second,third etc does not?
    Are you sure you are in AT mode?
    Does “AT” work, do you get the “OK” reply?

    What model HC-05 do you have? Do you have the zs-050?
    Do you have the correct line endings set?
    Can you make contact with another device, for example an Android device?

    • Exactly, first command works but the second,third etc doesnt.
      im sure that AT mode is on cause led blinks each 2 seconds (aprox), and when send an AT command i ge an OK, but only the firts time.
      I got a zs-040, and i already tried some AT comands. Also i tried to connect with my android, and it works.

  18. Do you have “Both NL & CR” set in the serial monitor?

    using sketch “Basic Bluetooth sketch HC-05_02_9600+ECHO” what do you get in the serial monitor?

  19. In your method 2 you are using a transistor on ground to switch power to the module. Then in your sketch you have

    // set pin 34 HIGH
    digitalWrite(BT_PIN34, HIGH);
    delay(100);

    // turn on the HC-05
    digitalWrite(BT_POWERPIN, HIGH);

    But setting pin 34 high while you have the ground disconnected (BT_POWERPIN is still low) will do nothing as without ground the high on pin 34 has no place to go.

      • If this works it’s pure luck as there will be a race condition between VCC and Pin 34 when ground is connected [digitalWrite(BT_POWERPIN, HIGH)]

        • I’ve tested the above circuit and it appears to work fine. It may be that there is protection on the BT module.

          However, you are correct that there may be an issue and I have updated the guide. The example now uses a PNP transistor on the high side.

  20. Hi, when the hc-05 sends for example the ok response, does is send \r\n at the end of the data or end sort of characters that shows that it wont transmit anymore.. As doing an array and pasting the response send by the bt on an lcd. Thnks

    • Yes there are NL and CR characters after the visible characters. If you are displaying the received data on an LCD you will need to remove them.

      You can perform a simple test by comparing the character just received with 10 or 13. 10 = NL. 13 = CR

      c = Serial.read();
      if (c==13) { … }
      if (c==10) { … }

      The NL character is the last character so if c==10 you are at the end of the line.

  21. I used method 1 to my HC-05 and Uno board. but It doesn’t work… as yours. there isn’t any response in serial monitor when I type “AT”. What is the problem?… :(
    I think my HC-05 enters AT mode because the red led blink in 2s interval. but AT mode doesn’t work i think. please let me know how can I do it…

  22. It sounds like you have the wrong baud rate or the connections are not correct.

    1. Double check the connections.

    2. Using the Basic Bluetooth sketch HC-05_AT_MODE_01 sketch, run the sketch, open serial monitor and cycle the power of the HC-05. If you do not get a start up message, try a different baud rate. Start at 9600 and keep going until you find one that works.

  23. I can get the HC_05 led to blink slowly but it will not give any feedback to my AT commands.
    have tried 9600 and 38400 as AT baudrate but no luck.
    Any suggestions?

    • Have you selected “Both NL & CR” in the serial monitor?

      Check the connections. You can follow the second example on the http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-in-slave-mode/ page. If 9600 does not work try other baud rates.

      Using the same sketch, open serial monitor and then cycle the power to the BT module. If you have the correct baud rate you should get a start up message. If you do not get a message, change the baud rate, recompile etc and try again.

      It is worth confirming you are in AT mode. Start the BT module in normal mode and use an Android device to scan for BT devices. Your HC-05 should be listed. Now put the HC-05 in to AT mode and rescan. The HC-05 should now disappear. If it still shows then it is not in AT mode.

      Lastly, try to confirm what module you have. Newer ebay modules are using the same breakout board but use a a different firmware. See the FC-114 posts.

      If you are still having trouble post a photo of your module and let me know what name is reported when you scan for BT devices.

  24. Thank you for your reply :)
    I had written a long reply with lots of data and details when I discovered that a 10M resistor had slipped into my stack of 1M’s and was playing a trick on my voltage divider.
    Thank you for your post.

    • Ha ha. Sounds like something I would do which is why I like to put little stickers on the resistors I use for bread boarding.

      Glad you got it figured out.

  25. Hello,May I know how to wire the two pins marked in HC-05,STATE and EN.Could you please specify how two wire these two pins generally?

  26. great work, thanks

    with the method1 for hc05 zs-040, you can query name with AT+NAME? without connection pin34
    just press the push button and send command serial monitor, it responds
    +NAME:HC-05
    OK
    and i think same for “full AT” commands, beware if you change baudrate uart

  27. Hi Martyn!
    I shorted pin 34 with EN pin. But now I cannot see my LED on BT module blinking 5 times a second by providing digital LOW to EN pin. Anyhow, if I provide digital HIGH to EN pin it blinks on/of f every second. What am I doing wrong here? How can I control configuring BT module either in Command mode or in Data mode as per my wish through my Arduino Code. Kindly help!

    • Start the BT module first, then bring pin 34 HIGH. This puts you in AT mode using the user defined baud rate. To exit AT mode bring pin 34 LOW.

      I think Example 4 is what you need. This allows the Arduino to control entering and exiting AT mode.

  28. Hi,

    I have pin 34 high (3.3v) and still AT+INIT, AT+INQ, AT+PAIR etc do not work, hence not getting no response what so ever when I enter the AT commands.

    Any suggestions?

    Thanks,

    Kyle.

  29. Hello Martyn,
    I have 2 arduino uno boards, each connected with HC05(with button and EN pin-ZS040). Of these I want to use my 1 HC05 module as master for some time say for a period of 1 minute and then as a slave for same period of time (1 minute); at this time I want to keep my other HC05 module as slave for first one minute and then as master for other minute. Within this span I want these 2 modules to connect with each other, exchange information and raise a flag when exchange is over; And then again configure one as master and other as slave and repeat the process. But I am totally confused about how should I do this using just arduino code without any human intervention. Could you kindly help and guide me here?

  30. Hi Bhoomika,

    Unfortunately I don’t have the time to create the code but this would be a really good way to learn Ardiono and Bluetooth.

    If you are not sure about controlling the HC-05s start with a manual process, get the 2 Arduinos communicating manually (you enter the commands via the serial monitor) and after you have worked out what commands to use and when you can create a sketch and let the Arduino do it.

    Start with example 4 above. Change the code so that the Arduino controls when the BT module uses Master mode and when it uses Slave mode. I would suggest adding an LED to the Arduino to show the mode the HC-05 is using. When doing the code use millis() rather than delay. You can find more information by search for “blink without delay” on the Arduino forums. After you have got the first Arduino working start on the second.

    .

  31. Pingback: GPS Clock Project – parte 3 – MUG Roma Tre

  32. Pingback: GPS Clock Project – parte 2 – MUG Roma Tre

  33. Hi,
    I tried to follow your excellent guidelines to make a connection with a PC instead of an Arduino but I have not been able to make it work.

    Will you be so kind to include some guidelines on how to do it with a PC?

    Thanks in advance!!

    • It is my understanding that the PC has to be the master device and has to initiate the connection. This means the HC-05 should be in slave mode. Turn on the HC-05 and then use the PC to search for Bluetooth devices.

  34. Hi Bhoomika,
    remember you need to add “\r\n” to the end of commands. BTserial.println(“AT”) should work but I prefer to add manually using print rather than println – BTserial.print(“AT\n\r”)

    • The only way I know in AT mode is to issue a LF and CR. This results in an error but once you have the error you can send new commands again. In data mode I don’t think you can flush the modules buffer.

  35. Hi Martyn,
    thanks for a great tute. I’m using HC 05 and HC 06 on two nano clones wired as per your tute.
    I followed it exactly and got the two BT units communicating however the two serial monitors only display (x,€ ϴ) when sent alpha-numeric chars from the other monitor. Also the SM on master displays the sent characters as typed. It looks like a baud rate issue but the baud rates are all set to 38400.

    Any suggestions would be appreciated.
    cheers Steve

  36. Hi, thank you very much for this tutorial it helped me a lot but I still have a problem. I get the OK respond and also the ones to AT+NAME and others but when I want to change the name or the password using commands as AT+NAMEmyname or AT+PSWDnnnn it sends me ERROR(0)
    Do you have an idea of what the problem could be ? (sorry for my bad english)

    • Do you have pin34 HIGH?

      Pressing the small button switch makes pin34 HIGH so just before sending the commands press and hold the button switch. Wait for the reply and then you can release.

  37. I have read many of your post about hc-05 module. I also experimenting with HC-05 FC-114 and eventually enter into AT mode following instruction here (after so many failed attempt) so thanks.

    But I wonder how many type of break-out board and firmware available out there? so far I assume you have encounter three type of breakout board (FC-114, ZS-040, FS-040 ) and bolutek firmware. But my FC-114 have firmware version: 2.0-20100601 which i’m not sure whose firmware is that (linvor, bolutek, or another).

    So can you point out a list of difference between various board and firmware you have encounter? thanks

  38. Hi,

    Thank you for sharing your work!
    I have a question, hope you help me.
    I want to tranfer files between two Arduino UNO’s using hc-05 bluetooth module. I have been searching for a couple of hours and seems nobody had similar project with me. Is it possible sending an audio file (.WAV in my case) from an Arduino to another Arduino using hc-05 module?
    Thank you in advance!

  39. Hello

    Excelent article, thanks a lot for sharing this.

    I can use and test each and everyone of the AT commands succesfully (Method 2). I can also pair my HC-04 ZS-40 to my Android smart phone but I just don’t know how to stablish a connection between them. I’ll appreciate any hints to acomplish such connection.

    Regards

  40. I’ve googled for a long time.. Can’t find out how to exit command mode. anyone? I see you using AT+RESET. Is that the only way? Wondering because if I tie the KEY pin HIGH i’m going to be stuck in command mode every time the module reboots.

  41. Please help me!!!
    I followed your instructions and changed the name if my module.
    Then turned off my module and powered it on again.
    I was able to find the new name on my phone and was able to connect it BUT :-(

    My HC-05 Enters Command mode insted of data Transfer mode

    (I am sating that my bluetooth module enters Command mode by looking at the LED blinking)

    • I also Tried AT+RESET it resets my name password an all.
      But still if I pair it enters Command mode

      PLS pls help

        • Martyn, I tried it.

          No use, Still having the same problem.

          My module has a button on top of EN(key) pin. I have to press in while making the 34pin high. It worked perfectly in command mode. It still does work in Command mode, but when i pair my module it does not show data transfer mode the led bliks like it does in Command mode when paired.

          Please help!!

  42. Hello sir.I have make a bluetooth robot which i can control it via android(tablet) and i have a problem with the code.I want from the robot to stop when connection lost or bluetooth disconnected.Now when the connection lost the robot go ahead and falls on the objects.How to add this line on the code?Can you help me please?Thank you for your time

    The bluetooth that i use is HC-05

    My code:

    #include

    Servo SERVO_1; // Initialize Servo1

    // Motor Control Variables
    int PWM1 = 9;
    int ENABLE1 = 8;
    int PWM2 = 5;
    int ENABLE2 = 7;
    int PWM3 = 3;
    int ENABLE3 = 4;
    int PWM4 = 6;
    int ENABLE4 = 2;

    void setup() {
    SERVO_1.attach(10);
    Serial.begin(9600);
    pinMode(ENABLE1, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE2, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE3, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE4, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος

    }

    void loop() {

    // see if there’s incoming serial data:
    if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    int incomingByte = Serial.read();
    // action depending on the instruction
    // as well as sending a confirmation back to the app
    switch (incomingByte) {
    case ‘F':
    moveForward();
    Serial.println(“Going forward”);
    break;
    case ‘L’ : // Case ‘L’ is received,
    SERVO_1.write (180); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘N':
    turnright();
    Serial.println(“Turning right”);
    break;
    case ‘M':
    turnleft();
    Serial.println(“Turning left”);
    break;
    case ‘O’ : // Case ‘L’ is received,
    SERVO_1.write (0); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘B':
    moveBackward();
    Serial.println(“Going forward”);
    break;
    case ‘P':
    SERVO_1.write(90); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘S':
    moveNone();
    Serial.println(“Stopping”);
    break;
    default:
    // if nothing matches, do nothing
    break;
    }
    }
    }
    void moveForward() {
    // turn the driving motor on to go forwards at set speed
    digitalWrite(ENABLE1, HIGH);
    digitalWrite(ENABLE2, HIGH);
    digitalWrite(ENABLE3, HIGH);
    digitalWrite(ENABLE4, HIGH);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);

    }

    void moveBackward() {
    // turn the driving motor on to go backwards at set speed
    digitalWrite(ENABLE1, LOW);
    digitalWrite(ENABLE2, LOW);
    digitalWrite(ENABLE3, LOW);
    digitalWrite(ENABLE4, LOW);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }
    void turnright() {
    digitalWrite(ENABLE1, HIGH);
    digitalWrite(ENABLE2, HIGH);
    digitalWrite(ENABLE3, LOW);
    digitalWrite(ENABLE4, LOW);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }

    void turnleft() {
    digitalWrite(ENABLE1, LOW);
    digitalWrite(ENABLE2, LOW);
    digitalWrite(ENABLE3, HIGH);
    digitalWrite(ENABLE4, HIGH);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }
    void moveNone() {
    // turn the driving motor off
    digitalWrite(ENABLE1, 0);
    digitalWrite(ENABLE2, 0);
    digitalWrite(ENABLE3, 0);
    digitalWrite(ENABLE4, 0);
    analogWrite(PWM1, 0);
    analogWrite(PWM2, 0);
    analogWrite(PWM3, 0);
    analogWrite(PWM4, 0);
    SERVO_1.detach();
    }

    • Hi Jack,

      probably the best method is to use the STATE pin on the HC-05. When the HC-05 is connected the STATE pin goes HIGH. Connect this to the Arduino and then in your sketch keep checking the pin state. HIGH means connected, LOW means not connected.

  43. Thank you sir for your reply.I modify the code and now i am getting this error
    case label “S” is not within a switch statement.

    What does this mean?Thank you again for your time

    The modified code:

    #include

    Servo SERVO_1; // Initialize Servo1

    // Motor Control Variables
    int PWM1 = 9;
    int ENABLE1 = 8;
    int PWM2 = 5;
    int ENABLE2 = 7;
    int PWM3 = 3;
    int ENABLE3 = 4;
    int PWM4 = 6;
    int ENABLE4 =12;
    int BTState=2;

    void setup() {
    SERVO_1.attach(10);
    Serial.begin(9600);
    pinMode(ENABLE1, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE2, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE3, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(ENABLE4, OUTPUT); //Δήλωση όλων των μεταβλητών ως έξοδος
    pinMode(BTState, INPUT);
    }

    void loop() {

    //Stop car when connection lost or bluetooth disconnected
    if(digitalRead(BTState)==LOW) { case ‘S': }

    // see if there’s incoming serial data:
    if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    int incomingByte = Serial.read();
    // action depending on the instruction
    // as well as sending a confirmation back to the app
    switch (incomingByte) {
    case ‘F':
    moveForward();
    Serial.println(“Going forward”);
    break;
    case ‘L’ : // Case ‘L’ is received,
    SERVO_1.write (180); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘N':
    turnright();
    Serial.println(“Turning right”);
    break;
    case ‘M':
    turnleft();
    Serial.println(“Turning left”);
    break;
    case ‘O’ : // Case ‘L’ is received,
    SERVO_1.write (0); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘B':
    moveBackward();
    Serial.println(“Going forward”);
    break;
    case ‘P':
    SERVO_1.write(90); // Στρίψε Αριστερά.
    SERVO_1.attach(10);
    break;
    case ‘S':
    moveNone();
    Serial.println(“Stopping”);
    break;
    default:
    // if nothing matches, do nothing
    break;
    }
    }
    }
    void moveForward() {
    // turn the driving motor on to go forwards at set speed
    digitalWrite(ENABLE1, HIGH);
    digitalWrite(ENABLE2, HIGH);
    digitalWrite(ENABLE3, HIGH);
    digitalWrite(ENABLE4, HIGH);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);

    }

    void moveBackward() {
    // turn the driving motor on to go backwards at set speed
    digitalWrite(ENABLE1, LOW);
    digitalWrite(ENABLE2, LOW);
    digitalWrite(ENABLE3, LOW);
    digitalWrite(ENABLE4, LOW);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }
    void turnright() {
    digitalWrite(ENABLE1, HIGH);
    digitalWrite(ENABLE2, HIGH);
    digitalWrite(ENABLE3, LOW);
    digitalWrite(ENABLE4, LOW);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }

    void turnleft() {
    digitalWrite(ENABLE1, LOW);
    digitalWrite(ENABLE2, LOW);
    digitalWrite(ENABLE3, HIGH);
    digitalWrite(ENABLE4, HIGH);
    analogWrite(PWM1, 255);
    analogWrite(PWM2, 255);
    analogWrite(PWM3, 255);
    analogWrite(PWM4, 255);
    }
    void moveNone() {
    // turn the driving motor off
    digitalWrite(ENABLE1, 0);
    digitalWrite(ENABLE2, 0);
    digitalWrite(ENABLE3, 0);
    digitalWrite(ENABLE4, 0);
    analogWrite(PWM1, 0);
    analogWrite(PWM2, 0);
    analogWrite(PWM3, 0);
    analogWrite(PWM4, 0);
    SERVO_1.detach();
    }

  44. The check on the BTstate should not use the case statement.

    use something like (not full code)

    if (BTstate pin == HIGH)
    {
    if (Serial.available() > 0) {
    int incomingByte = Serial.read();
    .
    .
    .

    }

    In this way you are only reading and processing commands when connected.

  45. Hi. is possible operate (AT commands) with the module throught the Arduino Nano in FTDI mode (RST+GND bridged)?

  46. Great and usefull guide!

    I personaly have a bare HC-05 connected to a Teensy LC (3.3V) so I can directly wire everything. Entering AT mode on booting works nice and easy but if I try method 3 or 4 I only get an Error(0) when I write AT :/

    Is this firmware related? And do you know where I can get the firmware your BT module uses?

    • After applying power, bring pin 34 HIGH and keep it HIGH. This will enter AT mode using the baud rate you set for communication. If you have not changed the baud rate it will use the default speed which is usually 9600.

  47. Martyn,
    thank you for your great work.
    I’ve bought 20 pcs HC-05 / ZS-040 again. The new ones differ from the old ones in that the „STATE” pins don’t show whether the devices are connected or not, but these pin are floating.
    Could you recommend some solution? Perhaps there are commands to set these features.
    Using sw work-around like “AT STATE?” command would mean some problems.
    Regards
    Tamas

    • Check which firmware you have and then see if one of the pins on the actual Bluetooth module (the small daughter board) is being used. It may be that the pin used is not connected. If this is the case you can connect a wire directly to the pin.

  48. Hi Martyn, you have done a great work explain how the hc-05 works, but i have a trouble, my BT conects but don´t give me an answer when I send “AT” or any other message, I checked all conections and are ok, I´m using an Arduino MEGA, I hope that you can help me

    • Hi,
      double check the connections, the resistor values and the baud rate.

      Almost every time somebody reports an issue it is because they have a wrong baud rate, incorrect connection or the resistor are incorrect.

      After rechecking the connections and resistor confirm you are actual entering AT mode by checking the LED blink rate.

      Since you are using the mega, you should one of the extra hardware serials rather than software serial.

      If still having issues take a step back and confirm basic communication works in slave mode. See http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-in-slave-mode/

  49. Martyn,
    thank you for your great work.

    In method 4, in communication mode HC-04 led is not blinking and in at mode led is blinking @ 2 sec interval, However, I can’t get response from HC-04 in serial monitor for at commands.

    I have checked my connections and resistors value.

  50. Hey

    Thanks for the detailed information.

    I’m trying to set things up but I’m conncting hc-05 to my PC using RS232 USB TTL cable. No arduino.

    I’m able to get the led to blink slowly by holding the key down while powering up, which means its in AT mode.

    Set arduino serial to NL+CR, 38400 baud rate.

    Getting no response on AT commands.Just accepts the command but no output. What am I doing wrong?

Leave a Reply

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


+ seven = 8

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=""> <s> <strike> <strong>