[pedido] ayuda con leer datos serial

Hola a todos , queria ver si alguien podria facilitarme el codigo Arduino que haga lo siguiente ya que he leido y no he llegado a entender como hacerlo , (si no es mucho pedir que tambien explique un poco el codigo) :

Necesito recibir por usb al arduino dos valores , X y Y , y luego dependiendo de que valores sean esos realizar cierta accion, el problema es el recibir X y Y y almacenarlos en dos variables diferentes. (los valores se enviarian por el monitor serial del IDE Arduino)

Como haria ? entonces para recibir dos valores y guardarlos en dos varibles diferentes

int x = 0, y =0;

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

void loop()
{
//recibir los dos valores y guardarlos en las dos variables
x = valorrecibido1;
y= valorrecibido2;

realizaraccion(x,y);

}

PD: los valores que recibira X y Y son numeros (ej : 1 100)

A mi se me ocurre la siguiente forma de solucionarlo. Para poder diferenciar si el valor es de x o de y, añadirle el prefijo x ó y al valor, para que así, poderlos diferenciar al llegar por puerto serie, y que se puedan almacenar en variables diferentes.

Este es el código que he hecho para este caso:

int Xarray[3];
int Yarray[3];
int x;
int y;
char XY;

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

void loop() {
  if (Serial.available() > 0) {
    XY = Serial.read();
    if (XY == 'X' || XY == 'x') {
      for (int a = 0; a < 3; a++) {
        Xarray[a] = (Serial.read() - 48);
        delay(10);
      }
    }
    if (XY == 'Y' || XY == 'y') {
      for (int a = 0; a < 3; a++) {
        Yarray[a] = (Serial.read() - 48);
        delay (10);
      }
    }  Serial.flush();
  }
  x = ((Xarray[0] * 100) + (Xarray[1] * 10) + Xarray[2]);
  y = ((Yarray[0] * 100) + (Yarray[1] * 10) + Yarray[2]);
 
 //Esta parte la he hecho para comprobar los valores que se graban. Se puede eliminar todo lo que hay después de esa linea.
  Serial.print ("X=");
  Serial.print (x);
  Serial.print (" Y=");
  Serial.println (y);
  delay (10);
}

De esta forma, por ejemplo, para X=100 y=200, podemos escribir las siguientes combinaciones:

x100y200
y200x100

He hecho el código de forma que el prefijo, puede estar en mayúsculas o en minúsculas, que lo detecta igualmente. Incluso se puede meter primero el valor de x y luego el de y de la siguiente forma:

x100
y200

Este sistema solamente plantea un problema, y es que asume valores de 3 cifras solamente, y que para valores inferiores, hay que llenar de ceros la parte anterior. Por ejemplo, si queremos x=50 y=3 deberemos teclear:

x050y003

Dime si te sirve, y si no, planteamos otra forma de hacerlo.

Creo que este sistema me serviría, solo unas consultad
Esta parte del código no entendí que es lo que hace

x = ((Xarray[0] * 100) + (Xarray[1] * 10) + Xarray[2]);
  y = ((Yarray[0] * 100) + (Yarray[1] * 10) + Yarray[2]);

Y otra consulta ya q no tengo mi placa arduino para probarlo ahora, al final de todo x me quedaría con un valor '050' por ejemplo o seria 'x050' y para enviarle los datos seria todo de una ? O en dos partes?en el monitor serial : Nose si me explico : mando ej: x050y200
O primero mando x050 , envío y después mando y200
En caso de ser en dos partes cuanto tiempo tengo entre q mande el primer valor hasta mandar el segundo

Los valores, los puedes enviar juntos o por separado, como te vaya mejor. No es necesario esperar entre datos, si los envías por separado.

Para explicarte qué hace esa parte final del código, antes tengo que explicarte otra. Después del if, que detecta qué letra es, si X ó Y, viene un bucle for, que guarda el valor de cada número. Como lo que guarda es el valor ASCII, le resto 48, que es el valor ASCII del cero. El bucle for, guarda las centenas en el array[0], las decenas en el array[1] y las unidades en el array[2], de forma que si yo envío el dato x123, me guarda un array con estos valores;

Xarray[3]={1,2,3}

De forma que, llegamos a la parte final del código por la que preguntas, que lo que hace es guardar el valor final en la variable X ó Y según proceda. Para ello, como tenemos la cifra de las centenas en el array Xarray[0], lo multiplicamos por 100, a ello, le sumamos la cifra de las decenas del Xarray[1] multiplicado por 10, y finalmente, sumamos las unidades del Xarray[2], que no hay que multiplicarlas por nada, ya que las unidades son una sola cifra.

Quizá es una forma un poco chapucera de hacerlo todo, pero es la primera que se me ha ocurrido.

Por cierto, me acabo de dar cuenta que el Serial.flush() no hace nada, y se puede eliminar. el código quedaría así:

int Xarray[3];
int Yarray[3];
int x;
int y;
char XY;

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

void loop() {
  if (Serial.available() > 0) {
    XY = Serial.read();
    if (XY == 'X' || XY == 'x') {
      for (int a = 0; a < 3; a++) {
        Xarray[a] = (Serial.read() - 48);
        delay(10);
      }
    }
    if (XY == 'Y' || XY == 'y') {
      for (int a = 0; a < 3; a++) {
        Yarray[a] = (Serial.read() - 48);
        delay (10);
      }
    }
  }
  x = ((Xarray[0] * 100) + (Xarray[1] * 10) + Xarray[2]);
  y = ((Yarray[0] * 100) + (Yarray[1] * 10) + Yarray[2]);

  //Esta parte la he hecho para comprobar los valores que se graban
  Serial.print ("X=");
  Serial.print (x);
  Serial.print (" Y=");
  Serial.println (y);
  delay (10);
}

Ok, entendí la explicación, muchas gracias ni bien pueda lo estaré probando al código y cualquier consulta la posteare

Saludos

Primero muchas gracias por el post....llevaba tiempo intentando resolver el tema!!!! :slight_smile:
ahora solo me falta con python crear la cadena x123y345.....
ya que la orden de envio hacia el Ardu es ser.write('x') pero no puedo poner ("x"+x+"y"+y).....
como tendría que enviar los dos carácteres junto con los dos valores.....quizá creando un string con x e y como letras y luego sus valores? y luego poner ser.write(elstring) ?

muchas gracias.

Marc

solucionado!

coord = "x" + str(x) + "y" + str(y)

gracias.....ahora solo falta resolver lo de las coordenadas de menos de 3 cifras.... :slight_smile:

Marc

.......aunque ya probándolo.....veo que funciona bien unos segundos.....al cabo de un rato empieza a recibir valores que no tienen nada que ver con lo que mando desde el mac... :open_mouth:
alguna idea de porque?

gracias....

es a partir del bucle que hace 25 aprox....empieza a leer mal los datos... :open_mouth:
pero si reseteo el Ardu vuelve a leer bien los datos otra vez veinti tantas veces...

raro, no? quizá algo que ver con la sincronización enviar-leer?

gracias...

Marc

Intenta poniendo una pequeña pausa entre envíos de datos, no vaya a ser un problema de saturación de buffer.

RESPUESTA:

Intenta poniendo una pequeña pausa entre envíos de datos. Podría ser algún problema de saturación de buffer.

gracias,

publico tu respuesta en el forum como bien me has dicho.

Marc