assigning variables to colon separated strings

Hi,

I have a colon separated string coming in over a radio for example '01:2:3:4:5:67'.

How could I assign each part of the string to a variable?

For example:

char id;
char type;
char volt;
char current;
char humidity;
char temp;

id = 01
type = 2

Thanks

atoi() or similar function, you may need strtok() depending on how you do it.

int val;
char str[20];

strcpy(str, "98993489");
val = atoi(str);
printf("String value = %s, Int value = %d\n", str, val);

Arlove:
int val;
char str[20];

strcpy(str, "98993489");
val = atoi(str);
printf("String value = %s, Int value = %d\n", str, val);

98993489 won't fit in an int type.

then float :slight_smile:

Hi,

Thanks, could you give an example using '01:2:3:4:5:67' ? Can atoi parse on a colon?

Where is assigns

id = 01
message num = 2
voltage = 3
current = 4
humidity = 5
Temp = 67

So then when I do for example Serial.println(voltage) it prints '3'.

Kind regards

Thanks, could you give an example using '01:2:3:4:5:67' ? Can atoi parse on a colon?

The atoi() function does not parse anything. The strtok() function does the parsing. The atoi() function converts the token to an int, which may, or may not, be appropriate. Why are id, type, volt, etc. declared as char variables?

Arlove:
then float :slight_smile:

…and risk truncation errors? I think not.

Thanks for all your replies.

I actually got it kind of working. However, I am stuck on converting a substring to a float. For example the variable c below is only displayed as 4 instead of 4.5.

Any ideas? .toInt() is not valid on substring().

Thanks

String input = "12:3:4.5:6";
int a, b, d;
float c;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  for (int i = 0; i < input.length(); i++) {
  if (input.substring(i, i+1) == ":") {
    a = input.substring(0, i).toInt();
    b = input.substring(i+1).toInt();
    c = input.substring(i+2).toInt();
    d = input.substring(i+3).toInt();
  
    break;
  }
}
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(a);
  Serial.println(b);
  Serial.println(c);
  Serial.println(d);


}

However, I am stuck on converting a substring to a float.

Do you really expect toInt() to return a float? Would you then expect toFloat() to return a pineapple?

Have a look at the parse example in serial input basics. It uses a comma as a separator but that is easily changed to a colon.

...R

Oh, great. You suddenly change the example so it needs to read a float. Well, there is atof().

Stay clear of the String class on the Arduino platform. It is a known resource hog.

below is some serial parsing code that seems similar to your data packet format. You use a colon to separate the data in the packet, do you have an end of packet marker?

//zoomkat 11-12-13 String capture and parsing  
//from serial port input (via serial monitor)
//and print result out serial port
//copy test strings and use ctrl/v to paste in
//serial monitor if desired
// * is used as the data string delimiter
// , is used to delimit individual data 

String readString; //main captured String 
String angle; //data String
String fuel;
String speed1;
String altidude;

int ind1; // , locations
int ind2;
int ind3;
int ind4;
 
void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 11-12-13"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like 90,low,15.6,125*
  //or 130,hi,7.2,389*

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == '*') {
      //do stuff
      
      Serial.println();
      Serial.print("captured String is : "); 
      Serial.println(readString); //prints string to serial port out
      
      ind1 = readString.indexOf(',');  //finds location of first ,
      angle = readString.substring(0, ind1);   //captures first data String
      ind2 = readString.indexOf(',', ind1+1 );   //finds location of second ,
      fuel = readString.substring(ind1+1, ind2+1);   //captures second data String
      ind3 = readString.indexOf(',', ind2+1 );
      speed1 = readString.substring(ind2+1, ind3+1);
      ind4 = readString.indexOf(',', ind3+1 );
      altidude = readString.substring(ind3+1); //captures remain part of data after last ,

      Serial.print("angle = ");
      Serial.println(angle); 
      Serial.print("fuel = ");
      Serial.println(fuel);
      Serial.print("speed = ");
      Serial.println(speed1);
      Serial.print("altidude = ");
      Serial.println(altidude);
      Serial.println();
      Serial.println();
      
      readString=""; //clears variable for new input
      angle="";
      fuel="";
      speed1="";
      altidude="";
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Some very similar code to Zoomkat’s, consuming less RAM, less program memory, and avoiding the use of Strings entirely.

const int MAX_LEN = 80;
const char lineEnding = '\n'; // whatever marks the end of your input.
char inputSentence [MAX_LEN + 1];
int inputIndex;
bool newInput;

const byte MAX_TOKENS = 4;
const char* delimiters = ", "; // whatever characters delimit your input string
char* tokens [MAX_TOKENS + 1];
enum indexName {angle, fuel, speed, altitude};
#define PRINT_ITEM(x) printItem (x, #x)

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

void loop ()
{
 if (newInput && strlen (inputSentence))
 {
   int tokenIndex = 0;
   Serial.println (inputSentence); // tell 'em what you've got
   tokens [tokenIndex] = strtok (inputSentence, delimiters);
   while ((tokenIndex < MAX_TOKENS - 1) && tokens [tokenIndex])
   {
     tokenIndex++;
     tokens [tokenIndex] = strtok (NULL, delimiters);
   }
   
   PRINT_ITEM (angle);
   PRINT_ITEM (fuel);
   PRINT_ITEM (speed);
   PRINT_ITEM (altitude);

   // reset things for the next lot.
   newInput = false;
   inputIndex = 0;
   inputSentence [0] = '\0';
 }
}

void serialEvent ()  // build the input string.
{
 while (Serial.available() )
 {
   char readChar = Serial.read ();
   if (readChar == lineEnding)
   {
     newInput = true;
   }
   else
   {
     if (inputIndex < MAX_LEN)
     {
       inputSentence [inputIndex++] = readChar;
       inputSentence [inputIndex] = '\0';
     }
   }
 }
}

void printItem (int index, char* name)
{
 Serial.print (name);
 Serial.print (F(" "));
 Serial.println (tokens [index]); 
}