I have been attempting to program my HC-05 ZS-040 Bluetooth module for quite some time, and I cannot get the AT commands to return any values. I have searched google for quite some time, and I none of the answers seem to work for me. I have been following along with this website:


I am using an Arduino Mega 2560 clone by Elegoo to program this Bluetooth module. Currently I have it wired up using this diagram


Currently I have it modified slightly to use a voltage divider between the Arduino's Tx and the HC-05 Rx, as the HC-05 works on 3.3v logic. The one possibility I think could be causing this problem is that the Arduino Mega is just interpreting all Tx incorrectly as I measured that it sounds ardoun 3.2 volts for a high voltage. According to multiple websites the HC-05 is in AT command mode when the LED flashes slowly, about once every 2 seconds, which is happening. I put it in command mode by holding down the button above the EN pin while providing power to the HC-05.

I have been using pin 14 and 15, which are Hardware Serial3 on the Arduino Mega. Here is the code I have written:

  Software serial multple serial test

 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.
#include <SoftwareSerial.h>

SoftwareSerial mySerial(15, 14); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  // set the data rate for the SoftwareSerial port

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

Any suggestions are much appreciated!

EDIT: I have now received some unrecognizable responses from the controller after sending AT multiple times, here is the screenshot, included is a video of my circuit, which shows how the LED is flashing:


The only modification to the code is adding a Serial.println("TESTING"); in the while loop that reads Serial3. I have tried using other Hardware serial ports as well, all with the same result as the above screenshot.

  • I looked more closely at your code and I believe I see the problem now. I'll add the additional info in my answer, but did you notice that you set up the mySerial object, but you don't actually reference it in the code? Your mySerial is analogous to my BTSerial object. I'll write your code as it should be in my answer so you can copy it and try it. – raddevus Jun 23 '18 at 2:15

###### Try This : Your Code Updated With Possible Fixes ######

After examining your code and comparing it to my working code I believe I have found a definitive answer. I'm altering your code so you can copy it and try it. I'll add comments where I've changed it.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(15, 14); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.println("Enter AT commands:"); // a prompt in Serial Monitor
  // Deleted while loop, unnecessary

  // set the data rate for the SoftwareSerial port
  // notice that your comment on previous line says SoftwareSerial port
  // but you are setting the Serial3 port -- this is where we use mySerial
  // Serial3.begin(38400); // commented your line of code

void loop() { // run over and over
  //if (Serial3.available()) { // we don't use Serial3 any more
  if (mySerial.available()) {
  if (Serial.available()) {

I am confident that if you use this newly modified code it will solve your problem. I should've noticed this earlier.

Here's the rest of my original answer.

I have struggled with this myself. As a matter of fact it took me a few months of owning some HC-05s before I finally dug up an answer. It's been a while since I worked with it so I'll do my best to explain what to do.

Arduino Nano

Also, I use an Arduino Nano to do the programming of the HC-05.

This Setup Lets You Alter HC-05

Once you wire it up and run the program (included here) you will be able to send any of the HC-05 commands and they work great. You can change the name of the device, the 4-digit pass-code and everything.

Crude Snapshot, But Enough To Build Simple Circuit

I also have a crude snapshot* of the circuit I used (at the time just for documenting it for my own memory) but I think we can work you thru it. and I know those wires are all crammed together and it almost looks like they are in the same breadboardholes but they are actually hooked up properly. I was so excited it finally worked I snapped the pic too fast.

*see image below

Here's the code I use:

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX | TX

void setup()
  //pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  //digitalWrite(9, HIGH);
  Serial.println("Enter AT commands:");
  BTSerial.begin(38400);  // HC-05 default speed in AT command more

void loop()

  // Keep reading from HC-05 and send to Arduino Serial Monitor

  if (BTSerial.available())
     //Serial.println("bt available...");

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())

Does Your HC-05 Have the Button?

Okay, so the first thing is to check to see if your HC-05 has the little button on it? If it does that has to be held when you apply power to the circuit. The HC-05 will blink and then it will be in COMMAND mode and you can let go.

If No Button

You can see that mine has the button. That is why the first two lines the setup() method are commented out. I don't need D9 to go high (it is not connected to the pin) because mine has the button. If yours has the button (most likely does) then you don't even have to worry about it.

Looking Back At Your Question

Now that I look back at your sample code it could be that you're not aware that you have to hold that button when you power up. Or you don't know that you need to connect that wire to keep the HC-05 in command mode.

Pins For TX / RX

That's probably the problem you are having, because everything else looks the same -- except you are using 15 and 14 for TX / RX. I am using D10 and D11 for mine and I remember something about those pins in the back of my mind so if yours still doesn't work, try switching to those and try using my code.

I remember the first time I finally got this working and I was dancing around the room. Good luck and I hope you are dancing soon. :)

hc-05 via nano

  • Thanks for the response! I tried your suggestion to use pins 10 and 11 however I got no response. I have been pressing down the button while applying power, and the indicator LED is one for two seconds, then off for two seconds. However when using the Hardware serial ports on my Mega 2560, I get responses now in the serial monitor, and managed to change the name of the HC-05, but the responses are still unreadable. Could it be that the HC-05 high (3.3v) is not enough for the Arduino Mega to interpret as a high value, thus sometimes the response appears okay and other times it doesn't? – Justin VanderBerg Jun 22 '18 at 15:29
  • @JustinVanderBerg I think that is a good guess, but I'm not sure about it because I don't have experience with Mega. It may be worth it to you to buy this pack of 3 Nanos amzn.to/2MOfHYE ($12.68USD) at Amazon and use one of them to program your HC-05. Sorry i couldn't be more help with this. Like I said, I struggled with it for a few months trying off and on to resolve it. – raddevus Jun 22 '18 at 16:04
  • @JustinVanderBerg I was thinking about this again and if you are getting garbled text that often means the speed does not match. I noticed yesterday that even though my Arduino was writing to serial port at 9600 (via setting in software) I actually had to set the Arduino IDE Serial Monitor to 19200 to get valid output. My point is, have you tried setting the speed to different values in the Serial Monitor? It may be that the HC-05 is defaulting to 9600 -- which is the default for regular data send mode. It may be worth a try. – raddevus Jun 22 '18 at 16:43

Thanks for all the help! I had given up on getting Bluetooth module to work, however when working with a simple RGB LED, I noticed my mistake. I was using the ground from my breadboard power supply for the module instead of the ground from the Arduino Mega. I rewired my breadboard so the ground and power come from my Arduino Mega, and everything works perfectly! I ended up using the exact same code that I posted in my original question, so it was just that I was not using the ground from my Arduino Mega

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.