Splitting a String

Introduction

There are times when a string is recieved, but rather than the entire string, just a piece of the string is desired. Unfortunately, there does not appear to be a simple way to handle strings in C++. Therefore, I have devised a way to split a string based on comma separation.

This way of splitting strings is rather crude and refinement for it will be worked on, but for immediate use, the current function is given with two examples of how it can be altered and used.

Coding

Splitting Strings - Two Characters

This code was used in a project that controlled a robot via computer. The computer sent data through an XBee to an Arduino that served as the brains. That Arduino would get the string from the computer, pick it apart and find the important information. That information was then relayed to an Arduino that controlled the robot's motors. The single character that was sent to the motor Arduino then told which direction to move the robot in.

//Brain Code

char string[25];
char id[2];
char direct[2];


int ii=0;

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial1.begin(9600);
  //Serial.println("Motor test!");
}

void loop() {
}

void serialEvent() {
  int i=0;
  if (Serial.available()) {
    delay(50);
    while(Serial.available()) {
      string[i++] = Serial.read();
    }
    string[i++]='\0';
    splitString(string);
    if (id[0] == 'M') {
      Serial1.print(direct[0]);
    }
  }
}

void splitString(char* chars) {
  char val1[15]={};
  char val2[15]={};
  
  int i=0;
  int cnt_id,cnt_val1,cnt_val2;

  //get identifier
  while(chars[i] != ',' && i<25) {
    i++;
    if (chars[i] == ',' || chars[i]=='\0') {
      for(int j=0;j<i;j++) {
        id[j] = chars[j];
        cnt_id=j;
      }
      id[cnt_id+1]='\0';
      //Serial.println(id);
    }
  }

  i++; //skips the comma
  
  while(chars[i] != '\0' && i<25) {
    i++;
    if (chars[i] == ',' || chars[i]=='\0') {
      for(int j=cnt_id+2;j<i;j++) {
        direct[j-(cnt_id+2)] = chars[j];
        cnt_val1=j-2;
      }
      direct[cnt_val1+1]='\0';
      //Serial.println(direct);
    }
  }
}

A question may arise of why even bother with this code? Why not directly send to the motors which direction to move? And in this case, yes, that would have been much simpler. However, this is one part of a much bigger project where more than just motor information will be sent, so the first character being sent in will indicate which part of the robot it pertains to.

Splitting Strings - Getting Floats

Often times, it may be necessary to send actual number values, whether that is a float or an integer, through serial. Therefore, there needs to be a way to recover that data. It can be sent as a byte, but floats and larger integers may not fit into a byte.

For example, in a project it was necessary to send a string like "L,1234.5678,2345.6789" through serial to an Arduino. This is intepretted as sending a Location to the Arduino with the following coordinates. This would involve both splitting up the string and turning the number values into floats.

Unfortunately, there are not very elegant ways to handle strings in C, so two functions had to be made by scratch to split the string. In this particular example, this was the only type of string that was going to be sent to the Arduino, so code was made to split this specific string, but it can be adapted to other means.

The following code shows how the string is split:

void splitString(char* chars, char* id, double &numX, double &numY) {
  char val1[15]={};
  char val2[15]={};
  
  int i=0;
  int cnt_id,cnt_val1,cnt_val2;
//get identifier while(chars[i] != ',' && i<25) { i++; if (chars[i] == ',' || chars[i]=='\0') { for(int j=0;j<i;j++) { id[j] = chars[j]; cnt_id=j; } id[cnt_id+1]='\0'; } }
i++; //skips the comma //get first float while(chars[i] != ',' && i<25) { i++; if (chars[i] == ',' || chars[i]=='\0') { for(int j=cnt_id+2;j<i;j++) { val1[j-(cnt_id+2)] = chars[j]; cnt_val1=j-2; } val1[cnt_val1+1]='\0'; CharToFloat(val1, numX, cnt_val1+1); } }
i++; //skips the comma
//get second float while(chars[i] != '\0' && i<25) { i++; if (chars[i] == ',' || chars[i]=='\0') { Serial.println(chars[i]); for(int j=cnt_id+cnt_val1+4;j<i;j++) { val2[j-(cnt_id+cnt_val1+4)] = chars[j]; cnt_val2=j; } val2[cnt_val2+1]='\0'; CharToFloat(val2, numY, cnt_val2+1); } } }

It may be noticed that in this case, a function CharToFloat is called. This function is explained in another tutorial. It is one method for turning character arrays into more precise floats.