strtok delimiter

Hi,

I am trying to receive a message via xbee which has the format shown in the attached screenshot.

What I want is to extract the TEM, HUM AND PRES values ​​using the strtok command and save them in 3 variables, var1, var2, var3.

This is what I tried in the code but I did not have a good result since I have never worked with the function:

char* data = strtok( (char*)xbee802._payload, “:”);
if (data = strtok( (char*)xbee802._payload, “:”))

sprintf(var1,"%s",data);
USB.println (var1);

if (data = strtok(NULL, “:”));
{
sprintf(var2,"%s",data);
USB.println (var2);
}

if (data = strtok(NULL, “:”));
{
sprintf(var3,"%s",data);
USB.println (var3);
}

Thanks

How to post images.

Posting images of text just makes it harder to help you. If I want to write some code to try to decipher that line, I would have to type it in. What a pain. If you post the text I could copy and paste.

Please read the forum guidelines to see how to properly post code.

My bad,

This is what I get on my xbee receiver:

Data: <=>†#575FB2C2CB018083#node_TX#102#TC:26.81#HUM:38.7#PRES:91364.92#

As I said earlier what I want is to extract the TC, PRES AND HUM data to save them in variables var1, var2, var3 with the command strtok.

The message where all the data come from is stored in xbee802._payload.

This is what I tried in the code but I did not have a good result since I have never worked with the function:

char* data = strtok( (char*)xbee802._payload, ":");
if (data = strtok( (char*)xbee802._payload, ":"))

sprintf(var1,"%s",data);
USB.println (var1);

if (data = strtok(NULL, ":"));
{
sprintf(var2,"%s",data);
USB.println (var2);
}

if (data = strtok(NULL, ":"));
{
sprintf(var3,"%s",data);
USB.println (var3);
}

Thanks

What are the printed results from your code?

here’s an approach

#include <stdio.h>
#include <string.h>

#define MAX_TOK  10
char *toks [MAX_TOK];

int
getToks (
    char *s)
{
    int   n;
    char  t [100];
    char *q;

    strcpy (t, s);
    q = t;

    for (n = 0; toks [n] = strtok (q, "#"); n++, q = NULL)
        ;
    return n;
}

int
main ()
{
    const char *s = "xx#575#mode_TX#237#TC:26.95#HUM:39.7#PRES:9139663#";
    int ntoks = getToks ((char*)s);

    for (int n = 0; n < ntoks; n++)
        printf (" %d  %s\n", n, toks [n]);

}
 0  xx
 1  575
 2  mode_TX
 3  237
 4  TC:26.95
 5  HUM:39.7
 6  PRES:9139663

strok() inserts nulls into the string passed to it. that’s why it’s copied

This is the complete code, I was modifying it but it prints the 3 variables and does not save them separately since as I mentioned before I have never worked with the strtok function

#include <WaspXBee802.h>

// define variable
uint8_t error;


char var1[10], var2[10], var3[10];

void setup()

{  
  // init USB port
  USB.ON();
  USB.println(F("Receiving example"));

  // init XBee 
  xbee802.ON();
}


void loop()
{ 
  // receive XBee packet (wait for 10 seconds)
  error = xbee802.receivePacketTimeout( 10000 );

  // check answer  
  if( error == 0 ) 
  {

char* data = strtok( (char*)xbee802._payload, ":");
while(data != NULL)
{
data = strtok(NULL, ":");  
sprintf(var1,"%s",data);
USB.println (var1);


}

  }
  else
  {
    // Print error message:
    /*
     * '7' : Buffer full. Not enough memory space
     * '6' : Error escaping character within payload bytes
     * '5' : Error escaping character in checksum byte
     * '4' : Checksum is not correct	  
     * '3' : Checksum byte is not available	
     * '2' : Frame Type is not valid
     * '1' : Timeout when receiving answer   
    */
    USB.print(F("Error receiving a packet:"));
    USB.println(error,DEC);     

    
  
  }
  
}

Esto es lo que imprime

J#
Receiving example
Error receiving a packet:1
26.73#HUM
38.6#PRES
91341.33#

Thanks

Here is how I would decode that:

char array[] = "Data: <=>†#575FB2C2CB018083#node_TX#102#TC:26.81#HUM:38.7#PRES:91364.92#";
char *strings[15];
char *ptr = NULL;

void setup()
{
    Serial.begin(9600);
    //Serial.print(array);
    byte index = 0;
    ptr = strtok(array, ":,#");
    while(ptr != NULL)
    {
        strings[index] = ptr;
        index++;
        ptr = strtok(NULL, ":,#");
    }
    //Serial.println(index);
    
    for(int n = 0; n < index; n++)
   { 
    Serial.println(strings[n]);
   }
   
   Serial.print("\n\ntemperature = ");
   Serial.print(strings[6]);
   Serial.print("   humidity = ");
   Serial.print(strings[8]);
   Serial.print("   pressure = ");
   Serial.println(strings[10]);
}

void loop()
{
    // put your main code here, to run repeatedly:

}

It seems clear the message consists mostly of name/value pairs. Each pair is delimited by '#', and the name and value within each pair are delimited by ':'. The sensible way to parse that is:

  1. Process the entire string using strtok, with '#' as the delimiter, to extract all of the name/value pairs. Save pointers to ALL of the strings returned by strtok, to be used in step #2.

  2. Process ALL the strings obtained from #1 above, and use strtok again, with ':' as the delimiter, to separate the individual name/value pairs.

  3. Process each name/value pair by examining the name to find the names you care about, and retrieve the values for those names, ignoring/discarding all the others.

That makes for a very simple, step-by-step parsing of all variables that can be easily extended to add new name/value pairs as needed.

Regards,
Ray L.