2012-06-25 7 views
10

Tengo que administrar servos desde una computadora.¿Cómo se lee un valor de cadena con un delímetro en Arduino?

Así que tengo que enviar mensajes de administración desde la computadora a Arduino. Necesito administrar el número de servo y la esquina. Estoy pensando en enviar algo como esto: "1; 130" (primer servo y esquina 130, delímetro ";").

¿Hay algún método mejor para lograr esto?

Aquí es mi este código:

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); 
} 

Esto no funciona. ¿Cuál es el problema?

Respuesta

2

Necesita crear un búfer de lectura y calcular dónde comienzan y finalizan sus 2 campos (servo # y esquina). Luego puede leerlos y convertir los caracteres en enteros para usarlos en el resto de su código. Algo como esto debería funcionar (no probado en Arduino, sino en el estándar 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); 
      } 
     } 
+0

su no trabajo .. primer error con itoa .. ya no haya quizá Arduino esta función – yital9

+0

Arduino se basa en C/C++ y enlaces contra AVR Libc. Consulte la referencia aquí para la función http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html – Mangist

+1

Debe incluir en su código fuente – Mangist

4

Este es un gran subtipo que encontré. Esto fue muy útil y espero que sea para ti también.

Este es el método que llama al submarino.

String xval = getValue(myString, ':', 0); 

This is The 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]) : ""; 
} 
+1

¡Funciona muy bien y se puede usar directamente tal cual para Arduinos! – Bort

15
  • Puede utilizar Serial.readString() y Serial.readStringUntil() para analizar cadenas de serie en la Arduino
  • También puede utilizar Serial.parseInt() para leer los valores enteros de serie

Ejemplo Código

int x; 
String str; 

void loop() 
{ 
    if(Serial.available() > 0) 
    { 
     str = Serial.readStringUntil('\n'); 
     x = Serial.parseInt(); 
    } 
} 

El valor para enviar más seria l sería "mi cadena \ n5" y el resultado sería str = "mi cadena" yx = 5

1

Parece que sólo tiene que corregir

foo = ''; >>to>> foo = ""; 

    foo += Serial.read(); >>to>> foo += char(Serial.read()); 

también hice shomething similares .. :

void loop(){ 
    while (myExp == "") { 
    myExp = myReadSerialStr(); 
    delay(100); 
    } 
}  

String myReadSerialStr() { 
    String str = ""; 
    while (Serial.available() > 0) { 
    str += char(Serial.read()); 
    } 
    return str; 
} 
3

la mayoría de las otras respuestas son o muy detallado o muy general, por lo que pensé que le daría un ejemplo de cómo se puede hacer con su ejemplo específico utilizando las librerías de Arduino:

Puede usar el método Serial.readStringUntil para leer hasta su delimitador desde el puerto Serial.

Y a continuación, utilice toInt para convertir la cadena en un número entero.

lo tanto, para un ejemplo completo:

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! 
    } 
} 

Por supuesto podemos simplificar esto un poco:

void loop() 
{ 
    if (Serial.available() > 0) 
    { 
     int servo = Serial.readStringUntil(';').toInt(); 
     int corner = Serial.readStringUntil('\n').toInt(); 

     // Do something awesome! 
    } 
} 
Cuestiones relacionadas