TransWikia.com

Search for a certain combination of strings in serial and read the following characters until another set character stops the search

Arduino Asked by heljo on December 24, 2020

I have the following serial message that I’m receiving from an ESP32 running GRBL:

<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>

I want to check the value after SD: which in this case would be 0.21.
It is a value that represents the percentage of a file being read, so values between 100.00 and 0.00 are being sent.

My guess is to look for the SD: in the string and then read all characters until the , but I can’t really find a way to realize that.

I found the startsWith() and the substring()function that are able to look for a set of characters in a string, but it seems like they can only check a set amount of characters which in this case doesn’t work as 0.00 is 4 characters and 100.00 is 6 characters.

Any help is much appreciated!!

One Answer

Firstly you should really be working with a C string (char *) instead of a String object, otherwise you will be massively fragmenting your heap with the string manipulations to come.

Once you have your data in a C string (char array) you can use strtok_r to split the string on the | character, then for each substring further split it on the :. You need the _r variant of strtok to make it "re-entrant" so you can have two tokenizations at once nested.

For example (untested):

char *data = "<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>";
char *pair; // Pointer to a K/V pair
char *pairptr = data; // Pointer for outer strtok

// Split the string on the first |
pair = strtok_r(data, "|", &pairptr);

// While we have a K/V pair
while (pair) {
    char *kvptr = pair;
    // Split the substring into two parts on the colon
    char *key = strtok_r(pair, ":", &kvptr);
    char *val = strtok_r(NULL, ":", &kvptr);
    if (val) { // If we split the data correctly:
        if (strcmp(key, "SD") == 0) { // If the key is "SD" then
            Serial.print("SD data: ");
            Serial.println(val);
        }
    }
    // Get the next string portion
    pair = strtok_r(NULL, "|", &pairptr);
}

Once you have your val you can further split that down on commas in the same way as it's been split on the colon.

Answered by Majenko on December 24, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP