Decode a serial link

Hi
I have a 2 arduino's and trying to make a serial command between them.

The first one is sending a serial string to the other

void setup()
{
 Serial.begin(9600);
}
void loop()
{
 int value1 = 10; // some hardcoded values to send
 int value2 = 100;
 int value3 = 1000;
 
 
 Serial.print('

Plan is for when i get it to work, is to send a analog command to the other one. Just wanæt to get it to work before i move on

The serial output for now is
$,10,100,1000
$,10,100,1000
$,10,100,1000
$,10,100,1000
$,10,100,1000
$,10,100,1000

How can I decode it?
I have tried with examples with strtok() function. but I have had no luck

This is my first time trying the arduino, so just a total noob question
Could someone help me in the right direction?

); // unique header to identify start of message
Serial.print(",");
Serial.print(value1,DEC);
Serial.print(",");
Serial.print(value2,DEC);
Serial.print(",");
Serial.print(value3,DEC);
Serial.print(","); // note that a comma is sent after the last field
Serial.println(); // send a cr/lf
delay(100);

}


Plan is for when i get it to work, is to send a analog command to the other one. Just wanæt to get it to work before i move on

The serial output for now is
$,10,100,1000 
$,10,100,1000
$,10,100,1000
$,10,100,1000
$,10,100,1000
$,10,100,1000

How can I decode it?
I have tried with examples with strtok() function. but I have had no luck

This is my first time trying the arduino, so just a total noob question
Could someone help me in the right direction?

Post your strtok attempt.

Have a look at Serial input basics - updated

Here is my attempt

#include <string.h>
char inData[80];
char thruster[80];
byte index = 0;

void setup()
{
Serial.begin(9600);

}

void loop()
{
  while(Serial.available() > 0)
  {
     char aChar = Serial.read();
     if(aChar == '\n')
     {
        // End of record detected. Time to parse
           char *p = inData; //assign the string to *p
           char *str;        //intialize str
           int counter = 0; //initialise the counter
           
           while (str = strtok_r(p, ",", &p)) // delimiter is the comma. NULL is the terminator
           {
                 thruster[counter] = *str; //use the counter as an index to add each value to the array
                 counter++; //increment the counter
    
              p = NULL;
           }
               index = 0;
        inData[index] = NULL;
          
     }
     else
     {
        inData[index] = aChar;
        index++;
        inData[index] = '\0'; // Keep the string NULL terminated
        
     }
  }
  //debugging
        Serial.print("Fwd: ");
        Serial.println(thruster[0]);
        Serial.print("aft: ");
        Serial.println(thruster[1]);
        Serial.print("Lat: ");
        Serial.println(thruster[2]);
}

you might want to:

  • test for bounds so that you don't overflow memory (you have 79 chars + the trailing null to fit in the buffer max)
  • write the serial handler as a separate function you call from the loop()
  • put the parser outside the serial handler function

that will make your code more robust and reusable

I'm not sure what you are receiving but this codethruster[counter] = *str; //use the counter as an index to add each value to the arraystores the first character of each token into the thruster array in sequence. is that what you want? (probably not I assume you want the full token)

Hi WildBill
Tried the link you showed me and made this

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

      // variables to hold the parsed data
int thruster1 = 10;
int thruster2 = 100;
int thruster3 = 1000;

boolean newData = false;

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

void setup() {
    Serial.begin(9600);
    Serial.println("Enter data in this style $,10,100,1000\r\n  ");
    Serial.println();
}

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

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 = '

I receiving data but it will only show
Thruster1: 0
Thruster2: 0
Thruster3: 0

;
   char endMarker = '\n';
   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(NULL, ",");
   thruster1 = atoi(strtokIndx); // copy it to Thuster1

strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
   thruster2 = atoi(strtokIndx);     // convert this part to an integer

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

}

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

void showParsedData() {
   Serial.print("Thruster1: ");
   Serial.println(thruster1;
   Serial.print("Thruster2 : ");
   Serial.println(thruster2);
   Serial.print("Thruster3:  ");
   Serial.println(thruster3);
}


I receiving data but it will only show
Thruster1: 0
Thruster2: 0
Thruster3: 0

J-M-L
Hi

Yes.. And I are moving away from the code I was testet to a code that more in line with what you suggest.

As my string is now
$,10,100,1000\r\n

I want to strip away the start character
and divide the string in the respective order

thruster1 10
thruster2 100
thruster3 1000

So i can use them later on in my program

comment on your post #5

  • you are initializing thruster2 twice instead of thruster3
  • print what you are parsing, that will give you a hint

The first call to strtok should not take NULL as a parameter but the string you're asking it to parse.

try something like this

char message[] = "$,10,100,1000\r\n";

int thruster[3];

void showParsedData() {

  for (int i = 0; i < 3; i++) {
    Serial.print(F("Thruster"));
    Serial.print(i);
    Serial.print(F(" : "));
    Serial.println(thruster[i]);
  }
}

boolean parseData() {
  boolean parseOK = false;
  if ((*message == '

) && (strlen(message) > 8)) { // assume it's good
    char * str = strtok(message + 2, ",");
    int index = 0;
    while (str && index < 3) {
      thruster[index++] = atoi(str);
      str = strtok(NULL, ",");
    }
    parseOK = (index == 3);
  }
  return parseOK;
}

void setup() {
  Serial.begin(115200);
  if (parseData()) showParsedData();
  else Serial.println(F("Parse Error"));
}

void loop() {}

Hi Wildbill

I'm guessing you mean this line of code

strtokIndx = strtok(NULL, ",");
thruster1 = atoi(strtokIndx); // copy it to Thuster1

I see that i did something wrong when i copied a line..
That did the trick ..

Will try and advance on the code now to se if I can get everything to play ball

psathammer:
Will try and advance on the code now to se if I can get everything to play ball

check what I posted above, maybe that will help out

J-M-L
I will have a look..
Probably gonna ask some questions as i progress with my program