There was no indication that there was an end-of-line character, such as a newline, linefeed, carriage return, etc, only that the data ends with a double colon "::", and I forgot to ask if every transmission frame would contain all the variables, so testing for "59:x::" as an end-of-line indicator might not be reliable. I tried a slightly different tactic of considering each variable/value pair to be its own line of data. Without seeing the rest of the code its really difficult to know if this would be acceptable, but its easy enough to implement.
The following code will take the input line:
2:0::3:0::5:0::15:0::19:0::20:0::37:0::38:0::40:0::42:0::51:0::58:0::59:0::
and separate it into individual lines of input data in the format:
2:0:
3:0:
5:0:
15:0:
19:0:
20:0:
37:0:
38:0:
40:0:
42:0:
51:0:
58:0:
59:0:
From there it's easy to parse each line for the ":" and set the appropriate variable to its corresponding value.
const byte numChars = 32;
char receivedChars[numChars]; //array to store received data
char endMarker = ':'; //end of input data indicator <cr>
bool newData = false;
byte var2, var3, var5, var15, var19, var20, var58, var59;
float var37, var38, var40, var42, var51;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println(F("startup"));
}
void loop() {
ReceiveData();
if (newData == true) {
newData = false;
Serial.println(receivedChars);
parseData();
//only printing when last data has been received
//otherwise the receive buffer overruns because
//of delay from printing too much text.
// if ((receivedChars[0] == '5') && (receivedChars[1] == '9')) {
if (atoi(receivedChars) == 59) {
displayData();
}
}
}
void ReceiveData() {
static byte index = 0; //index into receive buffer
static bool endPending = false; //flag to indicate potential double colon separator
char RcvChar;
while (Serial.available() > 0 && newData == false) {
RcvChar = Serial.read();
if ((RcvChar == endMarker) && (endPending == true)) { //if current and previous character was :
receivedChars[index] = '\0'; // terminate the string
index = 0; //reset index to beginning of buffer
newData = true; //let program know new data is available
} else {
endPending = (RcvChar == endMarker) ? true : false; //set flag to indicate : has been received
receivedChars[index] = RcvChar;
index++;
if (index >= numChars) { //check for receive buffer overflow
index--;
}
}
}
}
void displayData() {
Serial.println();
Serial.print(F("var2 = "));
Serial.println(var2);
Serial.print(F("var3 = "));
Serial.println(var3);
Serial.print(F("var5 = "));
Serial.println(var5);
Serial.print(F("var15 = "));
Serial.println(var15);
Serial.print(F("var19 = "));
Serial.println(var19);
Serial.print(F("var20 = "));
Serial.println(var20);
Serial.print(F("var37 = "));
Serial.println(var37, 5);
Serial.print(F("var38 = "));
Serial.println(var38, 5);
Serial.print(F("var40 = "));
Serial.println(var40, 5);
Serial.print(F("var42 = "));
Serial.println(var42, 5);
Serial.print(F("var51 = "));
Serial.println(var51, 5);
Serial.print(F("var58 = "));
Serial.println(var58);
Serial.print(F("var59 = "));
Serial.println(var59);
Serial.println();
}
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
byte variable;
char tempChars[numChars];
strcpy(tempChars, receivedChars);
strtokIndx = strtok(tempChars, ":"); // get the first part - the string
if (strtokIndx != NULL) {
variable = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":"); // this continues where the previous call left off
if (strtokIndx != NULL) {
switch (variable) {
case 2:
var2 = atoi(strtokIndx);
break;
case 3:
var3 = atoi(strtokIndx);
break;
case 5:
var5 = atoi(strtokIndx);
break;
case 15:
var15 = atoi(strtokIndx);
break;
case 19:
var19 = atoi(strtokIndx);
break;
case 20:
var20 = atoi(strtokIndx);
break;
case 58:
var58 = atoi(strtokIndx);
break;
case 59:
var59 = atoi(strtokIndx);
break;
case 37:
var37 = atof(strtokIndx);
break;
case 38:
var38 = atof(strtokIndx);
break;
case 40:
var40 = atof(strtokIndx);
break;
case 42:
var42 = atof(strtokIndx);
break;
case 51:
var51 = atof(strtokIndx);
break;
default:
//error
break;
}
}
}
}