Arduino (язык C) разбор строки с разделителем (ввод через последовательный интерфейс)
Arduino (язык C) разбор строки с разделителем (ввод через последовательный интерфейс)
Не нашел ответ здесь:/
Я хочу отправить на arduino через последовательный интерфейс (Serial.read()) простую строку из трех чисел, разделенных запятой. Эти три цифры могут быть в диапазоне 0-255.
Eg.
255,255,255
0,0,0
1,20,100
90,200,3
Что мне нужно сделать, так это разобрать эту строку, отправленную в arduino, на три целых числа (скажем, r, g и b).
Итак, когда я отправляю 100,50,30
arduino переведет его на
int r = 100
int g = 50
int b = 30
Я пробовал много кодов, но никто из них не работал. Основная проблема заключается в том, чтобы перевести строку (связку символов) в целое. Я понял, что, возможно, будет strtok_r для цели разделителя, но это о нем.
Спасибо за любые предложения:)
Ответы
Ответ 1
Чтобы ответить на заданный вами вопрос, объекты String очень мощные, и они могут делать именно то, что вы просите. Если вы ограничиваете свои правила синтаксического анализа непосредственно со входа, ваш код становится менее гибким, менее многоразовым и слегка запутанным.
Строки имеют метод indexOf(), который позволяет вам искать индекс в массиве символов String определенного символа. Если символ не найден, метод должен возвращать -1. Второй параметр можно добавить к вызову функции, чтобы указать начальную точку для поиска. В вашем случае, поскольку ваши разделители являются запятыми, вы должны позвонить:
int commaIndex = myString.indexOf(',');
// Search for the next comma just after the first
int secondCommaIndex = myString.indexOf(',', commaIndex + 1);
Затем вы можете использовать этот индекс для создания подстроки с использованием метода substring() класса String. Это возвращает новый String, начинающийся с определенного начального индекса, и заканчивается непосредственно перед вторым индексом (или конец файла, если ни один не указан). Таким образом, вы бы напечатали нечто похожее на:
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex + 1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex + 1); // To the end of the string
Наконец, целые значения могут быть получены с использованием недокументированного метода класса String, toInt():
int r = firstValue.toInt();
int g = secondValue.toInt();
int b = thirdValue.toInt();
Более подробную информацию о объекте String и его различных методах можно найти в документации Arduino.
Ответ 2
Используйте sscanf
;
const char *str = "1,20,100"; // assume this string is result read from serial
int r, g, b;
if (sscanf(str, "%d,%d,%d", &r, &g, &b) == 3) {
// do something with r, g, b
}
Используйте мой код здесь, если вы хотите проанализировать поток строки ex: 255,255,255 0,0,0 1,20,100 90,200,3
Функция анализа для строки с разделителями-запятыми
Ответ 3
Я думаю, вы хотите сделать что-то подобное, чтобы читать данные:
String serialDataIn;
String data[3];
int counter;
int inbyte;
void setup(){
Serial.begin(9600);
counter = 0;
serialDataIn = String("");
}
void loop()
{
if(serial.available){
inbyte = Serial.read();
if(inbyte >= '0' & inbyte <= '9')
serialDataIn += inbyte;
if (inbyte == ','){ // Handle delimiter
data[counter] = String(serialDataIn);
serialDataIn = String("");
counter = counter + 1;
}
if(inbyte == '\r'){ // end of line
handle end of line a do something with data
}
}
}
Затем используйте atoi(), чтобы преобразовать данные в целые числа и использовать их.
Ответ 4
Это здорово!
Последний комментарий о "thirdvalue = 0" является истинным из кода, приведенного в самом верхнем ответе @dsnettleton. Однако вместо использования "lastIndexOf (',');", код должен просто добавить "+1" в "secondCommaIndex", как @dsnettleton правильно сделал для commaIndex + 1 (отсутствует +1, вероятно, просто опечатка от парня).
Вот обновленный фрагмент кода
int commaIndex = myString.indexOf(',');
int secondCommaIndex = myString.indexOf(',', commaIndex+1);
String firstValue = myString.substring(0, commaIndex);
String secondValue = myString.substring(commaIndex+1, secondCommaIndex);
String thirdValue = myString.substring(secondCommaIndex+1); //To the end of the string
Пример)
Для myString = "1,2,3"
- commaIndex = 1 (поиск по индексу 0, пятно, взятое символом 1, в положение первой запятой)
- secondCommaIndex = 3 (поиск из индекса 2, место, взятое символом 2, в место следующей запятой)
- firstValue читает из индекса 0-1 = "1"
- secondValue читает из индекса 2-3 = "2"
- thirdvalue читает из индекса 4-4 (последнее индексное пятно строки) = "3"
Примечание. Не путайте INDEX с ДЛИНОЙ строки. Длина строки равна 5. Так как String indexOf подсчитывается начиная с 0, последний индекс равен 4.
Причина, по которой просто
String thirdValue = myString.substring(secondCommaIndex);
возвращает 0, когда используется .toInt() - это потому, что thirdValue = ", 3", а не "3", который крепит toInt().
пс. жаль писать все инструкции, но как мех eng, даже мне иногда хотелось бы, чтобы кто-то замалчивал код для меня, особенно консультировался в течение последних 7 лет. Следите за потрясающей публикацией! Помогает людям, как я, много!
Ответ 5
Простейший, я думаю, использует parseInt()
для выполнения этой задачи:
void loop(){
if (Serial.available() > 0){
int r = Serial.parseInt();
int g = Serial.parseInt();
int b = Serial.parseInt();
}
}
делает трюк.
Ответ 6
Для n числа, разделенного строкой
int end;
while((end=str.indexOf(","))!=-1){
String num = str.substring(0,end);
str= asc.substring(end+1,str.length());
Serial.println(num);
}
Ответ 7
@cstrutton - отличное предложение об использовании 'indexOf'. это спасло мне массу времени для моего проекта. Тем не менее, один незначительный указатель,
Я заметил, что третье значение не отображалось (возвращалось как ZERO). Поиграв с ним немного и перейдя через документ в http://arduino.cc/en/Tutorial/StringIndexOf
Я понял, я могу использовать lastIndexOf для последнего значения.
Вот две строки модификаций, которые обеспечивали правильное третье значение.
int lastCommaIndex = myString.lastIndexOf(',');
String thirdValue = myString.substring(lastCommaIndex+1); // To the end of the string
Ответ 8
String myString = "dfsdfgsafhffgsdvbsdvdsvsdvsdsdfdfsdsff|date|recipt|weight|time|date|";
// the setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
int Index1 = myString.indexOf('|');
int Index2 = myString.indexOf('|', Index1+1);
int Index3 = myString.indexOf('|', Index2+1);
int Index4 = myString.indexOf('|', Index3+1);
int Index5 = myString.indexOf('|', Index4+1);
int Index6 = myString.indexOf('|', Index5+1);
String secondValue = myString.substring(Index1+1, Index2);
String thirdValue = myString.substring(Index2+1, Index3);
String fourthValue = myString.substring(Index3+1, Index4);
String fifthValue = myString.substring(Index4+1, Index5);
String firstValue = myString.substring(Index5+1, Index6);
//Serial.println(Index1);
//
Serial.println(secondValue);
Serial.println(thirdValue);
Serial.println(fourthValue);
Serial.println(fifthValue);
Serial.println(firstValue);
delay(14000);
}