0

As an introduction, I bought myself an arduino and a few modules to learn some software stuff. The project is to eventually connect to a bluetooth OBD2 reader on my car to display real time data on a small LCD.

The problem

I am either not able to connect to, or not write to, my HC05 module via software serial. I think I have narrowed this down to a couple possibilities.

  1. I am unable to connect to the module in the first place.

I have a Mega 2560 and HC05.

5V <-> VCC

GND <-> GND

D2 <-> RXD

D3 <-> TXD

Note that I have seen 9600 and 38400 baud rates for connecting but neither worked, so I made this function to try them all for me...

//set up serial relay into HC05.
SoftwareSerial hc05(2,3);

//computer serial baud rate 115200

bool hc05_connect() { 
  long baud_list[] = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400}; 
  Serial.println("Attempting to connect to HC05 bluetooth module...");
  bool success = 0;
  for (int i=0; i<(sizeof(baud_list) / sizeof(baud_list[0])); i++) {
    Serial.print("Baud rate ");
    Serial.print(baud_list[i]);
    Serial.print("...");
    hc05.begin(baud_list[i]);
    hc05.write("AT");
    delay(1000);
    if (hc05.available()) {
      Serial.println(" successful!");
      success = 1;
      return success;
    } else {
      Serial.println(" failed");
    }
  }
  return success;
}

Notes:

  • This has always returned failed for every baud rate.
  • I have the bluetooth module in command mode, initiated by pressing the button as I supply power.
  • I have tried unplugging the TX/RX pins while uploading the sketch. No difference noted.
  1. My attempts to send commands to the HC05 are failing.

Below is my function for sending commands to the module.

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

  // listen for user input and send it to the ESP8266
  if (Serial.available() > 0) {
    Serial.println("Writing to hc05...");
    Serial.println(Serial.available());
    Serial.println(Serial.read());
    hc05.write(Serial.read());
  }
}

I have added in a few lines which write back to Serial so I can see what's being sent, and the monitor returns weird stuff. For example, if I send "AT", this is what the monitor reads:

Writing to hc05...
3
65
Writing to hc05...
1
10

Notes:

  • Why is it sending 2 different items?
  • Why is it sending integers rather than the characters I said?
  • Does this indicate I'm just sending it nonsense commands so it's not responding?

I can provide full code if you want, this is already a huge textwall though. Please help me!

Edit

So I have been able to get communication two ways via the bluetooth module using a modified version of the code in this instructable: https://www.instructables.com/How-to-Set-Up-and-Test-Arduino-Bluetooth-Connectio/

I was able to send from PC only and not receive to an android bluetooth terminal using SoftwareSerial with HC05's RX - TX0 / TX - RX0. And I was able to receive to PC and not send using hardware serial / Serial1 with HC05's RX - TX1 / TX - RX1.

So now I have RX - TX0 / TX - RX1. It seems to communicate through terminal like this.

void setup() {
  Serial.begin(9600); //open the serial port
  Serial1.begin(9600);
}

void loop() {
  if (Serial1.available()) {
    Serial.print("(Received)");
    Serial.println(Serial1.readString()); // send from serial to bluetooth
  }
  if (Serial.available()) {
    Serial.print("(Sent)");
    Serial.println(Serial.readString());
    Serial1.println(Serial.readString()); // send from bluetooth to serial
  }
}

But if I apply this to my code, I still can't get it to work.

Before I try to hack this together, why am I getting serial to work across 2 different serial channels? Weird...

omfaer
  • 184
  • 3
  • 16
  • Try using something like the [terminal app](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&utm_source=www.apk4fun.com) on your phone to test your connection to the HC-05. Also, I can never remember if the Rx/Tx lines need to be swapped. Have you tried with `SoftwareSerial hc05(3,2);`? – ukBaz Oct 03 '20 at 07:11
  • Mega has 4 hardware Serial ports. why do you use SoftwareSerial? not all pins of Mega support SoftwareSerial – Juraj Oct 03 '20 at 08:34
  • Thanks guys. I have had some success, but it raised many questions - see edit. – m.murphy3711 Oct 05 '20 at 11:55
  • "RX - TX0 / TX - RX1" TX0? – Juraj Oct 06 '20 at 05:43
  • Hi @juraj, sorry I was struggling to describe simply. Basically, RX from HC05 into port TX0 on Mega (aka D1) etc. – m.murphy3711 Oct 06 '20 at 11:00

