Read serial data (RS232) and convert numbers of the string to integer

Hey,

I'm working on a new project. For getting my data I would like to read serial data given by a commercial measurement device. As far as I know I do have to use a MAX232 to change the +-12V-RS232-signal to a TTL-signal.

For reading the signal to an Arduino Uno I am very happy with the description at http://www.arduino.cc/en/Tutorial/SerialEvent

Here you can see an example of the data I am expecting:

0 22.04.16 13:19:26 0 xyz 100 % 7 xyz 38 %
0 22.04.16 13:19:27 0 xyz 100 % 5 xyz 45 %
0 22.04.16 13:19:28 0 xyz 100 % 7 xyz 38 %
0 22.04.16 13:19:29 0 xyz 100 % 10 xyz 32 %
0 22.04.16 13:19:30 0 xyz 100 % 9 xyz 34 %

Nevertheless I do have to find a specific number in each line for my analysis - I have marked these numbers bold in the table above. Do you see any possibility to find the number in the string (between "%" and "xyz")?
If I would get this string, I could convert it by "int()" and average or display the numbers.

Thank you very much for your help!

I would not use the String class or serial event to input the data. I would use the techniques from serial input basics to read and parse the data. Using the example that uses strtok you can break down the data and pull what you want out, use the atoi() function to turn string data to integers or atof() to get floats.

Thank you very much for this hint! I have tried to use the example for reading serial data, to convert the string to a char-array and to break the data afterwards:

String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int measurement_int = 0;

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

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    char * strtokIndx; // this is used by strtok() as an index
    strtokIndx = strtok(inputStringChar," ");// get the first part
    strtokIndx = strtok(NULL," ");// get the second part
    strtokIndx = strtok(NULL," ");// get the third part
    strtokIndx = strtok(NULL," ");// get the fourth part
    strtokIndx = strtok(NULL," ");// get the fifth part
    strtokIndx = strtok(NULL," ");// get the sixth part
    strtokIndx = strtok(NULL," ");// get the seventh part
    measurement_int = atoi(strtokIndx);//converts data to integer
    Serial.println(measurement_int);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
      char inputStringChar[] = ""; //creates a new empty char-array
      inputStringChar[] = char(inputString); //converts string to char-array
    }
  }
}

When compiling I to get an error:

avr-g++: error: missing filename after '-o'

exit status 1
Error compiling.

First of all I thought, that I would have done an error - but even the presented example of a "SerialEvent" does cause the same error.
Can you identify the problem?

Thank you very much!!

This is not right

      char inputStringChar[] = ""; //creates a new empty char-array
      inputStringChar[] = char(inputString); //converts string to char-array

To convert String to string
add char inputStringChar[50]; as a global variable and replace the above 2 lines with

inputString.toCharArray(inputStringChar, 50);

50 character buffer gives a bit of headroom. Code compiles and works for me with above changes using Ver. 1.04.

I would recommend getting rid of the String class altogether and using the c-array techniques presented by Robin2 in the serial input basics posts.

String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int measurement_int = 0;
char inputStringChar[50];
void setup()
{
  // initialize serial:
  Serial.begin(9600);
  // reserve 80 bytes for the inputString:
  inputString.reserve(80);
}

void loop()
{
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    char * strtokIndx; // this is used by strtok() as an index
    strtokIndx = strtok(inputStringChar," ");// get the first part
    strtokIndx = strtok(NULL," ");// get the second part
    strtokIndx = strtok(NULL," ");// get the third part
    strtokIndx = strtok(NULL," ");// get the fourth part
    strtokIndx = strtok(NULL," ");// get the fifth part
    strtokIndx = strtok(NULL," ");// get the sixth part
    strtokIndx = strtok(NULL," ");// get the seventh part
    measurement_int = atoi(strtokIndx);//converts data to integer
    Serial.println(measurement_int);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent()
{
  while (Serial.available())
  {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n')
    {
      stringComplete = true;
      inputString.toCharArray(inputStringChar, 50);
    }
  }
}

Hello again,

first of all thank you very much for this kind help! Unfortunately I have to leave to Cape town for the next few days, so I will have to test your hints after my return of the journey.

Have some nice days until then!

Have a look at Serial Input Basics - Updated to get some ideas.

Hmm, CapeTown. If you live in the WestRand near Johannesburg, we can meet if you need help.

I suggest you use the appropriate function from Serial Input Basics rather than implement a similar version. It already uses c strings.

...R

Hello again,

thank you very much, the code runs very well now and the data is collected properly!
I will save the link to the "Serial input basics" - they will be very usefull somewhen!!

@ sterretje: Thank you very much for the offer to meet! I have only had some days in Cape Town at a conference and had to go home directly afterwards again..

Thank you for your kind help!

Best regards,
Christoph

Still living in the WestRand (Johannesburg) :wink: So it depends on where you are :smiley:

Oh, sorry, I forgot to write that I am living in Austria (Central Europe), that's a huge distance :wink:

Ahah. I know it's a huge distance; I'm Dutch and travel at occasion that way.