Separate from Serial for digitalWrite()

This is my current code (Arduino Mega 2560):

#define p1 2
#define p2 3

void setup() {
 Serial.begin(9600);
 pinMode(p1, OUTPUT);
 pinMode(p2, OUTPUT);
 Serial.println("ARDUINO : CONNECTED");
}

void loop() {
 if (Serial.available()) {
  String state = Serial.readString();
  
  if (state.startsWith("LED1ON")) {
    digitalWrite(p1, HIGH);
  }
  if (state.startsWith("LED1OFF")) {
    digitalWrite(p1, LOW);
  }
  if (state.startsWith("LED2ON")) {
    digitalWrite(p2, HIGH);
  }
  if (state.startsWith("LED2OFF")) {
    digitalWrite(p2, HIGH);
  }
  // ... and next condition LED
 }
}

how can i do for multiple dynamic input serial use seperator(";") ? like : LED1ON;LED2OFF;LED3OFF;...

expacted: one time command (LED1ON;LED2OFF;...) many condition (led turn on and led 2 turn off and etc)

please, tks

I would suggest to study Serial Input Basics to handle this

1 Like

Welcome to the forum.

Which Arduino board do you use ? (since you use pin 1).

We don't use the Serial.readString(). Its behaviour is not well defined.
We even try to avoid the String class on a Arduino Uno.

I would like a good description of the commands that can be entered. This is where most beginners fail, so I hope that you can do this. Here are some notes to think about:

  • You use the ';' as seperator, but there is no ';' after the last command ?
  • What is at the end of a line ? A CarriageReturn or LineFeed or both or neither ? Suppose that you upload a file with commands, what is at the end of the lines in that case ?
  • Should there be a timeout ? Suppose that you have two commands "BLINK1" and "BLINK100". If you receive "BLINK1", how long do you wait for "00" that might or might not come ?
  • Do you want to add a parameter in the future ? For example blinking a led at pin 5 with 2 blinks per second: "BLINK:5:2;" or send a floating point number: "OFFSET:3.1415;". How about sending text ?
  • Do you want to request data in the future ? For example requesting the version of the code: "GETVERSION;" and the Arduino will reply with "2.01.02;".

Use a new line as separator - it solve your problem

In the setup, it is missing to initialize the serial:

"Serial.begin(XXXX); // XXXX = Serial speed. 9600, 115200,... etc...

1 Like

The command can still be parsed using strtok() function:

Sketch: (select Newline option in the Line ending box of Serial Monitor)

char myMsg[20];

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);  //LED1
  pinMode(4, OUTPUT);  //LED2
}

void loop()
{
  byte n = Serial.available();
  if (n != 0)

  {
    byte m = Serial.readBytesUntil('\n', myMsg, 20);
    myMsg[m] = '\0' ; //null charcater
    Serial.println(myMsg);
    char *token;
    token = strtok(myMsg, ";");
    if (strcmp(token, "LED1ON") == 0)
    {
      digitalWrite(13, HIGH);   //LED1 is ON, ;LED2OFF
    }
    token = strtok(NULL, ";");
    if (strcmp(token, "LED2OFF") == 0)
    {
      digitalWrite(4, LOW);   //LED2 is OFF
    }
  }
}
1 Like

The Serial input basics have a demo-code in post 2

where a start-marker and an end-marker is used to separate commands from each other.

So if you can change the character-sequence that you are sending to the arduino to look like this

<LED1ON><LED2OFF><LED3BLINK><LED4ON>

where the "<" acts as the startmarker and the "<" acts as the endmarker,
each time the end-marker is received the flag newData becomes true and you can process this one command. And then continue with reading from the serial inputbuffer.

Depending on how much characters you want to send at once you must iterate through your whole code very fast. Otherways if the number of sended characters exceeds the number the serial receive-buffer can hold some characters will get lost.

best regards Stefan

Try this code:

(simulated at: " https://wokwi.com/projects/371142682088743937

#define p1 2
#define p2 3

void setup() {
  Serial.begin(9600);
  pinMode(p1, OUTPUT);
  pinMode(p2, OUTPUT);
  Serial.println("ARDUINO : CONNECTED");
}

void loop() {
  if (Serial.available()) {
    String state = Serial.readString();
    //Serial.println(state);   // For debug
    state.toUpperCase();
    int msgLgt = state.length();
    //Serial.println(msgLgt); // For debug
    int semiC = state.indexOf(";");
    String firstArg = state.substring(0, semiC);
    //Serial.println(firstArg);   // For debug
    String ScndArg = state.substring(semiC + 1, msgLgt-1);
    ///Serial.println(ScndArg);   // For debug

    if (firstArg == "LED1ON") {
      digitalWrite(p1, HIGH);
    }
    if (firstArg == "LED1OFF") {
      digitalWrite(p1, LOW);
    }
    if (ScndArg == "LED2ON") {
      digitalWrite(p2, HIGH);
    }
    if (ScndArg == "LED2OFF") {
      digitalWrite(p2, LOW);
    }
    // ... and next condition LED
  }
}

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