Arduino (C language) parsing a delimited string (serial input)

Arduino (C language) parsing a delimited string (serial input)

Did not find the answer here: /

I want to send to arduino via a serial interface (Serial.read ()) a simple string of three numbers separated by a comma. These three numbers can be in the range 0-255.

Eg. 255,255,255 0,0,0 1,20,100 90,200,3

What I need to do is parse this string sent to arduino into three integers (say r, g and b).

So when I send 100.50.30 arduino will translate it to

 int r = 100 int g = 50 int b = 30 

I tried a lot of codes, but none of them worked. The main problem is to translate a string (string of characters) into an integer. I realized that there might be strtok_r for the purpose of the delimiter, but that's about it.

Thanks for any suggestions :)

+10
c string parsing delimiter arduino
source share
8 answers

To answer your question, String objects are very powerful, and they can do exactly what you ask. If you restrict your parsing rules directly from the input, your code becomes less flexible, less reusable, and slightly confusing.

Strings have an indexOf () method that allows you to search for an index in a String character array of a specific character. If the character is not found, the method should return -1. The second parameter can be added to the function call to indicate the starting point for the search. In your case, since your delimiters are commas, you should call:

 int commaIndex = myString.indexOf(','); // Search for the next comma just after the first int secondCommaIndex = myString.indexOf(',', commaIndex + 1); 

You can then use this index to create a substring using the substring () method of the String class. This returns a new String, starting at a specific starting index, and ending immediately before the second index (or the end of the file if none are specified). So you would print something similar to:

 String firstValue = myString.substring(0, commaIndex); String secondValue = myString.substring(commaIndex + 1, secondCommaIndex); String thirdValue = myString.substring(secondCommaIndex + 1); // To the end of the string 

Finally, integer values ​​can be obtained using the undocumented method of the String class, toInt ():

 int r = firstValue.toInt(); int g = secondValue.toInt(); int b = thirdValue.toInt(); 

More information about the String object and its various methods can be found in the Arduino documentation .

+20
source share

Use sscanf ;

 const char *str = "1,20,100"; // assume this string is result read from serial int r, g, b; if (sscanf(str, "%d,%d,%d", &r, &g, &b) == 3) { // do something with r, g, b } 

Use my code here if you want to parse a line stream ex: 255,255,255 0,0,0 1,20,100 90,200,3 Analysis function for comma delimited line

+6
source share

I think you want to do something like this to read data:

 String serialDataIn; String data[3]; int counter; int inbyte; void setup(){ Serial.begin(9600); counter = 0; serialDataIn = String(""); } void loop() { if(serial.available){ inbyte = Serial.read(); if(inbyte >= '0' & inbyte <= '9') serialDataIn += inbyte; if (inbyte == ','){ // Handle delimiter data[counter] = String(serialDataIn); serialDataIn = String(""); counter = counter + 1; } if(inbyte == '\r'){ // end of line handle end of line a do something with data } } } 

Then use atoi () to convert the data to integers and use them.

+1
source share

It's great!

The last comment about "thirdvalue = 0" is true from the code provided in the @dsnettleton top answer. However, instead of using "lastIndexOf (',');", the code should simply add "+1" to "secondCommaIndex", as @dsnettleton did correctly for commaIndex + 1 (missing +1, probably just a typo from the guy).

Here is the updated code snippet

 int commaIndex = myString.indexOf(','); int secondCommaIndex = myString.indexOf(',', commaIndex+1); String firstValue = myString.substring(0, commaIndex); String secondValue = myString.substring(commaIndex+1, secondCommaIndex); String thirdValue = myString.substring(secondCommaIndex+1); //To the end of the string 

Example)

For myString = "1,2,3"

  • commaIndex = 1 (search by index 0, spot taken by character 1, to the position of the first comma)
  • secondCommaIndex = 3 (search from index 2, place taken by character 2, to the place of the next comma)
  • firstValue reads from index 0-1 = "1"
  • secondValue reads from index 2-3 = "2"
  • thirdvalue reads from index 4-4 (last index spot of a row) = "3"

Note. Do not confuse INDEX with LENGTH string. The length of the string is 5. Since String indexOf is counted starting at 0, the last index is 4.

Reason why just

 String thirdValue = myString.substring(secondCommaIndex); 

returns 0 when .toInt () is used - this is because thirdValue = ", 3", and not "3", which attaches toInt ().

ps. I’m sorry to write all the instructions, but as a fur eng, even sometimes I would like someone to keep silent about the code for me, especially consult for the last 7 years. Stay tuned for amazing posting! Helps people like me a lot!

+1
source share

The simplest, I think, uses parseInt() to accomplish this task:

 void loop(){ if (Serial.available() > 0){ int r = Serial.parseInt(); int g = Serial.parseInt(); int b = Serial.parseInt(); } } 

does the trick.

+1
source share

For n number separated by a string

 int end; while((end=str.indexOf(","))!=-1){ String num = str.substring(0,end); str= asc.substring(end+1,str.length()); Serial.println(num); } 
0
source share

@cstrutton is a great suggestion for using 'indexOf'. it saved me a lot of time for my project. However, one minor pointer,

I noticed that the third value was not displayed (returned as ZERO). After playing with it a bit and going through the document at http://arduino.cc/en/Tutorial/StringIndexOf I realized I can use lastIndexOf for the last value.

Here are two lines of modifications that provide the correct third value.

 int lastCommaIndex = myString.lastIndexOf(','); String thirdValue = myString.substring(lastCommaIndex+1); // To the end of the string 
-2
source share
  String myString = "dfsdfgsafhffgsdvbsdvdsvsdvsdsdfdfsdsff|date|recipt|weight|time|date|"; // the setup routine runs once when you press reset: void setup() { Serial.begin(9600); } // the loop routine runs over and over again forever: void loop() { int Index1 = myString.indexOf('|'); int Index2 = myString.indexOf('|', Index1+1); int Index3 = myString.indexOf('|', Index2+1); int Index4 = myString.indexOf('|', Index3+1); int Index5 = myString.indexOf('|', Index4+1); int Index6 = myString.indexOf('|', Index5+1); String secondValue = myString.substring(Index1+1, Index2); String thirdValue = myString.substring(Index2+1, Index3); String fourthValue = myString.substring(Index3+1, Index4); String fifthValue = myString.substring(Index4+1, Index5); String firstValue = myString.substring(Index5+1, Index6); //Serial.println(Index1); // Serial.println(secondValue); Serial.println(thirdValue); Serial.println(fourthValue); Serial.println(fifthValue); Serial.println(firstValue); delay(14000); } 
-3
source share

All Articles