2 Answers2

1

Okay, so I figured it out. (I can't say I fully understand, but maybe this will help people in future.)

1. Unable to connect to module

Thanks @ukBaz for suggesting I connect with the terminal app on my phone, this allowed me to debug the connection to the module in the first place. and @Juraj for suggesting that the Mega uses hardware serial.

Serial1 apparently is broken on my board, so I am using Serial3. I bluetoothed to the device with my phone, and was able to send commands back and forth between Serial and Serial3 both on 9600 baud rate. Here is the code I used:

void setup() {
  Serial.begin(9600); //open the serial port to PC
  Serial3.begin(9600); //open serial port to HC05. TX -> 15, RX -> 14
}

void loop() {
  if(Serial3.available()){
    Serial.print(Serial3.readString()); // send from serial to bluetooth
  }
  if(Serial.available()){
    Serial3.print(Serial.readString()); // send from bluetooth to serial
  }
}

I suspect I was using the wrong read/readString and write/print/println for my purpose initially.

2. Unable to issue commands to the module

Once I got that working, I changed the baud rate to 38400, and tied the STATE pin of the module to VCC (rather than using the button). Uploaded code, disconnected 5V, reconnected 5V, reset arduino.

At that point, I could issue "AT" to the module via Serial Monitor, and receive "OK" back. Woohoo!

I think I understand now that @hlovdal was suggesting that I was issuing a command to the module and never parsing a response I got, so it was.. clogged parhaps? In any case. I can now successfully issue commands and receive responses from the module.

Thanks everyone for your help.

-1

There are some problems with how you are communicating AT command lines to your device. For instance:

hc05.write("AT");
delay(1000);

You do not send an AT command to a modem, you send an AT command line that contains zero or more AT commands, followed by a command line terminating character (that always should be '\r', aka carriage return (or <CR>)).

You are missing that terminating character here, so the modem will never send you a reply, because you have not sent it a command line.

And also, you should never, ever use delay as a substitute for reading and parsing the responses that the modem sends back. See this answer for some more details.

Makyen
  • 31,849
  • 12
  • 86
  • 121
hlovdal
  • 26,565
  • 10
  • 94
  • 165
  • Thank you for your answer @hlovdal, I will implement this in my code. I should note that I don't expect it to change anything, other than correctly telling me whether it's connected or not - when I use serial monitor to sent "AT" it will still fail to respond, whether I connect to/read with 9600 or 38400 baud rate. Could you explain in simple terms (I'm a beginner) why I shouldn't use a delay, and what I can do instead? I am not yet capable enough to understand the answer you have linked. – m.murphy3711 Oct 09 '20 at 00:51
  • Just as you would not attempt to write a web browser that sends a HTTP request to the web server but then ignore any response it sends back, you should not write code that sends AT commands to a modem but then ignores any response it sends back. When the modem is done processing an AT command line (which might takes many, many seconds) then it sends a *Final Result Code* to indicate that it is done. After having sent a command line, your code should never send anything to the modem again before receiving a final result code. That is why you need to read and parse the responses from the modem. – hlovdal Oct 09 '20 at 10:03
  • OK. So here I have updated my `setup()` loop to `Serial3.write("AT\r");` and then `while ( !Serial3.available() );`. This is my best attempt to wait for a final result (?). The program now sticks in the `while` loop forever. – m.murphy3711 Oct 10 '20 at 03:31
  • See [this](https://stackoverflow.com/a/36899432/23118), [this](https://stackoverflow.com/a/36873777/23118) and [this](https://stackoverflow.com/a/37977157/23118) answer which contains descriptions of the steps needed (and some more for some of the answers). – hlovdal Oct 10 '20 at 10:15