Go Down

Topic: Separate multipe values with letters - But how to read them value by value? (Read 852 times) previous topic - next topic

gnom

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

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


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

Best


UKHeliBob

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 ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

eried

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

Code: [Select]
!Xa

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

Code: [Select]
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)
My website: http://ried.cl

wildbill

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
Code: [Select]
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.

Riva

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

Some excerpt code...
Code: [Select]
#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 (:) before using parseInt to get the number (or remove it from the transmission)
http://forum.arduino.cc/index.php?action=unread;boards=5,67,10,11,66,12,15,17,21,22,23,24,25,29;ALL

gnom

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 ;-)

so i send some value here

Code: [Select]
  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

Quote
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

Code: [Select]
   if (cmdByte >= 'A' && cmdByte <= 'Z'){
      cmdByte |= 0X20;     


?

sunny greatings from berlin and theanks for all the answers!

Riva

Code: [Select]
    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.

Quote
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
http://forum.arduino.cc/index.php?action=unread;boards=5,67,10,11,66,12,15,17,21,22,23,24,25,29;ALL

gnom

okay great, the line wrap was only to get not totally confussed ;-) 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

Code: [Select]
Serial.print('a');

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

wildbill

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.

Riva

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.

Code: [Select]
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.
http://forum.arduino.cc/index.php?action=unread;boards=5,67,10,11,66,12,15,17,21,22,23,24,25,29;ALL

gnom

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

guix


gnom


econjack

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.

gnom

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

why is geek talk so great but girls are not appreciate about it ;-)

Go Up