Разделенный последовательный поток Arduino, разделенный запятыми

Я пытаюсь прочитать последовательные данные в Arduino.

Обычно я использую кабель Serial-to-USB для подключения к оборудованию и отправляю данные, например

33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68

Со скоростью 38 400.

Я читал этот пост Разделение строки, разделенной запятыми, через последовательный порт (Arduino) https://www.arduino.cc/reference/en/language/functions/communication/serial/print/

Я пытался написать что-то свое, но ничего не вернуло читаемых данных.

Какие-нибудь советы, пожалуйста?

, 👍1

Обсуждение

Похоже, ваше устройство использует линейный протокол, в котором каждое сообщение заканчивается символом CR и/или LF. Первое, что вы должны сделать, это убедиться, что вы буферизуете ввод, чтобы обрабатывать по одной строке за раз. См. [Reading Serial on the Arduino] (https://majenko.co.uk/blog/reading-serial-arduino), автор Majenko. Как только вы разберетесь с этим, следуйте совету Крисла., @Edgar Bonet

см. https://arduinoprosto.ru/q/1013/how-do-i-split-an-incoming-string, @radinParsaei


1 ответ


Лучший ответ:

2

Справочная статья, на которую вы ссылаетесь, посвящена отправке данных через Serial, а не чтению.

Вы можете использовать функцию strtok(), которая может разделить буфер символов на токены на основе символа-разделителя (запятая в вашем случае).

Во-первых, у вас есть буфер, в котором сохраняется ваше сообщение Serial (я не буду рассматривать фактическое получение/чтение данных Serial здесь, потому что в Интернете есть множество руководств):

char buffer[] = "1,2.3,4,0x56";

Тогда вы можете получить первый токен:

char *token1 = strtok(buffer, ",");

token1 — это указатель на начало токена. strtok() заменяет найденный разделитель (который вы указываете вторым параметром) нулевым символом. Это означает, что token1 указывает на заканчивающуюся нулем строку C, содержащую только первый токен (имейте в виду, что при этом изменяется буфер, поэтому нет смысла пытаться печатать buffer после того, как вы использовали strtok()). Обратите внимание, что это не создает новый буфер. Он просто указывает на определенное место внутри buffer.

Вы также можете напрямую обработать его, например преобразовать в целое число:

int token1_value = atoi(strtok(buffer, ",");

Чтобы получить следующий токен, вы просто снова вызываете strtok(), но теперь вы указываете NULL вместо buffer в первом параметре. . Это сообщает strtok(), что вы все еще хотите обработать тот же буфер, что и при последнем выполнении.

float token2_value = atof(strtok(NULL, ",");

Теперь вы можете делать это до тех пор, пока в буфере не останется необработанных токенов. В этом случае strtok() возвращает NULL.

char *token = strtok(NULL, ",");
while(token != NULL){
    Serial.println(token);
    token = strtok(NULL, ",");
}

Посмотрите справочник по C++ для strtok(). Он также включает онлайн-редактор, где вы можете запустить предоставленный пример и поиграть с ним.

,