Разбор целых чисел из последовательного потока данных
Я пытаюсь отправить данные датчика с моего пульта дистанционного управления на мой бот через Bluetooth. Это 6 чисел, которые я хотел бы читать как целые числа на другой стороне. Я печатаю их в Serial на удаленной стороне с числами, разделенными запятыми. Я также добавил маркер начала "<" и маркер конца ">".
Входящие данные с удаленного устройства выглядят в последовательном мониторе Bots следующим образом:
<1,1,1,1,1,512>
<1,1,1,1,1,512>
<1,1,1,1,1,513>
<1,1,1,1,1,512>
<1,1,1,1,1,512>
и т. д.
Перед добавлением маркеров я пытался использовать Serial.parseInt(), чтобы сделать это, но мне не хватило порядковых номеров (вероятно, из-за отсутствия начального маркера?).
if (Serial1.available() > 0) {
trig1 = Serial.parseInt();
trig2 = Serial.parseInt();
trig3 = Serial.parseInt();
trig4 = Serial.parseInt();
trig5 = Serial.parseInt();
pot = Serial.parseInt();
if (Serial.read() == '\n') {
}
}
Но теперь, когда у меня есть маркеры, я не знаю, как лучше инициализировать код. У кого-нибудь есть идеи, как преобразовать эти 6 чисел в пригодные для использования целые числа?
EDIT: я написал код на основе комментариев VE7JRO.
uint16_t myArray[6] = {};
int counter = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
char* pch = strtok(Serial.read,"<>,\r\n");
}
while(pch != NULL){
myArray[counter] = atoi(pch);
pch = strtok(NULL, "<>,\r\n");
counter += 1;
}
trig1 = myArray[0];
trig2 = myArray[1];
trig3 = myArray[2];
trig4 = myArray[3];
trig5 = myArray[4];
pot = myArray[5];
Serial.print (trig1);
Serial.print (", ");
Serial.print (trig2);
Serial.print (", ");
Serial.print (trig3);
Serial.print (", ");
Serial.print (trig4);
Serial.print (", ");
Serial.print (trig5);
Serial.print (", ");
Serial.println(pot);
}
Я получаю этот код ошибки: неправильное использование нестатической функции-члена
для этой строки:
char* pch = strtok(Serial.read,"<>,\r\n");
Кроме того. Я добавил тестовый ввод, который вставил VE7JRO, и вставил «Serial.read». Не уверен, что это правильный способ сделать это. Есть идеи?
Я попробовал ваш второй скетч. Это как бы сработало. Данные, напечатанные на последовательном мониторе, выглядели следующим образом:
1, 1, 1, 1, 1, 519 518, 1, 1, 1, 1, 519 1, 1, 1, 1, 19, 9 1, 1, 1, 1, 1, 519 1, 1, 1, 1, 1, 519 1, 1, 1, 1, 1, 518 1, 1, 519, 518, 1, 518 1, 1, 519, 518, 1, 518 1, 1, 518, 518, 1, 518 1, 1, 1, 1, 1, 8 1, 1, 1, 1, 1, 519 1, 1, 518, 1, 1, 1 8, 1, 518, 1, 1, 1 1, 1, 519, 1, 1, 1 1, 1, 1, 519, 1, 1 1, 1, 1, 519, 1, 1 1, 1, 1, 1, 1, 519 1, 1, 1, 1, 1, 518 1, 1, 1, 1, 519, 8 1, 1, 1, 1, 1, 518 1, 1, 1, 1, 1, 519 1, 1, 1, 1, 1, 518 1, 1, 1, 1, 1, 518 1, 1, 1, 1, 1 520
Все это должно было быть 1, 1, 1, 1, 1, 518 (даже).
@PatchBOTS, 👍1
Обсуждение1 ответ
Лучший ответ:
Вот скетч, использующий strtok() и atoi() для анализа данных и сохранения результатов в массиве integer
.
char testInput[] = "<1,2,3,4,5,512>\r\n";
uint16_t myArray[6] = {};
void setup(){
Serial.begin(9600);
int counter = 0;
char* pch = strtok(testInput,"<>,\r\n");
while(pch != NULL){
myArray[counter] = atoi(pch);
pch = strtok(NULL, "<>,\r\n");
counter += 1;
}
// Распечатать содержимое массива целых чисел.
for(int i = 0; i < counter; i++){
Serial.println(myArray[i]);
}
}
void loop(){}
Дополнение
Основываясь на ваших комментариях, у меня есть еще один скетч, который вы можете попробовать.
// Пример ввода: <1,2,3,4,5,512>
char testInput[40];
uint16_t myArray[6] = {};
int counter = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
if(Serial.available() > 0){
Serial.readBytesUntil('\n', testInput, 40);
char* pch = strtok(testInput,"<>,\r\n");
while(pch != NULL){
myArray[counter] = atoi(pch);
pch = strtok(NULL, "<>,\r\n");
counter += 1;
}
Serial.print (myArray[0]);
Serial.print (", ");
Serial.print (myArray[1]);
Serial.print (", ");
Serial.print (myArray[2]);
Serial.print (", ");
Serial.print (myArray[3]);
Serial.print (", ");
Serial.print (myArray[4]);
Serial.print (", ");
Serial.println(myArray[5]);
counter = 0;
}
}
Это очень полезно! Думаю, я понимаю большую часть этого. Это действительно все работает в настройках? Я не хочу печатать массив, а использую каждое целое число как переменную в остальной части моего скетча. Есть ли функция для этого? Извините, я немного новичок и едва понимаю это в целом, @PatchBOTS
Весь код находится в setup()
для целей тестирования. Целочисленный массив содержит 6 целых чисел и может использоваться в качестве переменных в остальной части вашего скетча. Каждый раз, когда вы получаете новые данные, их следует анализировать с помощью strtok()
., @VE7JRO
Так даст ли это мне переменные из массива? триггер1 = мой массив [1]; триг2 = мой массив [2]; триг3 = мой массив [3]; триг4 = мой массив [4]; триг5 = мой массив [5]; горшок = мой массив [6]; Я не могу проверить прямо сейчас, иначе я бы просто проверил себя. Рад найти ответ!, @PatchBOTS
Да, вы можете сделать это или просто использовать массив напрямую, например, if(myArray[0] > 1){ // сделать что-нибудь}
., @VE7JRO
Большое спасибо, это было очень полезно!, @PatchBOTS
Я отредактировал OP со своим кодом. Получение ошибки на одной из строк, @PatchBOTS
Я отредактировал OP с результатами вашего второго скетча. Смешанные результаты., @PatchBOTS
Попробуйте отправить \n
в конце ваших данных: "<1,1,1,1,1,512>\n", @VE7JRO
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- В чем разница между Serial.write и Serial.print? И когда они используются?
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Программы построения последовательных данных
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Очистить существующий массив при получении новой последовательной команды
У parseInt есть тайм-аут. Это может замедлить набросок. Вы можете заполнить буфер данными (каждый раз по одному байту), и когда все данные будут прочитаны, выполните sscanf. Для parseInt запятую нужно пропустить. Маркеры "<" и ">" очень хороши. Пожалуйста, предоставьте минимальный скетч, который считывает данные с последовательного монитора, чтобы мы могли его протестировать., @Jot