I have been playing around with programming for arduino but today i've come across a problem that i can't solve with my very limited C knowledge. Here's how it goes. I'm creating a pc application that sends serial input to the arduino (deviceID, command, commandparameters). This arduino will transmit that command over RF to other arduino's. depending on the deviceID the correct arduino will perform the command.

To be able to determine the deviceID i want to split that string on the ",". this is my problem, i know how to do this easily in java (even by not using the standard split function), however in C it's a totally different story.

Can any of you guys tell me how to get this working?

thanks

    /*
      Serial Event example

     When new serial data arrives, this sketch adds it to a String.
     When a newline is received, the loop prints the string and 
     clears it.

     A good test for this is to try it with a GPS receiver 
     that sends out NMEA 0183 sentences. 

     Created 9 May 2011
     by Tom Igoe

     This example code is in the public domain.

     http://www.arduino.cc/en/Tutorial/SerialEvent

     */

    String inputString;         // a string to hold incoming data
    boolean stringComplete = false;  // whether the string is complete
    String[] receivedData;

    void setup() {
      // initialize serial:
      Serial.begin(9600);
      // reserve 200 bytes for the inputString:
      inputString.reserve(200);
    }

    void loop() {
      // print the string when a newline arrives:
      if (stringComplete) {
        Serial.println(inputString); 
        // clear the string:
        inputString = "";
        stringComplete = false;
      }
    }

    /*
      SerialEvent occurs whenever a new data comes in the
     hardware serial RX.  This routine is run between each
     time loop() runs, so using delay inside loop can delay
     response.  Multiple bytes of data may be available.
     */
    void serialEvent() {
      while (Serial.available()) {
        // get the new byte:
        char inChar = (char)Serial.read(); 
        if (inChar == '\n') {
          stringComplete = true;
        } 
        // add it to the inputString:
        if(stringComplete == false) {
          inputString += inChar;
        }
        // if the incoming character is a newline, set a flag
        // so the main loop can do something about it:
      }
    }

    String[] splitCommand(String text, char splitChar) {
      int splitCount = countSplitCharacters(text, splitChar);
      String returnValue[splitCount];
      int index = -1;
      int index2;

      for(int i = 0; i < splitCount - 1; i++) {
        index = text.indexOf(splitChar, index + 1);
        index2 = text.indexOf(splitChar, index + 1);

        if(index2 < 0) index2 = text.length() - 1;
        returnValue[i] = text.substring(index, index2);
      }

      return returnValue;
    }

    int countSplitCharacters(String text, char splitChar) {
     int returnValue = 0;
     int index = -1;

     while (index > -1) {
       index = text.indexOf(splitChar, index + 1);

       if(index > -1) returnValue+=1;
     }

     return returnValue;
    } 

I have decided I'm going to use the strtok function. I'm running into another problem now.

SerialEvent.cpp: In function 'void splitCommand(String, char)':

SerialEvent:68: error: cannot convert 'String' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'

SerialEvent:68: error: 'null' was not declared in this scope

    String inputString;         // a string to hold incoming data

    void splitCommand(String text, char splitChar) {
    String temp;
    int index = -1;
    int index2;

    for(temp = strtok(text, splitChar); temp; temp = strtok(null, splitChar)) {
      Serial.println(temp);
    }

    for(int i = 0; i < 3; i++) {
      Serial.println(command[i]);
    }
}
share|improve this question
Look at the strtok() function. – Kerrek SB Jan 30 '12 at 23:26
feedback

3 Answers

For dynamic allocation of memory, you will need to use malloc, ie:

String returnvalue[splitcount];
for(int i=0; i< splitcount; i++)
{
    String returnvalue[i] = malloc(maxsizeofstring * sizeof(char));
}

You will also need the maximum string length.

share|improve this answer
1  
You don't necessarily need malloc(). If the string is not going to change in between the split operation and the data transmission, it's perfectly safe to keep a set of pointers to various positions in the original string. It's also faster, uses less memory, and leaves fewer potential memory leaks. – japreiss Jan 31 '12 at 0:10
Yes, that could work, you would just have to keep manual track of the length/end of each string to avoid overlapping, as there would not be a '\0' termination character on any but the last one. – 3Pi Jan 31 '12 at 0:26
Good point. Guess it might not be worth it. – japreiss Jan 31 '12 at 0:48
feedback

The C way to split a string based on a delimiter is to use strtok (or strtok_r). See also this question.

share|improve this answer
feedback

I think your idea is a good start point. Here is a code that i use (to parse HTTP GET REST requests with an Ethernet shield).

The idea is to use a while loop and lastIndexOf of and store the strings into an array (but your could do something else).

"request" is the string you want to parse (for me it was called request because.. it was).

    int goOn = 1;
    int count = -1;
    int pos1;
    int pos2 = request.length();

    while( goOn == 1 ) {
        pos1 = request.lastIndexOf("/", pos2);
        pos2 = request.lastIndexOf("/", pos1 - 1);

        if( pos2 <= 0 ) goOn = 0;

        String tmp = request.substring(pos2 + 1, pos1);

        count++;
        params[count] = tmp;

        // Serial.println( params[count] );

        if( goOn != 1) break;
    }
    // At the end you can know how many items the array will have: count + 1 !

I have used this code successfully, but i thing their is an encoding problem when i try to print params[x]... i'm alos a beginner so i don't master chars vs string...

Hope it helps.

share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

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.