Problems Receiving and parsing data with an object.

Hi everyone , it's my first post here.

I am trying to create a Receiver class that will read from the serial monitor and store the received data into variables.

The object expect data arrange this way: <string, string, string, string , string>

I am starting from some code from the Serial Input Basics tutorial here on the Arduino forum, more specifically

"Example 5 - Receiving and parsing several pieces of data".

The code is compiling but the data get mixed up.

This is the code

class Signal {

private:

const static byte numChars = 32;
char tempChars[32]; 
char receivedChars[32];
boolean newData;

int data1;
int data2;
int button;
int xAxis;
int yAxis;


public :

  Signal(){

    newData = false;
  
    data1 = 0;
    data2 = 0;
    button = 0;
    xAxis = 0;
    yAxis = 0;
    
    }
  

//=============

  void loop() {
    
    recvWithStartEndMarkers();
    
      if (newData == true) {
        
        strcpy(tempChars, receivedChars);
        parseData();
        showParsedData();
        newData = false;
    }
   }

//============

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    static char startMarker = '<';
    static char endMarker = '>';
    
    
    while (Serial.available() > 0 && newData == false) {
      char rc = Serial.read();
        
        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars, ",");      // get the first part - the string
    xAxis =  atoi(strtokIndx);// copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    yAxis = atoi(strtokIndx);     // convert this part to an int
    
    strtokIndx = strtok(NULL, ",");
    data1 = atoi(strtokIndx);     // convert this part to a int

    strtokIndx = strtok(NULL, ",");
    data2 = atoi(strtokIndx);     // convert this part to a int

    strtokIndx = strtok(NULL, "");
    button = atoi(strtokIndx);     // convert this part to a int

}

//============

void showParsedData() {
   
    Serial.print("xAxis ");
    Serial.print (xAxis);
    Serial.print(" yAxis ");
    Serial.print(yAxis);
    Serial.print(" Data1 ");
    Serial.print(data1);
    Serial.print(" Data2 ");
    Serial.print(data2);
    Serial.print(" Button ");
    Serial.print(button);
    Serial.println("");  
}

};

//<0,0,0,0,0>

Signal RCsignal;

void setup() {
  Serial.begin(38400);
}

void loop() {
  RCsignal.loop();
}

Down here is the original version of the code that I want to turn into a class. This version is working just fine.

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing
boolean newData = false;

int xAxis, yAxis , data1 , data2, button ;


//============

void setup() {
    Serial.begin(38400);
    Serial.println("Enter data in this style <0,0,0,0,0>  ");
  
  
}
//============

void loop() {
    
    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
    }
   
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;


    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

//============

 void  parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars, ",");      // get the first part - the string
    xAxis =  atoi(strtokIndx);// 
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    yAxis = atoi(strtokIndx);     // convert this part to an integer
    
    strtokIndx = strtok(NULL, ",");
    data1 = atoi(strtokIndx);     // 

    strtokIndx = strtok(NULL, ",");
    data2 = atoi(strtokIndx);     // 

    strtokIndx = strtok(NULL, "");
    button = atoi(strtokIndx);     // 

}

void showParsedData() {
   
    Serial.print("x ");
    Serial.print (xAxis);
    Serial.print(" y ");
    Serial.print(yAxis);
    Serial.print(" data1 ");
    Serial.print(data1);
    Serial.print(" data2 ");
    Serial.print(data2);
    Serial.print(" Button ");
    Serial.print(button);
    Serial.println("");    
}

I can't find the problem(s) in my Signal class. What am I doing wrong? xAxis (0-180)and yAxis(0-255) are data collected from a joystick. The problem arise when I play with it. Some data from the joystick will sometime appear in the "button" and "data2 "variables. If I don't touch the joystick everything is fine, the same values are printed over and over again.

I am running this sketch on a nano.

Thanks in advance.

For starters you have unmatched curly braces on the class.

Do a ctrl+T on the sketch to format the text (and set indents) - this makes finding such things easier. And it looks nicer, too.

dougp:
For starters you have unmatched curly braces on the class.

Where exactly? I don't see it.

With my cursor on the brace of class Signal { , the matching brace shows after the closing brace of void showParsedData().

vince_s:
Down here is the original version of the code that I want to turn into a class. This version is working just fine.

There's some low quality code present in both versions. Also, conversion to the class is half-baked at the current stage.

However, I don't immediately see any reason why these two versions would behave differently. Did you try to print the tempChars strings that are being handed over to parseData() for parsing? How do they compare between the two versions?

dougp:
With my cursor on the brace of class Signal { , the matching brace shows after the closing brace of void showParsedData().

Which is how it should be. Why did it make you conclude that the braces are unmatched?

Montmorency:
Which is how it should be. Why did it make you conclude that the braces are unmatched?

Because there's a void loop() contained within the class in addition to the one at the bottom of the sketch.

dougp:
Because there's a void loop() contained within the class in addition to the one at the bottom of the sketch.

There's nothing wrong with that. It is pretty obvious from the code why the OP decided to call that class method loop().

Did you try to print the strings that are being handed over to parseData() for parsing? How do they compare them between the two versions?

I just did. When I print the value of the strings just before the call to atoi, the values are correct.

vince_s:
I just did. When I print the value of the strings just before the call to atoi, the values are correct.

Keep narrowing the search then. Print the individual strtokIndx tokens and the converted values after atoi.

I just don't see how correct input to parseData() may lead to incorrect output from showParsedData(). There's no way.

If I skip showParsedData() and I print the value directly into parseData() its seems to be working.
I will continue to run some tests to find what was wrong. If I find anything I will share the info.

Thanks for the help.

Montmorency:
There's nothing wrong with that. It is pretty obvious from the code why the OP decided to call that class method loop().

Seems my reach exceeds my grasp. Apologies for any trouble caused to OP.