Problem of receiving bytes with Bluetooth

Hi,
I am making an android car using HC 05, the car has 3 operating modes: Line follower , obstacle avoiding , and Joystick app control. the mode is chosen by sending 1 byte from the app to the arduino and Joystick sends 2 bytes (x and y)
1.I want to choose the operating mode first and then if Joystick is chosen, start to receive the x and y coordinates. I tried the code below and could not get it to work as soon as it is in mode one I get Coordinates: -1,-1 in the serial monitor .
For the app im using when joystick is dragged send x(1byte) and y(1byte)
and for other buttons im just using send 1 byte

#include <SoftwareSerial.h>

SoftwareSerial BT(10, 11); // RX, TX

int bt_data; // variable to receive data from the serial port
int mode=0;

Serial.begin(38400);
BT.begin(38400); // Default communication rate of the Bluetooth module
delay(500);
}

void loop() {
  
if(BT.available() > 0){  
bt_data = BT.read();  
if(bt_data == 1){Serial.println("mode0");mode=0;}    //Manual Android Joystick Application
else if(bt_data == 3){Serial.println("mode1");mode=1; } //Auto Line Follower Command
else if(bt_data ==5){Serial.println("mode2");mode=2;} //Auto Obstacle Avoiding Command
}
if(mode == 0){
    xAxis = BT.read();
    delay(10);
    yAxis = BT.read();
   Serial.print("Coordinates: ");
   Serial.print(xAxis);
   Serial.print(",");
   Serial.println(yAxis);
  }
 }
  1. I also have other buttons for lights ,blinkers... How can i make the data not interfere with the coordinates(2 bytes) while sending all 3 bytes at the same time.

Serial.Read will return -1 if no data yet available.

RETURNS
"The first byte of incoming serial data available (or -1 if no data is available) - int ."

When sending multiple commands one way is to make all have same length. Maybe send some start sequence or bytes to reset the receiver.

Sending numbers in ascii may be simpler by delimiting each command with a ; or similar and each parameter using ,.

Then you can parse the string for char 0..9 and as long as there is number add it to a sum after sum first multiplied by 10.

sum *= 10;
sum += character - '0';

Or use Serial.parseInt() function.

Show us the blocks on how to send data from the app. Does the mode selection work well? Recognizes 1, 3 and 5 well?

thank you for the advice, can you explain to me more what do you mean by "make all have same length"?

3
it is simply when click send 3

This button selects mode1?

yes

Does it work correctly? Do you see mode1 in the serial monitor?


it works fine but if I add this condition it stops , any idea why?
aa

Okay, looks like it's working. Now show the blocks that send data from the joystick. And what do you get in serial monitor.

Serial.read receives data from the buffer, if the buffer is empty maybe it stops the program? Don't check it this way. First get the data into the variable, then check the value in the variable.

Continue the problem and the arduino code from the first post, because you wrote that you receive -1.

2


the output is non stop -1 when the mode is 0 because no data is received as @Tore_Forsgren stated. if i move the joystick i get some interfering values.
using the code below gives correct x , y coordinates.

while( BT.available() >= 2 ) {
    xAxis = BT.read();
    delay(10);
    yAxis = BT.read();
   Serial.print("Coordinates: ");
   Serial.print(xAxis);
   Serial.print(",");
   Serial.println(yAxis);
  }

I think I understand your problem. With your code you must always send 3 bytes of data for this to work. If you send 1 byte once and 2 bytes once, you need to change the way you receive data in your arduino code.

yes thats it, and I have other buttons that can be pressed simultaneously so it will be more than 3 bytes.

You send 2 bytes...

void loop() {
  
if(BT.available() > 0){  
bt_data = BT.read();  // here received first byte
if(bt_data == 1){Serial.println("mode0");mode=0;}    //Manual Android Joystick Application
else if(bt_data == 3){Serial.println("mode1");mode=1; } //Auto Line Follower Command
else if(bt_data ==5){Serial.println("mode2");mode=2;} //Auto Obstacle Avoiding Command
}
if(mode == 0){
    xAxis = BT.read(); // here received second byte
    delay(10);
    yAxis = BT.read(); // here no byte to received, -1

I think you should use tags as well, not just bytes. It will be difficult to distinguish what is what in the arduino code... the program will fail... eg:

  • mode change: "m|0", "m|1", "m|2".
  • coordinates: "x|12", "y|9"
void loop() {
  
if(BT.available() > 0) {  
  bt_tag = BT.readStringUtil("|");  
  if(bt_tag == "m") {
    bt_data = BT.read();
    Serial.println("mode" + bt_data);
    mode = bt_data;
  } else if(bt_tag == "x" || bt_tag == "y") {
    if(mode == 0) {
      if(bt_tag == "x") {
        xAxis = BT.read();
      } else if(bt_tag =="y") {
        yAxis = BT.read();
      }
      Serial.print("Coordinates: ");
      Serial.print(xAxis);
      Serial.print(",");
      Serial.println(yAxis);
   }
}

You recommend that I use the send text block ?

Try it:


blocks - 2023-05-06T125400.846

Thank you very much for your time. I will try it out and give you feedback.