Get command from serial

void setup()
{
  Serial.begin(9600, SERIAL_8N1);  			//USB-Prog. Port
  Serial1.begin(9600, SERIAL_8N1);			//Serial Device
  Serial.setTimeout(500);
  Serial1.setTimeout(50);
}

void loop()
{
  char command = Serial1.read();
  switch (command)
  {
    case 'a':
    routine1();
    break;
    case 'b':
    routine2();
    break;
  }
}

void routine1()
{
    Serial.println("received-a");
}

void routine2()
{
    Serial.println("received-b");
}

this works great already

however, I would like to use longer cases than a single character. But Strings don't work with these switch cases :thinking: any suggestions?

You can compare strings with '=' because it's overloaded in the String class. So instead of a switch case, you can just use a series of if-else blocks.

1 Like

You are reading from the serial receive buffer before you know that there is anything in the buffer to read. I suggest that you check out the serial input basics tutorial.

Don't worry, I know about "if serial available", just wanted the sketch as simple as it gets

Then you should correct the sketch of Post-1.

So I tried this

void setup()
{
  Serial.begin(9600, SERIAL_8N1);  		//USB-Prog. Port
  Serial1.begin(9600, SERIAL_8N1);		//Serial Device
  Serial.setTimeout(500);
  Serial1.setTimeout(50);
}

void loop()
{
  String command = Serial1.readString();
  String a = "routine1";
  String b = "routine2";
  while (command == a){
  Serial.println("received-a");
  }
  if (command == b){
  Serial.println("received-b");
  }
  else {
  //do nothing.. for the moment :)
  }
}

This doesn't work because it misses line feed / carriage return characters, I guess

Where in this loop, is the value of 'command' changed?

1 Like

this is it

void setup()
{
  Serial.begin(9600, SERIAL_8N1);  		//USB-Prog. Port
  Serial1.begin(9600, SERIAL_8N1);		//Serial Device
  Serial.setTimeout(500);
  Serial1.setTimeout(50);
}

void loop()
{
  String command = Serial1.readString();
  command.trim();
  String a = "routine1";
  String b = "routine2";
  while (command == a){
  Serial.println("received-a");
  command = "0";
  }
  if (command == b){
  Serial.println("received-b");
  command = "0";
  }
  else {
  //do nothing.. for the moment :)
  }
}

command.trim();

this will trim CR & LF

by the way, I use a simple batch file with an serial to usb adapter to emulate the serial device

MODE COM5 BAUD=9600 PARITY=N TO=ON DATA=8 STOP=1 XON=OFF
ECHO routine1 >COM5

Did you possibly mean

  if (command == a){
  Serial.println("received-a");
  command = "0";
  }

Is the above coding style of Post-8 correct (though it is working!) without checking the availability of data bytes in the Serial Buffer?

even better:

void setup()
{
  Serial.begin(9600, SERIAL_8N1);  		//USB-Prog. Port
  Serial1.begin(9600, SERIAL_8N1);		//Serial Device
  Serial.setTimeout(500);
  Serial1.setTimeout(50);
}

void loop()
{
  if (Serial1.available() > 0) {
  String command = Serial1.readString();
  command.trim(); 
  if (command == "routine1"){
  Serial.println("received-a");
  command = "0";
  }
  if (command == "routine2"){
  Serial.println("received-b");
  command = "0";
  }
  else {
  //do nothing.. for the moment :)
  }
  }
}

Perhaps, you are known that the veteran programmers of this Forum discourage to use the String data type in programming particulalrly in AVR Flatform. However, you are safe in DUE Platform as it contains a 32-bit MCU with large on-board memory.

It would still be a good practice to avoid the use of String data type in favor of cstring; where, strcmp() function could be used to compare two strings.

void loop() {

start:
pwrErr = 0;

if (Serial2.available() > 0) {
command = Serial2.readString();
command.trim();

if (command == "auto") {
delay(tOPing);
String C00 = "0";

Serial1.println("CPM");
CPM = Serial1.readString();
CPM.trim();
if (CPM.substring(1) == "APM") {
Serial.println(CPM + " Ping OK");
myNex.writeStr("t1.txt+", "Ping OK...\\r");
tstCnt++;
} else {
digitalWrite(RELPWR, LOW);
serErr = 1;
Serial.println(CPM + "Ping fail");
myNex.writeStr("t1.txt+", "Failed...\\r");
myNex.writeStr("t1.txt+", "Aborted\\r");
myNex.writeStr("t2.txt", (String) "Failed  -  (" + tstCnt + "/" + totTst + ") OK");
myNex.writeNum("t2.bco", 63488);

delay(tO1);
myNex.writeStr("b4.txt", "Repeat");
myNex.writeStr("vis b4,1");
myNex.writeStr("vis b5,1");
myNex.writeStr("vis b6,1");

delay(tO1);
goto start;
}
}

There is another issue with that part of my code, without the tO1 delays, it does not print all the strings to the nextion touchscreen. It somehow jumps back to start too quick.
The code works great but I don't like it.
I know its not a good idea to use "goto", any other ideas?

Yes, use a 'while' or 'for' statement.

Actually, looking at your code, I think you can simply remove the goto and its target label. It does nothing, as it is nested in loop().

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.