Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am sending a list of servo positions via the serial connection to the arduino in the following format


Which would be parsed as:

servoId : Position & servoId : Position & servoId : Position

How would I split these values up, and convert them to an integer?

share|improve this question
up vote 32 down vote accepted

Contrarily to other answers, I'd rather stay away from String for the following reasons:

  • dynamic memory usage (that may quickly lead to heap fragmentation and memory exhaustion)
  • quite slow due to construction/destruction/assignment operators

In an embedded environment like Arduino (even for a Mega that has more SRAM), I'd rather use standard C functions:

  • strchr(): search for a character in a C string (i.e. char *)
  • strtok(): splits a C string into substrings, based on a separator character
  • atoi(): converts a C string to an int

That would lead to the following code sample:

// Calculate based on max input size expected for one command
#define INPUT_SIZE 30

// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;

// Read each command pair 
char* command = strtok(input, "&");
while (command != 0)
    // Split the command in two values
    char* separator = strchr(command, ':');
    if (separator != 0)
        // Actually split the string in 2: replace ':' with 0
        *separator = 0;
        int servoId = atoi(command);
        int position = atoi(separator);

        // Do something with servoId and position
    // Find the next command in input string
    command = strtok(0, "&");

The advantage here is that no dynamic memory allocation takes place; you can even declare input as a local variable inside a function that would read the commands and execute them; once the function is returned the size occupied by input (in the stack) is recovered.

share|improve this answer
Hadn't thought of the memory issue. this is great. – ValrikRobot Mar 31 '14 at 18:39
Excellent. My answer was very "arduino" based and using typical arduino SDK functions which a novel user could be more used to, but this answer is what should be done for "production" systems. In general, try to escape from dynamic memory allocation in embedded systems. – drodri Apr 1 '14 at 9:22

This function can be used to seperate a string into pieces based on what the separating character is.

String xval = getValue(myString, ':', 0);
String yval = getValue(myString, ':', 1);

Serial.println("Y:" + yval);
Serial.print("X:" + xval);

Convert String to int

int xvalue = stringToNumber(xval);
int yvalue = stringToNumber(yval);

This Chunk of code takes a string and separates it based on a given character and returns The item between the separating character

String getValue(String data, char separator, int index)
 int found = 0;
  int strIndex[] = {
0, -1  };
  int maxIndex = data.length()-1;
  for(int i=0; i<=maxIndex && found<=index; i++){
  if(data.charAt(i)==separator || i==maxIndex){
  strIndex[0] = strIndex[1]+1;
  strIndex[1] = (i == maxIndex) ? i+1 : i;
  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
share|improve this answer
thats a beautiful perfect answer! thanks a lot ! – Curnelious Nov 26 '14 at 9:27

You could do something like the following, but please take into account several things:

If you use readStringUntil(), it will wait until it receives the caracter or timeouts. Thus, with your current string, the last position will last a little longer, as it as to wait. You can add a trailing & to avoid this timout. You can easily check this behavior in your monitor, try to send the string with and without the extra & and you will see such timeout delay.

You actually do not need the servo index, you can just send your string of positions, and get the servo index by the value position in the string, something like: "90&80&180&". If you use the servo index, maybe you want to check it (convert to Int, and then match the loop index i) to ensure that nothing went wrong with your message.

You have to check that the returning string from readStringUntil is not empty. If the function timeouts, you didnt receive enough data, and thus any attempt to extract your Int values will produce strange results.

void setup() {

void loop() {
    for(int i=1;i<=3;i++){
        String servo = Serial.readStringUntil(':');
            //here you could check the servo number
            String pos = Serial.readStringUntil('&');
            int int_pos=pos.toInt();
share|improve this answer
This seems like a very good solution thank you. The example clears it up perfectly – ValrikRobot Mar 31 '14 at 8:01
What if we had an undefined number of servo inputs? in my example there was 3. But what if sometimes it was more, or less. Can you offer any suggestion for handling such a scenario – ValrikRobot Mar 31 '14 at 8:30
Sure: There are two possibilities. 1. Send first the number of servos: 3:val1&val2&val3&, read such number prior to starting the loop. 2. Use a different terminator to indicate you have no more servos, loop until you find it: val1&val2&val3&#, for example. – drodri Mar 31 '14 at 8:34
of course. Seems so obvious now thank you – ValrikRobot Mar 31 '14 at 9:16
Glad this solution helped you, @ValrikRobot, could you please validate the answer if it was useful? – drodri Mar 31 '14 at 10:14

You can use Stream.readStringUntil(terminator) passing a different terminator for each part.

On each part you then call String.toInt

share|improve this answer

Se example at:

// spliting a string and return the part nr index split by separator
String getStringPartByNr(String data, char separator, int index) {
    int stringData = 0;        //variable to count data part nr 
    String dataPart = "";      //variable to hole the return text

    for(int i = 0; i<data.length()-1; i++) {    //Walk through the text one letter at a time

        if(data[i]==separator) {
            //Count the number of times separator character appears in the text

        }else if(stringData==index) {
            //get the text when separator is the rignt one

        }else if(stringData>index) {
            //return text and stop if the next separator appears - to save CPU-time
            return dataPart;


    //return text if this is the last part
    return dataPart;
share|improve this answer
String getValue(String data, char separator, int index)
    int maxIndex = data.length() - 1;
    int j = 0;
    String chunkVal = "";

    for (int i = 0; i <= maxIndex && j <= index; i++)

        if (data[i] == separator)

            if (j > index)
                return chunkVal;

            chunkVal = "";
        else if ((i == maxIndex) && (j < index)) {
            chunkVal = "";
            return chunkVal;
share|improve this answer

Simplest solution is to use sscanf().

  int id1, id2, id3;
  int pos1, pos2, pos3;
  char* buf = "1:90&2:80&3:180";
  int n = sscanf(buf, "%d:%d&%d:%d&%d:%d", &id1, &pos1, &id2, &pos2, &id3, &pos3);
  Serial.print(F(", pos1="));
  Serial.print(F(", pos2="));
  Serial.print(F(", pos3="));

This give the following output:

id1=1, pos1=90
id2=2, pos2=80
id3=3, pos3=180


share|improve this answer
It is not working for any idea why? I get the following error: invalid conversion from 'int' to 'char*' [-fpermissive] – Alvaro Apr 23 at 12:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.