Найти определенную комбинацию строк в serial и считывать следующие символы до тех пор, пока другой установленный символ не остановит поиск

У меня есть следующее последовательное сообщение, которое я получаю от ESP32 под управлением GRBL:

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

Я хочу проверить значение после SD: которое в данном случае будет равно 0.21. Это значение, представляющее процент считываемого файла, поэтому отправляются значения от 100.00 до 0.00.

Я предполагаю, что нужно искать SD: в строке, а затем читать все символы до тех пор, пока я не смогу найти способ понять это.

Я нашел функции StartsWith() и substring(), которые могут искать набор символов в строке, но похоже, что они могут проверять только заданное количество символов, которое в данном случае не работает, так как 0.00 - это 4 символа, а 100.00 - 6 символов.

Любая помощь очень ценится!!

, 👍0

Обсуждение

Я бы разделил строку на |, затем для каждой подстроки разделил ее на :. Затем у вас есть пары ключ / значение, которые легко сравнивать и с которыми легко работать. Используйте строку C, а не объект String, а также strtok_r и strcmp, чтобы выполнить задание с минимальными затратами памяти. Я напишу правильный ответ позже, в данный момент я разговариваю по телефону., @Majenko

@Majenko спасибо за супер быстрый ответ! Я попробую сделать это, насколько смогу!, @heljo


1 ответ


1

Во-первых, вы действительно должны работать со строкой C (char *) вместо строкового объекта, иначе вы будете массово фрагментировать свою кучу со строковыми манипуляциями.

Как только у вас есть данные в строке C (массив char), вы можете использовать strtok_r для разделения строки на символ |, а затем для каждой подстроки дополнительно разделить ее на :. Вам нужен вариант _r strtok, чтобы сделать его "повторным участником", чтобы вы могли вложить сразу две токенизации.

Например (непроверено):

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; // Указатель на пару K/V
char *pairptr = data; // Указатель на внешний strtok

// Разбить строку на первую |
pair = strtok_r(data, "|", &pairptr);

// Пока у нас есть пара K/V
while (pair) {
    char *kvptr = pair;
    // Разбить подстроку на две части по двоеточию
    char *key = strtok_r(pair, ":", &kvptr);
    char *val = strtok_r(NULL, ":", &kvptr);
    if (val) { // Если мы правильно разделим данные:
        if (strcmp(key, "SD") == 0) { // Если ключ "SD", то
            Serial.print("SD data: ");
            Serial.println(val);
        }
    }
    // Получить следующую часть строки
    pair = strtok_r(NULL, "|", &pairptr);
}

Как только у вас есть val, вы можете разделить его на запятые так же, как он был разделен на двоеточие.

,