ESP32 is getting restarted while using strtok

Hello,

I am using a strtok to store a value that is coming from another esp32. But when I store the first value, it gets stored

The data is coming in the format

78542EF8A038,46,91]

but when I try to store another value, the esp32 gets restarted, but it is still able to print a few data points. I don't know what's going wrong. Here is code

#include <HardwareSerial.h>

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
char macFromPC[numChars] = {0};
char ttlFromPC[numChars] = {0};
char statusFromPC[numChars] = {0};

boolean newData = false;

HardwareSerial SerialPort(2);
//============

void setup() {
    Serial.begin(115200);
    SerialPort.begin(9600,SERIAL_8N1, 16, 17);
    
}

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

void loop() {
    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);

        parseData();
        showParsedData();
        newData = false;
    }
}

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

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

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

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

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

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

void parseData() {     

    char * strtokIndx; 

    strtokIndx = strtok(tempChars,",");      
    strcpy(macFromPC, strtokIndx); 
     
    strtokIndx = strtok(NULL,",");      
    strcpy(ttlFromPC, strtokIndx); 


    strtokIndx = strtok(NULL,",");      
    strcpy(statusFromPC, strtokIndx); 

}

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

void showParsedData() {
    Serial.print("MAC");
    Serial.println(macFromPC);
    Serial.print("TTL VALUE ");
    Serial.println(ttlFromPC);
    Serial.print("STATUS VALUE");
    Serial.println(statusFromPC);
}

I don't know why it's getting restarted the data which is coming is very less .

here's the error i get

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0

Is tempChars always guaranteed to have data in that format, which I recognise from your other topic, or is it possible that some or all of the data is missing ?

Ohk I need to check on that . I though if data is not present it will just skip .

So, a better approach would be to save the incoming value as a string with the same format first, and then apply. Is it a good idea

Here's i am getting data i have printed on serial monitor

 B21041DB2895,57,3]
3E839948A7AA,58,2]
1E2E9E8EC9A
9AD925CDFEC

Serial.readBytesUntil () may be easier to use, as well as a generic tokenizer

Output

 -13035  123456789
     59  59
      1  1
  MAC 123456789
  TTL 59
  Status 1
      0  

Code

// -----------------------------------------------------------------------------
#define MaxTok  10
char *toks [MaxTok];
int   vals [MaxTok];

int
tokenize (
    char       *s,
    const char *sep )
{
    unsigned n = 0;
    toks [n] = strtok (s, sep);
    vals [n] = atoi (toks [n]);

    for (n = 1; (toks [n] = strtok (NULL, sep)); n++)
        vals [n] = atoi (toks [n]);

    return n;
}

// -------------------------------------
void dispToks (
    char * toks [])
{
    char s [40];
    for (unsigned n = 0; toks [n]; n++)  {
        sprintf (s, " %6d  %s", vals [n], toks [n]);
        Serial.println (s);
    }
}

// -----------------------------------------------------------------------------
char s [80];
void
decode (
    char *buf )
{
    int nTok = tokenize (buf, ",");
    dispToks (toks);

    if (3 == nTok)  {
        sprintf (s, "  MAC %s",    toks [0]); Serial.println (s);
        sprintf (s, "  TTL %s",    toks [1]); Serial.println (s);
        sprintf (s, "  Status %s", toks [2]); Serial.println (s);
    }
}

// -----------------------------------------------------------------------------
char buf [80];

void loop ()
{
    if (Serial.available ()) {
        int n = Serial.readBytesUntil ('>', buf, sizeof(buf)-1);
        buf [n] = '\0';

        decode (buf);
    }
}


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

awareness can be gained seeing other parts of code

How ? Wow. But it's very difficult to understand this code. Need to try but it's works like a charm .

Isn't that blocking code?

that's how you learn. and you're already using the pieces

tokenize just provides a general purpose routine that can be used elsewhere with less duplication

yes. is that a constraint in this case?

Just my own constraint when using a ESP32. An ESP32 has no need to do blocking code, Understanding may yet come? But I won't be able to teach it.

regardless of what the processor is capable of, isn't it the application that dictates the requirements?

KISS

Not always. Sometimes one's own skill limitations may dictate requirements.

an opportunity to learn. otherwise i don't see value in implementing something that is not required

strtok() is useful. But can be tricky.

Take a look at this complete example, here using the more common pattern wherein a while statement controls the action:

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

int main () {
   char str[80] = "This is - www.tutorialspoint.com - website";
   const char s[2] = "-";
   char *token;
   
   /* get the first token */
   token = strtok(str, s);
   
   /* walk through other tokens */
   while (token != NULL) {
      printf(" %s\n", token);
    
      token = strtok(NULL, s);
   }
   
   return(0);
}

Perhaps protect against running out of data:

void parseData() {     
    char * strtokIndx; 
    strtokIndx = strtok(tempChars,",");
    if (strtokIndx != NULL)
    {
      strcpy(macFromPC, strtokIndx);

      strtokIndx = strtok(NULL,",");
      if (strtokIndx != NULL)
      {
        strcpy(ttlFromPC, strtokIndx);

        strtokIndx = strtok(NULL,",");
        if (strtokIndx != NULL)
        {
          strcpy(statusFromPC, strtokIndx);
        }
      }
    }
}

The sketch is compiled and uploaded in UNO, but it does not show any output on the Serial Monitor. The Arduino compatible one is given below:

char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char *token;

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

  /* get the first token */
  token = strtok(str, s);

  /* walk through other tokens */
  while (token != NULL) 
  {
    Serial.println(token);
    token = strtok(NULL, s);
  }
}

void loop() {}

Figure out what you are doing wrong.

I just cut the code from your post, loaded it on an UNO and this came out

This is 
 www.tutorialspoint.com 
 website

the expected output.

a7

There are three tokens in the given string (with "-" as delimiter) and the output is showing them except that the first token is shifted to the left by one character position. If I choose " - " (3 characters) as delimiter, then I get four tokens -- why?

You need to go look at how strtok() works.

You need to know what a delimiter is, and what is meant in this context by a token.

There is nothing surprising in your posts, other than you have failed to explain why it didn't work at all for you at first…

Try google when you are up to it.

a7