Как прочитать строковое значение с разделителем на Arduino?
Мне нужно управлять сервомашинами с компьютера.
Поэтому мне нужно отправить управляющие сообщения с компьютера на Arduino. Мне нужно управлять количеством сервопривода и угла. Я думаю о том, чтобы отправить что-то вроде этого: "1; 130" (первый серво и угол 130, делиметр ";" ).
Есть ли лучшие методы для этого?
Вот мой код:
String foo = "";
void setup(){
Serial.begin(9600);
}
void loop(){
readSignalFromComp();
}
void readSignalFromComp() {
if (Serial.available() > 0)
foo = '';
while (Serial.available() > 0){
foo += Serial.read();
}
if (!foo.equals(""))
Serial.print(foo);
}
Это не работает. В чем проблема?
Ответы
Ответ 1
- Вы можете использовать Serial.readString() и Serial.readStringUntil() для анализа строк из Serial на Arduino
- Вы также можете использовать Serial.parseInt() для чтения целочисленных значений из последовательного
Пример кода
int x;
String str;
void loop()
{
if(Serial.available() > 0)
{
str = Serial.readStringUntil('\n');
x = Serial.parseInt();
}
}
Значение для отправки через последовательный будет "моя строка \n5", а результат будет str = "моя строка" и х = 5
Примечание. Serial.available() наследуется от служебного класса Stream. https://www.arduino.cc/reference/en/language/functions/communication/serial/available/
Ответ 2
Это отличный суб, который я нашел. Это было очень полезно, и я надеюсь, что это будет и для вас.
Это метод, который вызывает sub.
String xval = getValue(myString, ':', 0);
Это Sub!
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {
0, -1 };
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
Ответ 3
Большинство других ответов либо очень подробные, либо очень общие, поэтому я подумал, что приведу пример того, как это можно сделать с вашим конкретным примером, используя библиотеки Arduino:
Вы можете использовать метод Serial.readStringUntil для чтения до вашего разделителя с порта Serial
.
И затем используйте toInt, чтобы преобразовать строку в целое число.
Итак, для полного примера:
void loop()
{
if (Serial.available() > 0)
{
// First read the string until the ';' in your example
// "1;130" this would read the "1" as a String
String servo_str = Serial.readStringUntil(';');
// But since we want it as an integer we parse it.
int servo = servo_str.toInt();
// We now have "130\n" left in the Serial buffer, so we read that.
// The end of line character '\n' or '\r\n' is sent over the serial
// terminal to signify the end of line, so we can read the
// remaining buffer until we find that.
String corner_str = Serial.readStringUntil('\n');
// And again parse that as an int.
int corner = corner_str.toInt();
// Do something awesome!
}
}
Конечно, мы можем немного упростить это:
void loop()
{
if (Serial.available() > 0)
{
int servo = Serial.readStringUntil(';').toInt();
int corner = Serial.readStringUntil('\n').toInt();
// Do something awesome!
}
}
Ответ 4
Вам нужно построить буфер чтения и вычислить, где начинаются и заканчиваются ваши 2 поля (серво и #). Затем вы можете прочитать их и преобразовать символы в целые числа, чтобы использовать их в остальной части вашего кода. Что-то вроде этого должно работать (не проверено на Arduino, но стандартно C):
void loop()
{
int pos = 0; // position in read buffer
int servoNumber = 0; // your first field of message
int corner = 0; // second field of message
int cornerStartPos = 0; // starting offset of corner in string
char buffer[32];
// send data only when you receive data:
while (Serial.available() > 0)
{
// read the incoming byte:
char inByte = Serial.read();
// add to our read buffer
buffer[pos++] = inByte;
// check for delimiter
if (itoa(inByte) == ';')
{
cornerStartPos = pos;
buffer[pos-1] = 0;
servoNumber = atoi(buffer);
printf("Servo num: %d", servoNumber);
}
}
else
{
buffer[pos++] = 0; // delimit
corner = atoi((char*)(buffer+cornerStartPos));
printf("Corner: %d", corner);
}
}
Ответ 5
Похоже, вам просто нужно исправить
foo = ''; >>to>> foo = "";
foo += Serial.read(); >>to>> foo += char(Serial.read());
Я тоже сделал кое-что похоже.:
void loop(){
while (myExp == "") {
myExp = myReadSerialStr();
delay(100);
}
}
String myReadSerialStr() {
String str = "";
while (Serial.available () > 0) {
str += char(Serial.read ());
}
return str;
}