Separate multipe values with letters - But how to read them value by value?

Hi guys,

little question, but im getting angry with it.

I have send some values over XBEEs with a serial connection. The values are fomated like

X:163
Y:178
X:178
X:183
Y:201
...

how can i seperate them and using the letters for the separation?

Best

What form is the data held in on the receiving Arduino, char array or a String ? If the former, is it properly terminated with a null at the end ?

If the second value is in that range, 150 ~ 210 then I would use for example:

!Xa

Where 'a' is the number -'something' (ASCII value of double quotes " for example). So:

X:150 ->       !X"
X:151 ->       !X#
X:152 ->       !X$
...

And if you receive "!" then you will know the next byte is your letter, and the next one is the number (no extra tricky things needed)

As you receive characters from the serial port, store them in a char array and null terminate it. Before you store, check for 'X' or 'Y'. if that's what you have, use the current first char in your array to tell you which value you've been accumulating. Then use atoi to parse the value associated with it using

val=atoi(&myArray[2]);

Store val in your X or X variable, whichever is appropriate
set your index variable for the array back to zero.

Yet another option (assuming your reading the data using Serial) is the parseInt function.

Some excerpt code...

#define CMD_TRIGGER 't'
#define CMD_MASK 'm'


  while (Serial.available() > 0){                           // Serial available? Read it.
    unsigned int cmdData;
    byte cmdByte = Serial.read();                           // Read command
    if (cmdByte >= 'A' && cmdByte <= 'Z'){
      cmdByte |= 0X20;                                      // Convert to lower case
    }
    switch(cmdByte) {
      case CMD_TRIGGER:
      cmdData = Serial.parseInt();                          // Read value
      noInterrupts();
      triggerBits = (byte) cmdData;
      interrupts();
      break;
      case CMD_MASK:
      cmdData = Serial.parseInt();                          // Read value
      noInterrupts();
      triggerMask = (byte) cmdData;
      interrupts();
      break;
      default:
    }
  }

You would need to read the colon (:slight_smile: before using parseInt to get the number (or remove it from the transmission)

Thanks guys for all the replies! Sorry that i have to ask second time cause i didnt got it. I said it in another thread...i wanna learn but unfortunately im a newbee and sometimes it takes osme time to get the thing behind a operation :wink:

so i send some value here

  if ( old_JoyVarX != JoyVarX ) { Serial.print("X:"); Serial.println( JoyVarX ); }   
        old_JoyVarX = JoyVarX;       // left - right
                                  
    if ( old_JoyVarY != JoyVarY ) { Serial.print("Y:"); Serial.println( JoyVarY ); }    
        old_JoyVarY = JoyVarY;      // forward - backwards
         
    if ( old_JoyVarZ != JoyVarZ ) { Serial.print("Z:"); Serial.println( JoyVarZ ); }    
        old_JoyVarZ = JoyVarZ;        // twist
    
    if ( old_JoyVarHAT != JoyVarHAT ) { Serial.print("HAT:"); Serial.println( JoyVarHAT ); }   
        old_JoyVarHAT = JoyVarHAT;    //HAT Button

and receive them like this

X:163
Y:178
X:178
X:183
Y:201
...

I understand the method of Riva a bit but i dont get the line where i say "take everything after the letter and the :" is it the line with

   if (cmdByte >= 'A' && cmdByte <= 'Z'){
      cmdByte |= 0X20;

?

sunny greatings from berlin and theanks for all the answers!

    if (cmdByte >= 'A' && cmdByte <= 'Z'){
      cmdByte |= 0X20;                                      // Convert to lower case
    }

The comment says it all? I convert all letters (A-Z) to lower case (a-z) so I don't have to check for either version.

I understand the method of Riva a bit but i dont get the line where i say "take everything after the letter and the :" is it the line with

The code snippet I posted is expecting a letter followed by a number e.g. t100m123 would assign 100 to triggerBits and 123 to triggerMask. Your code was sending X:163 Y:178 so you would need to read the first character (X/Y) to determine where the following number gets stored but you would also need to read over the : else parseInt would not work.
If instead of Serial.print("Z:"); Serial.println( JoyVarZ ); } you did Serial.print("Z"); Serial.println( JoyVarZ ); } instead you will remove the colon that seems to serves no purpose here. You don't even need to split values across lines as the code would work just as well with X163Y178Z193 as with
X163
Y178
Z193

okay great, the line wrap was only to get not totally confussed :wink: so i understand everything with the Serial.print() stuff.

i still didnt got the thing with the converting to lower case. i mean i could also send the letter as lower case like

Serial.print('a');

Sorry that im a little bit confused, but i really try to get it :wink: And my biggest questions: In which line i say that everything after the letter is a value?

Given that you control what's being sent from the XBEE, you can rely on the X,Y,Z being upper case - there should be no need (in this situation) to worry about whether they are.

Does this help a little better, I have altered it to suit your data (apart from the colon) and remove the code to convert upper case to lower case as your won't need it with data fed from a program. I needed it because the data was typed by humans so could be mixed upper/lower case.

void setup(){
  Serial.begin(9600);
}

void loop(){
  int X,Y,Z = 0;
  while (Serial.available() > 0){       // Serial available? Read it.
    unsigned int cmdData;
    byte cmdByte = Serial.read();       // Read command
    switch(cmdByte) {
      case 'X':
      X = Serial.parseInt();            // Read X value
      break;
      case 'Y':
      Y = Serial.parseInt();            // Read Y value
      break;
      case 'Z':
      Z = Serial.parseInt();            // Read Z value
      break;
      default:
    }
  }
  Serial.print("X = ");
  Serial.print(X);
  Serial.print(", Y = ");
  Serial.print(Y);
  Serial.print(", Z = ");
  Serial.println(Z);
}

Serial.parseInt() will read serial bytes until a non number arrives and then convert what it's already got into an int.

Great,thanks. the info with Serial.parseInt() is perfect.
Guys, you are great! im so appreciate about all the help! thanks

sscanf is your friend :slight_smile:

qui ce la le ami mystique "sscanf"?

Read about the standard library function scanf() first:

http://www.cplusplus.com/reference/cstdio/scanf/

then read about sscanf(). It is not always your friend, however. Because it can do so much, it is often an H-bomb-to-kill-an-ant approach chewing up more memory than some simplier alternatives.

hähähähä...thanks i will do!

why is geek talk so great but girls are not appreciate about it :wink: