Comunicación Serial: Enviando datos de Arduino a Java

36
4625
La información suministrada en este post es considerada por mi persona como obsoleta debido a que fue publicada antes de mi librería Arduino para Java. Recomiendo visitar el siguiente post donde se explica el uso de la misma y donde es muy fácil comunicar Arduino con Java y vice versa.

***

Hola amigos. En las últimas semanas he estado escribiendo mucho acerca de Arduino, de Java y de como podemos utilizar ambas plataformas para realizar grandes proyectos. Empecé escribiendo como establecer Comunicación Serial con Arduino. Luego escribí como enviar datos de Java a Arduino a través de los métodos ArduinoConnection() y EnviarDatos().

Ahora es tiempo de aprender como recibir datos en Java desde Arduino. Para ello utilizaremos un método similar a EnviarDatos(): RecibirDatos().

Para poder utilizar este método necesitamos modificar nuestra función ArduinoConnection() y declarar algunas variables.

Los datos que enviamos de Arduino a Java se envían a través de una variable OutputStream llamada Output. Ahora declararemos una variable del tipo InputStream llamada Input.

private InputStream Input;

Resumiendo, las variables que necesitamos utilizar para comunicar Arduino y Java, y vice versa, son las siguientes:

 

Sin título

Ahora necesitamos inicializar la variable Input. Esto se hace en la función ArduinoConnection() donde ya existe una línea que inicializa la variable Output.

 

Como vemos, se prepara a la variable Input de la misma manera que a la variable Output. Hemos agregado 2 líneas más a nuestra función ArduinoConnection():

Esto permite que se genere un evento cada vez que Arduino envíe datos a Java. Para poder que esto funcione es necesario que implementemos la interfaz SerialPortEventListener de la misma manera que implementamos la interfaz Runnable cuando utilizamos los Java Threads.

Sin título

Por último necesitamos agregar un método en donde se establezca las acciones que se harán cuando ocurra un SerialPortEvent.

 

Por último agregamos RecibirDatos():

Con estas variables y estos métodos podemos lograr lo que queremos. Ahora es tiempo de probar si funciona o no.

Yo agregué los elementos necesarios al ejemplo Blink que ya hicimos:

Ahora vamos a Arduino y escribimos lo siguiente:

Con estos cambios estamos listos para ver como trabaja nuestro código. Lo que haremos es enviar el valor de una variable, en este caso, count, de Arduino a Java, con la salvedad de que cada segundo se aumentará el valor de count en 1 unidad.

Utilizamos Serial.print para enviar el mensaje. Si utilizamos println enviaremos el mensaje con un salto de renglón. Si utilizamos Serial.write, entonces no enviaremos el mensaje en ASCII sino como bits. El problema con esto es que es un bus de 8 bits, por lo que no podremos enviar valores más arriba del 255, ya que 2 elevado a la octava potencia es 256 y el bus solo admite 8 bits, del 0 al 255.

Aquí vemos la demostración:

Como podemos observar los datos se envían 1 a 1, es decir, caracter a caracter.

Espero sus comentarios. Saludos.

  • Pentagrama

    Hola, tengo una duda con respecto a como muestra los datos, al ejecutar el código java y mando datos para probarlo con una terminal, pero los datos que muestra no es el que mando, por ejemplo si le mando un 1 me muestra 49 y si es 2 muestra 50 y así con todos, incluso si le mando un 0 me muestra 48, alguna idea de porque pasa eso o hay algo de lo que no me entero o si alguien mas me podría ayudar se los agradecería. Saludos y gracias

    • Antony García González

      Verifica la tabla de datos ASCII

      • Pentagrama

        Ya solucione esa parte, pero ahora el problema esta en los datos que se reciben de uno en uno; existe alguna forma de que los datos sean por cadena; osea que si se manda 10 sea 10 y no 1 y 0. O si es la palabra hola sea hola y no h,o,l,a.

        • Antony García González

          Recibir datos en donde? Arduino o Java? Te recomiendo postear tu situación en el foro –> http://panamahitek.com/foro/

          • Pentagrama

            En java; al final del tutorial mencionan que “los datos se envían 1 a 1, es decir, caracter a caracter”; y efectivamente asi pasa, entonces mi duda es como hacer para que no sea de uno en uno, sino que se lea todo lo enviado; e visto que usan el buffer pero no me queda claro

          • Antony García González

            Para eso existe el método printMessage y isMessageAvailable()

  • Luis Eduardo Molina

    gracias yo resolvi antes de ver el pos no estaba tomando el contador en el tiempo de ejecucion

  • Luis Eduardo Molina

    estoy usando su libreria y parte de codigo nuevo en netbeans y pongo 2 potencometros que se vea la cantida de giro o sensor de humedad en un jtexfile solo dos . en el siglo de este codigo

    l void serialEvent(SerialPortEvent spe) {
    if (Arduino.MessageAvailable()){
    if(Slot== 1){
    Slot= 2;
    if (lectura > 1) {lectura++; pote1= Arduino.PrintMessage();}

    } else if (Slot== 2){ Slot= 1;lectura++;pote2 = Arduino.PrintMessage();

    txtarduinovalue = new txtarduino();
    txtarduino.setText(pote1);

    txtarduino1value = new txtarduino1();
    txtarduino1.setText(pote2 );
    pero no me acepta un tercero quiero poner en ese mismo siglo 6 en total . gracias por su ayuda

  • Ezekiel Kardenas

    amigo eso lo quiero hacer pero al reves que de java mande a arduino si puedes subir algun codigo te lo agradeceria

  • Hector

    hola muy buen aporte, estoy probando la libreria arduino y lo que intento es mostrar los datos leidos desde el arduino y en lugar de graficarlo me muestre el valor en un textField pero no logro hacerlo no se si tengas idea como puedo resolver esto

    este es lo que hago:

    jTextField1.setText(Arduino.PrintMessage());

    y solo me muestra la leyenda que no hay datos disponibles pero si me grafica los datos

    • Lo que sucede es que al graficar estas enviando el valor de la variable a las gráficas y el textfield trata de leer el siguiente valor en la fila del puerto serie, el cual es un valor nulo. Lo que tienes que hacer es leer la variable, luego en un proceso separado graficar y enviar al jTextField. Una vez leido el valor que se recibe por medio de printMessage, el mismo no puede usarse para nada mas, a menos que uses una variable que lo contenga y a partir de la misma desencadenar los demás procesos.

      Saludos.

  • Jsanchez

    Me aparece cuando intento enviar serial con TX después de haber iniciado la conexión. Inicio la conexión y luego intento inicializarla en otra parte y me aparece ese error.

  • Jsanchez

    Me aparece un error cuando corro el programa “Arduino.arduino” a que se debe y como lo corrijo gracias.

  • Jose

    podrias subir el codigo a algun servidor para descargarlo??

  • Irving

    Disculpa amigo, no me funciona. serialPort.addEventListener(this); me lo marca como error. A qué se debe??Saludos.

  • Cristian Rincon Bosigas

    Las imágenes son de gran ayuda para entender el proceso que se realizo, no se si están dañadas o es problema del pc pero no logro verlas. No entiendo muy bien la parte de los hilos, ¿estos son obligatorios?¿como van a funcionar en la aplicación? Le agradecería su colaboración. Gracias

  • aitor

    Hola:

    Tienes algún otr tutorial en el que se reciban datos de manera ininterrumpida desde arduino?. Por ejemplo con un botón de start y otro de parada para detener.

  • Daniel

    hola amigo!! primero que nada quiero agradecerte por este gran aporte!!!
    y quisiera hacerte una pregunta, lo que pasa que estoy haciendo un programa en java y arduino, pero a la ora de enviar un numero como 10, 20 30 etc,
    en java se muestra:
    1
    0
    hay alguna forma de que me imprima el 10??

    • No. Necesitas hacer lectura dígito a dígito. Yo por ejemplo envío 3 dígitos y en Arduino los leo de la siguiente manera:
      int c; int d; int u; int num;
      c=Serial.read();
      delay(10)
      d=Serial.read()
      delay(10)
      u=Serial.read();
      num=(100*c)+(100*d)+u;

      Ahí está

  • Yahir Nieto

    Primero que nada muchas gracias por todos los tutoriales, han sido de muchisima ayuda…
    una duda, al momento de implementar SerialPortEventListener, quitamos el Runnable y ahora ya no me sirven los hilos…
    Que puedo hacer??

    • Puedes implementar Runnable y SerialPortEventListener al mismo tiempo. Solo tienes que agregarlo arriba y te dejará usar hilos. Si no me equivoco, colocas implements SerialPortEventListener, Runnable

    • Yahir Nieto

      Ya lo pude solucionar, todo funciono de maravilla!
      Muchas gracias!!

  • Willy

    interesante el aporte, probare el código, saludos

  • Moises Jaber

    Disculpa no entra al EventListener

    • ¿Podrías ser un poco más específico en cuanto al error que se está presentando?