PROGMEM bluetooth communication not working

Hello,

I'm trying to create a robot controlled by commands through bluetooth from a phone app i made in MIT App Inventor. The commands look like this:

example: "@sc0&"
"@" = routing symbol (routes the command to the correct function)
"sc0" = the command itself (this one is supposed to change speed to 0)
"&" = ending symbol (symbolizes the end of command, intended to fix a bug where the app would send two commands instead of one when two buttons were pressed too quickly, I wasn't able to get it working sadly)

The code should the following way:

void loop is continuously checking if Serial has available data and if it does, it writes it down to the variable InputString, afterwards it adds a NULL character.
it then calls the fucnction "RouteCommand", which checks the routing symbol and routes it to its correct function.
The correct Function then compares the input to the commands saved in PROGMEM and changes global values, which then influence the robot's movement.

But for some reason, whenever i send a command, the program just stops working.
I added a Serial.print to the RouteCommand function, so I can see what the program recieves.
here's what happens:

program turned on
connected through bluetooth, no problems so far
I try to send a command "#0&" which should stop the robot's movement
Serial monitor shows "#0⸮"
I try to send another command
Serial monitor shows "#0⸮⸮"
now whenever I try to send another command it adds a "⸮"

Code attached

What am i doing wrong?

robot_control_system_2.ino (8.73 KB)

afterwards it adds a NULL character.

Where in the code does it do that ?

TGelectronics:
What am i doing wrong?

For one, improper input handling. Read Robin2's tutorial and understand it,
then modify it to match the normal comunication circumstances
which are lines delimited by CR and often LF.

//RX-TX communication
const byte TX PROGMEM = 1;
const byte RX PROGMEM = 1;

  pinMode(TX, OUTPUT);
  pinMode(RX, INPUT);

What kind of pinMode Bingo is that?

char inputString[33];

    inputString[Cwriter] = "\n";

Enable warnings, the above does not what you think it does.

 if(strcmp(strcpy_P(ProgBuff, (char *)pgm_read_word(&(cmd_cmp[9]))), inputStr) == 0){

There is a strcmp_P function, I would write the above like so

 if (!strcmp_P(inputStr, (char *)pgm_read_word(cmd_cmp + 9))) {

I would test for the commands in a for loop.

//prints an information line using minimal resources
void sendCommand(char inp){
  const char *p;
  p = inp;
  while(*p){
    Serial.print(*p);
    p++;
  }
}

The comment is needed, I would have thought the function would send a command, silly me.
But it's crap anyway, obviously untested.

BTW

 Serial.print(informationLine); //prints an information line using minimal resources

You use delays to control some/all timing.

Magical constants all over the place.

You have a long way to go,
start by enabling all warnings and fix them, most of them are real errors.

I rewrote the entire code using Robin2's tutorial and it's working perfectly, thank you for your help!

So maybe you should post the sketch you are happy with,
so other people might benefit from that?

Here is the new Code.

robot_control_system_3.ino (5.84 KB)

You can tidy that up considerably.

Take this for instance

  if (inputString[0] == '#')
  {
    changeRobotDirection(inputString);
  }

You determine that the first character of inputString is '#' so call the function
Then, in the function you do this

void changeRobotDirection(char inpStr[])
{
  if (strcmp("#0", inpStr) == 0)
  {
    Rdirection = 0;
  }
  else if (strcmp("#1", inpStr) == 0)
  {
    Rdirection = 1;
  }
  else if (strcmp("#2", inpStr) == 0)
  {
    Rdirection = 2;
  }
etc, etc

So Rdirection is being set to inpStr[1] - '0'. This means that there is no need for the series of comparisons as you can do it with just one statement. The same goes for other functions in your code

I didn't know it's possible to change char into int, but it shortened the code significantly, thank you for suggesting that. I also created a new function to shorten up the moveRobot function a bit.

robot_control_system_3_cleaned.ino (4.52 KB)

I also created a new function to shorten up the moveRobot function a bit.

You can shorten it a more by eliminating many of the switch/cases

Declare a 2 dimensional array of booleans with each row containing the appropriate combination of values that you want to write for that row. For instance, row 0 of the array would contain false, false, false, false and row 1 would contain true, false, true, false and so on up to your 9 rows

Now, with the value of dir between 0 and 8 you can do this

writeDirection(dir);

and inside the function use the values in the array for that row to control the robot.

if (theArray[0] == true)
  {
    digitalWrite(leftForward, HIGH);
  }
  else
  {
    digitalWrite(leftForward, LOW);
  }
and so on
      delay(10 - halffast + halffast);

Rather pointless computation in that ugly delay.

Ive cleaned it further.

robot_control_system_3_cleaned.ino (4.15 KB)