2011-05-18 27 views
9

Estoy trabajando en un proyecto Arduino, y estoy interactuando con una secuencia de comandos de Python debido a limitaciones de memoria. En el lado de Python, tengo una matriz bidimensional que contiene los respectivos valores x, y para las coordenadas, y en esta lista hay 26000 pares de coordenadas. Por lo tanto, a fin de aclarar la estructura de datos para todos ustedes, pathlist[0][0], devolvería el valor X de la primera coordenada de mi lista. Realizar diferentes operaciones, etc. en esta lista en Python no plantea problemas. Sin embargo, cuando estoy teniendo problemas, envío estos valores a Arduino en serie, de una manera que sea útil.Comunicación en serie de Python

Debido a la naturaleza de la comunicación serial (al menos creo que este es el caso) debo enviar cada entero como una cadena, y solo un dígito a la vez. Entonces, un número como 345 sería enviado como 3 caracteres individuales, siendo por supuesto, 3, 4, luego 5.

Lo que estoy luchando es encontrar la manera de reconstruir esos enteros en el Arduino.

Cada vez que envíe un valor superior, que está recibiendo los datos y la salida de él de este modo:

//Python is sending over the number '25' 
    2ÿÿ52 
    //Python is sending the number 431. 
    4ÿÿ321ÿÿÿ2 

El código de Arduino es:

String str; 
int ds = 4; 

void setup() { 
    Serial.begin(9600); 
} 

void loop(){ 
    if (Serial.available()>0) { 
     for (int i=0; i<4; i=i+1) { 
      char d= Serial.read(); 
      str.concat(d); 
     } 

     char t[str.length()+1]; 
     str.toCharArray(t, (sizeof(t))); 
     int intdata = atoi(t); 
     Serial.print(intdata); 
    } 
} 

Y el código Python se ve así:

import serial 

s = serial.Serial(port='/dev/tty.usbmodemfd131', baudrate=9600) 

s.write(str(25)) 

Estoy casi seguro de que el problema no proviene del método de salida (Serial.print), ya que cuando declaro otro int, formatea bien en el resultado, entonces asumo que el problema radica en cómo se construye la variable intdata.

Una cosa de la nota que puede ayudar a diagnosticar este problema es que si cambio Serial.print(intdata) a Serial.print(intdata+5) mi resultado es 2ÿÿ57, donde esperaría 30 (25 + 5). Este 7 está presente independientemente de la entrada. Por ejemplo, yo podría escribir 271 a la serie y mi resultado se vería de la siguiente manera:

//For input 271. 
2ÿÿ771ÿÿÿ7 

Me parece que Arduino se CHUNKING los valores en pares de dos y añadiendo la longitud hasta el final. No puedo entender por qué sucedería eso.

También me parece que el ÿ se está agregando en el ciclo for. Lo que significa que se agregan porque no se envía nada en ese momento. Pero incluso arreglando eso agregando otro if(Serial.available()>0) condicional, el resultado todavía no se trata como un entero.

Además, ¿sería apropiado usar Pickle aquí? ¿Qué estoy haciendo mal?

+0

¿Por qué es esto etiquetado 'java'? – NPE

+0

@aix Bueno, pensé que Arduino estaba basado fuera de Java y, por lo tanto, el conocimiento de Java sería aplicable. Con mucho gusto lo cambiaré si me equivoco: D – danem

+1

Es solo el IDE de Arduino el que está escrito en Java. Su código que se ejecuta en el Arduino está en C, por lo que Java no es relevante para la pregunta. – NPE

Respuesta

5

Debe esperar un poco para que lleguen los datos en serie.

código de Arduino debería ser:

if (Serial.available()){ 
    delay(100); // Wait for all data. 
    while (Serial.available()) { 
     char d = Serial.read(); 
     str.concat(d); 
    } 
} 

También usted tiene que limpiar su cadena antes de volver a usarlo.

[Editar]

me olvidó mencionar y == == -1 255 Serial.read() que significa que está diciendo que no puede leer nada.

+1

Gah. Siento que esto fue una publicación innecesariamente compleja por un problema simple. Heh, me siento tonto. Bueno, funciona! Muchas gracias, realmente lo aprecio. – danem

+0

Un problema que me estoy encontrando es que cuando trato de usar esto en mi lista gigante de coordenadas, falla. Por ejemplo, si solo envié los primeros 40 xey vals, obtengo el resultado '-5062'. ¿Lo estoy sobrecargando con la entrada o algo así? – danem

+0

Tuve este problema una vez. Creo que fue porque cuando envías un montón de datos, el Arduino podría no haber terminado el ciclo (fíjate que he agregado 100 ms adicionales al tiempo de procesamiento mediante el retraso de llamadas). Una solución es agregar un carácter de línea final y procesar el ciclo hasta que llegue. – JBernardo

5

que cambiaría la comunicación a fin de pitón envía saltos de línea entre los números, por lo que no son tan dependientes del tiempo:

s.write(str(25)+'\n') 

y luego en el lado receptor:

void loop(){ 
    while (Serial.available() > 0) { 
     char d = Serial.read(); 
     if (d == '\n') { 
      char t[str.length()+1]; 
      str.toCharArray(t, (sizeof(t))); 
      int intdata = atoi(t); 
      Serial.print(intdata); 
      str = String(); 
     } 
     else { 
      str.concat(d); 
     } 
    } 
} 
Cuestiones relacionadas