Dividing UART message into two variables

In my program I send mesage to Arduino by UART in format like that "xxx;xxx", so two informations separeted by semicolon . I want Arduino to read this message and put first part (before " ; ") to one variable and then read next part to end of line and put it to another variable.

I was trying to do it like that:

var1 = Serial.readStringUntil(";");

var2 = Serial.readStringUntil('\n');

But Arduino was loosing second part and var2 always ends empty.
I will appriciate your help and I'm looking forward to see how to do it, because I cannot find solution (for relativly easy question, I think) anywhere.

Click " < code >" and post your code .

This is something i got of of this forum a while ago. A better way to handle serial input.
Kind of what you are asking about but place your serial input between <> , so < is a begin marker and > is an end marker

The code is:

char mystring[25]="";
void setup() {
  Serial.begin(115200);
  Serial.println("start");
}

void loop() {
  
      if (Serial.available() > 0 ){    //something in serial port
         mychar = Serial.read();   
          if (mychar == '<') {       //if it is a < we enter a loop that will read valid characters
            numchars=0;
            while( (mychar=Serial.read() ) != '>' {
               mystring[numchars] = mychar ;
              numchars++;
          }
            Serial.println(mystring);     //mystring contains the string
         }//if
         
      }//Serial available
  
} //loop

The readStringUntil() function is blocking and it uses the String class. Are you aware of the problems that the String class can cause with memory fragmentation?
The evils of Arduino Strings

The serial input basics tutorial shows good ways to handle serial data.

Example 5 of the tutorial shows how to split values out delimited data with the strtok() function.

Hi @drakevimes ,
Welcome to the forum!

something to try..

char buff[80];

char* var1;
char* var2;
int recvCount = 0;
bool bufferReady = false;

void setup() {
  Serial.begin(115200);
  Serial.println("Ready");
}

void loop() {
  if (Serial.available())
  { char achar = Serial.read();
    if (achar != 10) {
      buff[recvCount] = achar;
      recvCount++;
      if (recvCount >= sizeof(buff)) recvCount = 0;
    } else {
      bufferReady = true;
      recvCount = 0;
    }
  }

  if (bufferReady) {
    SplitBuffer(buff);
    bufferReady = false;
    Serial.println(var1);
    Serial.println(var2);
  }

}

void SplitBuffer(char* abuff) {
  int splits = 0;
  for ( char* piece = strtok( abuff, ";");
        piece != nullptr;
        piece = strtok( nullptr, ";")) {
    if (splits == 0) {
      var1 = piece;
      splits++;
    } else if (splits == 1) {
      var2 = piece;
      splits++;
    }
  }
}

good luck.. ~q

Thanks for all your help, it inspired me and I finally find solution. It's a bit diffrent from all code you have send and it use other methods than complex ways of reading message character after character.
Instead of dividing mesage during reciving it, I save is as one string and then use substring() function, that separate it into two part of specific lenght. That means, I need to know exact lenght of variables beforhand, but it's not a problem in my program.
Here's the code:

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {

String speed = " ";       //declaration of variables
String direction = "";
String recivedData = ""; 

/* my message is in format "D;SSS" where:
 D is one letter for direction, 
 then is pause, which can be any character, but I chose semicolon
 SSS is one to three digit wchich means speed */

while (Serial.available() == 0) { }       //waiting for data
recivedData = Serial.readStringUntil('\n');     //saving all as one string

direction = recivedData.substring(0, 1); //substring cut part with first character, so before ";"
speed = recivedData.substring(2, 5); //cutting 3 characters behind ";" 

Serial.println("speed " + speed);  //printing data
Serial.println("direction "+direction);
/* now, I can transform string type data into other types and work with them */
}

I know it's not best solution and it work only in very specific situation, but I chose it as least complicated. I wanted to save Serial.readStringUntil('\n'), because its very easy way of getting whole message. It return string type data, which I prefer, because it's easy in use and easy in tranfsform to int data, which I will mainly use.

One day I will sat and fully understand char * type data and those more universal solutions that you send to me.
Again, thank for help and I think this thread can be closed (shall I do it, or moderation does?)

I can understand that you had difficulties to understand the posted code.
The posted code-examples have no explanations. Neither comments nor links to introductional tutorials.

Using Strings will become complicated of you do an often repeated receiving of Strings.

The often repeated receiving, assigning, modifying of Strings results in:
all available memory will be used and then going on receiving, assigning, modifying Strings will result in corrupting your variables which will be very very hard to find.

Your code will start to act really strange which is no wonder if variables change their value because of memory-corruption.

There is a safe to use alternative:
The SafeString-library. The SafeString-library can be installed with the library-manager of the arduino-IDE.

The SafeString-library offers almost the same comfort as Strings but the name is program:
SafeStrings are safe to use and will never cause memory-corruption

If you have any questions about the examples which were provided with the library simply contact the author of the SafeString-library
or ask here in the forum.

best regards Stefan

Here is your code adapted to use SafeStrings.

There are some differencies.
With Strings you assign the result this way

speed = recivedData.substring(2, 5)

With SafeStrings
the SafeString that gets assigned the substring is the first parameter

  recivedData.substring(speed, 2, 5); //cutting 3 characters behind ";"

Similar for transforming into integers

  speed.toInt(mySpeed); // variable "mySpeed" is the integer-variable

It is done this way because the SafeStrings functions deliver a result if an operation was successfull or not.
And SafeStrings have even inbuild-debug-capabilities that print error-messages to the serial monitor if you activate the debug-printing.

You will have to add error-checking for invalid input like
"99;-129"
"abc;3857" etc.

I have added serial printing that will make it easier to narrow down bugs
because it shows what you really have received

So here is the code

#include <SafeString.h>

//cSF(nameOfVariable, length);
cSF(direction, 8);
cSF(speed, 8);
cSF(recivedData, 16); //cSF = short for createSafeString

int myDirection;
int mySpeed;


void setup() {
  Serial.begin(9600);
  Serial.println("Type D;SSS");
  Serial.println("example Type 1;243");
}

void loop() {

  /* my message is in format "D;SSS" where:
    D is one letter for direction,
    then is pause, which can be any character, but I chose semicolon
    SSS is one to three digit wchich means speed */

  while (Serial.available() == 0) { }       //waiting for data
  recivedData = Serial.readStringUntil('\n').c_str();     //saving all as one string
  Serial.print("received character-sequence #");
  Serial.print(recivedData);
  Serial.println("#");
  Serial.println();
  
  //direction = recivedData.substring(0, 1); //substring cut part with first character, so before ";"
  //speed = recivedData.substring(2, 5); //cutting 3 characters behind ";"
  recivedData.substring(direction, 0, 1); //substring cut part with first character, so before ";"
  recivedData.substring(speed, 2, 5); //cutting 3 characters behind ";"

  Serial.print("direction as string #");
  Serial.print(direction);
  Serial.println("#");
  
  Serial.print("speed as string #");
  Serial.print(speed);  //printing data
  Serial.println("#");
  Serial.println();

  /* now, I can transform string type data into other types and work with them */
  direction.toInt(myDirection);
  speed.toInt(mySpeed);

  Serial.print("direction as int:");
  Serial.print(myDirection);
  Serial.println(":");

  Serial.print("speed as int:");
  Serial.print(mySpeed);  //printing data
  Serial.println(":");
}

best regards Stefan