0

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!!

jsotola
1,5342 gold badges12 silver badges20 bronze badges
asked Dec 17, 2020 at 12:06
2
  • I'd split the string on | then for each substring split it on :. You then have key/value pairs that are easy to compare and work with. Use a C string not a String object and strtok_r and strcmp to do the job with minimal memory outlay. I'll write a proper answer later, I'm on my phone at the moment. Commented Dec 17, 2020 at 12:26
  • @Majenko thanks for the super quick reply! I 'll give it a try as far as I can! Commented Dec 17, 2020 at 13:08

1 Answer 1

1

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 Dec 17, 2020 at 15:18

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.