HC-05 receiving mixed order of bytes on high baud rate

Hello everyone. I have a problem, with which I am afraid I won't deal on my own. will appreciate any suggestions or help.

I am using Arduino Micro with HC-05 module. It's used as remote driver for four DC motors. To handle that I am generating on source device (Android smartphone) 4-byte message, which should transfer with first two bytes a channel number, and in latter two bytes a power, that should be delivered to the selected channel.

I've started the project with default hc-05 baud rate - 9600, where everything was working well, using following code to get messages decoded:

//Serial1 is hardware port to which I have HC-05 connected
if(Serial1.available()){
    byte msg[4];
    int bytesRead = Serial1.readBytes(msg,4); //sender is emitting only 4-byte messages so I guess I should always get valid set of bytes

    int channel = word(msg[0],msg[1]); //read PWM channel
    int power = word(msg[2],msg[3]); // read power: <0,4095>

    //output for debugging
    Serial.print(channel);
    Serial.print(":");
    Serial.print(power);
    Serial.print("\n");
}

In general it should return numbers like:
0:0
4:0
8:0
12:0
0:345
4:1034
8:800
12:2500

etc.

Unfortunately it turned out that desired frequency of channel updates exceeds 9600 baud rate, so I modified HC-05 to use 115200, and updated my code accordingly.

Then I got into troubles, because data I started to get from HC-05 module is really messed up. Generally it looks like I am not getting bytes sent from source device in order in which they were sent. Few first messages are decoded correctly, then it starts to look like total mess with unexpected results.

I saw few topics discussing similar behavior, but none of them delivered answer to questions what causes such issues, as well as any fix more sophisticated than lowering baud rate to default. I think I might be able to implement software signal buffering and retrieve right order of bytes on my own, but I believe it would be silly to do something like that manually once I have hardware UART interface, right?

joorva:
Then I got into troubles, because data I started to get from HC-05 module is really messed up. Generally it looks like I am not getting bytes sent from source device in order in which they were sent. Few first messages are decoded correctly, then it starts to look like total mess with unexpected results.

If the data is not perfect you should consider it all corrupt.

Does it work at an internediate baud rate - say 38400 or 57600 ?

You might like to try one of the examples in Serial Input Basics - simple reliable ways to receive data. The system in the 3rd example will be most reliable if you have scope to modify how the data is sent.

...R

Thanks for reply.

I tried some speeds between 115200 and 9600, and none worked good. I also modified the way it reads bytes from readBytes function to read() and series of loops to make sure I am reading 4-byte chunks. None of that worked.

Next step I'll try to implements ping-pong style communication, where receiver will confirm getting of each byte, and sender won't send another without confirmation. Some overhead on communication, but this have to work.

I looked at examples you showed me. Generally they are build in a way I understand BT communication should work. But I don't see there any way of handling issue like mine.

joorva:
But I don't see there any way of handling issue like mine.

My code won't solve the problem but it should make it easier to reject invalid data.

How are you powering the HC05? - inadequate current could impact on its ability to work at higher speed. The Arduino 3.3v pin has a very low current capability. Adding a 10µF capacitor may help, but a separate 3.3v supply may be required. I have produced 3.3v from the Arduino 5v pin using an LM317 voltage regulator. (That was for an ESP8266 WiFi module which requires a lot of current).

...R

Good point about power. I am using regular 3.3V output (it should give just enough current according to papers, but does not have any space for any imprecisions). Need to check voltage during work.

Still I wonder how it could work then correctly at all? Does UART interface with adjusted baud rate consumes so much more energy than default one? I assume that BT module itself works same way no matter how fast UART is working.

joorva:
I assume that BT module itself works same way no matter how fast UART is working.

That is surely correct. The baud rate should have no bearing on the problem, so long as your code matches the configured rate. Exactly what BT module are you using?

joorva:
I assume that BT module itself works same way no matter how fast UART is working.

That sounds sensible. But adding a 10µF capacitor between 3.3v and GND might help to verify it.

...R

@Nick_Pyner
I am using this guy:

@Robin2
Sounds like good option. Will definitely try.

@Robin2 on the other hand I have seen no sings of power issues on 3.3v output. I was measuring it during (faulty) transmission and it was rock solid 3.3.

joorva:
@Robin2 on the other hand I have seen no sings of power issues on 3.3v output. I was measuring it during (faulty) transmission and it was rock solid 3.3.

If you were not using an oscilloscope you don't have any useful data. Things that vary within 62.5 nano-seconds matter.

...R

Robin2:
If you were not using an oscilloscope you don't have any useful data. Things that vary within 62.5 nano-seconds matter.

...R

Good point. I do not own an oscilloscope. Maybe it's time to get one...

Anyway I think I solved my case, seems to be 100% my fault. Hardware is good, issue was in my software. Generally, the way I was reading from BT device I assumed that I find always 4 bytes of data waiting for me in buffer and this is all I should care about. It seems that two facts were missed by me:
-> my code was processing data slower than sender was sending it (sender sends 16 bytes of data in every 2 ms, receiver takes in each loop 4 bytes and processes it, having also delay(1) function executed in each iteration (great flaw of mine) - left there just in case - which made it over 4ms to process whole chunk of data).
-> having such variance in input/output speed, it was only a matter of time when buffer got overflowed. Easy to get situation when, with buffer almost full, only a part of data chunk got stored. Then I got a shift between data chunks from sender and receiver, which resulted in totally messed up output.

It's still kind of not clear to me why it was working well on slower baud rates, but I assume that it was just minimizing a chance of data chunk incoming to receiver's buffer when there was not enough room for full set of bytes.

To get it fixed, I've done following things:

  • reorganized code in a way that it is not executing delay(1) function during data transfer, which makes my Arduino to read data as fast as CPU allows
  • changed format of messages with data to utilize Serial.readBytesUntil() instead of reading fixed amount of individual bytes. (kind of what was proposed in "Serial Input Basics" earlier :wink: ).

After all these fixes it seems that my board is able to smoothly process all data it gets.

Thanks for your help and time, Robin2. Even that my issue was related to software, I learned a lot from your suggestions and comments.