Para aquellos desarrolladores que utilizan el Eclipse Indigo como herramienta y entorno de programación, les cuento que he probado la librería de Antony en esta plataforma para encender y apagar el Led del pin 13 de la placa Arduino Uno. No obstante lo que he realizado es una comunicación bidireccional de manera que cuando Arduino encienda o apague dicho LED, esta envíe un mensaje de confirmación a la interface Java.
Por otra parte en envío de datos desde la interface utiliza la función sendByte, que a diferencia de posts anteriores lo hace mediante sendData. La diferencia es que sendBye tiene la posibilidad de enviar enteros entre 0 y 255.
Para conocer más de esta librería se encuentran los post anteriores, incluso navegando dentro de los Archivos de la API encontraran la implementación de dichas funciones y sus diferencias, para ello deben utilizar un editor de texto de su agrado para leer los archivos.java.
En principio no debería haber inconvenientes en cuanto al uso de la librería dado que NetBeans es también una plataforma en Java , aunque siempre encontramos alguna que otra diferencia en cuanto a las implementaciones.
El Eclipse que utilizo es el Indigo, ya que posee la ventaja de disponer del WindowBuider que nos permite disponer de todas las herramientas y objetos Swing para diseñar una interface gráfica.
El sitio para el Eclipse Indigo lo pueden encontrar en su sitio oficial.
La intención no es hacer un aporte sobre Eclipse, y entiendo que quienes lo utilicen ya están familiarizados con este entorno.
Lo primero que sucede al ejecutar Eclipse es preguntarnos el WorkSpace a utilizar. Este es una carpeta donde ustedes realizan sus proyectos, incluso pueden tener diferentes WorkSpace para distintos tipos de proyecto. Lo pueden crear en cualquier Disco, C, D, E etc, pero es conveniente hacerlo en la carpeta donde tengan el Eclipse y su archivo de ejecución.
Preparando el proyecto y la librería
- File – new – JavaProyect , le damos el nombre Ejemplo LEDD2.7
Crearemos el proyecto LED2.7 y una vez creado debe lucir como esto:
Vamos src – new – Others – WindowsBuilder – SwingDesigner y escogemos Jframe
Y en el campo Name, le damos el nombre a nuestra Clase , por ejemplo LED.
Cabe aclarar que en este paso estamos creando la Clase “Led” que va a extender a Jframe y que Eclipse va a preconstruir el marco inicial para nuestra interface, y es allí, donde arrastraremos los componentes u Objetos que necesitemos, botones, campos de texto, Labels, etc.
Ahora en la carpeta src, debemos ver la clase creada Led:
Podemos observar como Eclipse inserta el método estático Main() que es el encargado de ejecutar la aplicación. Dentro de este método se crea el objeto frame , como instancia de la clase creada Led:
LED frame = new LED();
Incluso podríamos agregar un título al frame que se va a visualizar:
frame.setTitle(“Probando librería arduino 2.7”);
frame.setVisible(true); hará visible dicho marco.
Lo que hago ahora es una forma de trabajo que considero es más ordenada. Debemos importar la librería de Arduino, pero previo a ello creamos una carpeta dentro del proyecto llamada por ejemplo Librerias, con el objeto de colocar allí los archivos .jar necesarios de la librería. De esta manera en cada proyecto sabremos las librerías que utiliza, es a mi entender , más ordenado.
Hay varias maneras de crear esta carpeta Librería, se puede hacer manualmente entrando a la carpeta del proyecto y crearla como cualquier carpeta. La otra manera es hacerlo desde Eclipse.
Desde Eclipse nos posicionamos en src – new – SourceFolder , y le damos el nombre Librerias.
Paso siguiente, debemos descargar la librería PanamaHitek_Arduino.jar.
La guardamos donde nos plazca. Una vez descargada la copiamos y la pegamos dentro de la carpeta Librerías ya creada. Para esto posicionamos sobre la carpeta Librerias y Click derecho – Paste(pegar).
Lo que haremos ahora es Importar la librería, ya que el hecho de haber creado esta carpeta no implica haberla importado, recordar que es solo a los efectos de orden.
Para importar nos posicionamos sobre el Proyecto LEDD2.7 – Click derecho – properties:
Vamos a JavaBuiltPath . Aquí hay varias opciones , entre ellas Add External Jar y Add Jar.
Como la librería está en una carpeta local que hemos creada hacemos Add Jar.
Buscamos la carpeta Librerías y seleccionamos PanamaHitek_Arduino v2.7.jar y le decimos OK.
Para asegurarse que la librería será encontrada debemos decirle a Eclipse la ruta Nativa, para este fin, vamos a desplegar la librería importada sobre el panel, para esto, si nos posicionamos sobre la librería, se observa un banner de expansión.
Vamos a Native Library Location(None) , aparece None porque no está configurado aún.
Vamos a Edit y luego a WorkSpace: y seleccionamos la carpeta Librerías que es donde está la librería de Arduino. Y le decimos OK.
El código
Hasta aquí ya está todo preparado , no hace falta nada más , no es necesario traer la librería RXTXComm.jar , como tampoco instalar los Drivers. La versión 2.7 lo hace automáticamente y crea los accesos a los drivers RxTxserial y RxTxParallel.dll(este último innecesario para esta aplicación).
Al ejecutarse el proyecto pueden ir al disco “C” y va a estar creada una carpeta con dichos Drivers
C:\JavaRxTx y dentro de ella dos subcarpetas para W32 y W64 bits.
Ahora vamos a la aplicación en sí:
Eclipse con el WindowsBuilder, permite ver dos vistas del proyecto:
- La solapa Source: permite ver el código.
- La solapa Design: la interface gráfica .
Vamos a la solapa DESIGN y lo primero que vamos a hacer es definir el Layout de los componentes. Hay varios tipos de Layout pero el más flexible es el AbsoluteLayout que nos va a permitir posicionar nuestros componentes donde queramos.
Para esto vamos a la interface gráfica dentro del Form que está vacío, sin componentes, y hacemos click derecho y seleccionamos SetLayout y luego Absolute Layout. El componente contentPane se alija dentro del Frame y es que va a su vez, a contener a los objetos con un Layout Absoluto.
Ahora podemos arrastrar nuestros componentes:
En este caso les voy a mostrar cómo queda la interface ya creada para no extender el tutorial:
A los botones debemos cambiarle la propiedad Name : OK y OFF también podemos darle estilos a los botones, colores, etc.
Es importante que los componentes se definan como globales , es decir variables de clase globales que se definen al inicio de la clase LED.java:
1 2 3 4 5 |
private JPanel contentPane; private JButton btnOn; private JButton btnOff; private static JPanel panel; private static JLabel lblEstado; |
Para hacer que estas variables de clase sean globales y accesibles desde cualquier lugar del código nos posicionamos sobre el componente, sobre el panel de navegación de las propiedades del objeto y hacemos click en el ícono que permite pasar de variable LOCAL a GLOBAL y viceversa es el que tiene una flecha apuntando hacia arriba con cuadro rojo a la derecha y verde superior
Para que no haya errores vamos a tener que ir importando librerías en la medida que se vayan solicitando.
Lo común es que al ir generando código, java , en caso de errores nos va indicando opciones para eliminarlos, y la mayoría se resuelven importando las librerías.
Creamos ahora una instancia de la Clase Ardunio, es decir un Objeto:
1 2 3 4 5 6 7 |
public class LED extends JFrame { // Nuestra CLASE private JPanel contentPane; private JButton btnOn; private JButton btnOff; private static JPanel panel; private static JLabel lblEstado; static PanamaHitek_Arduino ardu = new PanamaHitek_Arduino(); // Creamos Objeto ardu |
Para poder escuchar los eventos del puerto vamos a crear un objeto escucha llamado evento que va a ser el encargado de escuchar la recepción de datos del puerto. Este objeto es static dado que habrá un solo puerto de comunicación serie conectado a Arduino, es decir que todos los objetos creados dentro de la aplicación si lo utilizan, serán único, vale decir que no tiene sentido instanciar más de una vez a la clase SerialPortEventListener ya que físicamente es un solo puerto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class LED extends JFrame { private JPanel contentPane; private JButton btnOn; private JButton btnOff; private static JPanel panel; private static JLabel lblEstado; static PanamaHitek_Arduino ardu = new PanamaHitek_Arduino(); // Creamos Objeto ardu static SerialPortEventListener evento = new SerialPortEventListener() { // Objeto evento public void serialEvent(SerialPortEvent ev) { } }; |
Luego lo que hacemos es ir al constructor de la Clase LED, y creamos la conexión. Al instanciar a la Clase LED , como vimos en el método Main, se llama al constructor, que es el método que construye el objeto “frame” ( ver Main).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public LED() { // CONSTRUCTOR DE LA CLASE try { ardu.arduinoRXTX("COM5", 9600, evento); // Creamos la conexión } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } . // sigue el código, pero solo muestro esta parte . . } |
En mi caso uso el COM5, pero cada uno debe ver cual es el puerto conectado a Arduino. Ver Post anteriores.
Notar que la conexión lleva como argumento al objeto evento. Lo demás es conocido, el puerto y la velocidad ( misma que Arduino)
Volvemos a nuestra Clase donde creamos el objeto evento para ver como queda la recepción desde Arduino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
static SerialPortEventListener evento = new SerialPortEventListener() { public void serialEvent(SerialPortEvent ev) { if(ardu.isMessageAvailable()==true){ // Si hay datos disponibles ??? String mensage= ardu.printMessage(); // Creamos variable mensaje y le asignamos lo recibido System.out.println(mensage); // Imprimimos por CONSOLA JAVA if(mensage.equals("encendido")){ panel.setBackground(new Color(0, 255, 0)); // PANEL VERDE lblEstado.setText("ARDUINO DICE: *** led encendido"); } if(mensage.equals("apagado")){ panel.setBackground(new Color(255, 0, 0)); // PANEL ROJ0 lblEstado.setText("ARDUINO DICE: *** led apagado"); } } } }; |
Arduino al encender o apagar el Led confirma con un mensaje “encendido” o “apagado” y de acuerdo a este se actualiza el color del JPanel y el mensaje en el JLabel.
Envío de los comandos encender y apagar:
La fracción de código importante es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
btnOn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { try { ardu.sendByte(10); // envia entero 10 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // envia un Byte desde 0 a 255 } }); btnOff.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { ardu.sendByte(78); // envia entero 78 } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); |
Se utilizó el método sendByte para enviar enteros.
Codigo completo:
- Código Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JButton; import javax.swing.border.LineBorder; import java.awt.Color; import javax.swing.UIManager; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JLabel; import panamahitek.Arduino.PanamaHitek_Arduino; import java.awt.Font; import javax.swing.border.CompoundBorder; import javax.swing.border.MatteBorder; import java.awt.Cursor; public class LED extends JFrame { private JPanel contentPane; private JButton btnOn; private JButton btnOff; private static JPanel panel; private static JLabel lblEstado; static PanamaHitek_Arduino ardu = new PanamaHitek_Arduino(); // Creamos Objeto ardu static SerialPortEventListener evento = new SerialPortEventListener() { @Override public void serialEvent(SerialPortEvent ev) { if(ardu.isMessageAvailable()==true){ String mensage= ardu.printMessage(); System.out.println(mensage); if(mensage.equals("encendido")){ panel.setBackground(new Color(0, 255, 0)); lblEstado.setText("ARDUINO DICE: *** led encendido"); } if(mensage.equals("apagado")){ panel.setBackground(new Color(255, 0, 0)); lblEstado.setText("ARDUINO DICE: *** led apagado"); } } } }; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Led3 frame = new LED(); frame.setVisible(true); frame.setTitle("Usando Librería 2.7 en Eclipse Indigo"); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public LED() { //ardu.ArduinoRXTX("COM5", 2000, 9600, evento); try { ardu.arduinoRXTX("COM5", 9600, evento); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 380, 225); contentPane = new JPanel(); contentPane.setBackground(new Color(245, 222, 179)); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); btnOn = new JButton("ON"); btnOn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); btnOn.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 255))); btnOn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { try { ardu.sendByte(10); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // envia un Byte desde 0 a 255 } }); btnOn.setBackground(new Color(216, 191, 216)); btnOn.setFont(UIManager.getFont("Button.font")); btnOn.setForeground(new Color(0, 0, 0)); btnOn.setBounds(37, 22, 89, 23); contentPane.add(btnOn); btnOff = new JButton("OFF"); btnOff.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); btnOff.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { ardu.sendByte(78); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); btnOff.setForeground(Color.BLACK); btnOff.setFont(UIManager.getFont("Button.font")); btnOff.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 255))); btnOff.setBackground(new Color(216, 191, 216)); btnOff.setBounds(37, 104, 89, 23); contentPane.add(btnOff); panel = new JPanel(); panel.setBackground(new Color(255, 0, 0)); panel.setBounds(205, 58, 35, 23); contentPane.add(panel); lblEstado = new JLabel("ARDUINO DICE:"); lblEstado.setFont(new Font("Tahoma", Font.BOLD, 11)); lblEstado.setBounds(37, 150, 317, 26); contentPane.add(lblEstado); } } |
- Código Arduino
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/* Reading a serial ASCII-encoded string */ // pins for the LEDs: const int ledPin = 13; byte entrada; void setup() { // initialize serial: Serial.begin(9600); // make the pins outputs: pinMode(ledPin, OUTPUT); } void loop() { while (Serial.available() > 0) { // look for the next valid integer in the incoming serial stream: entrada = Serial.read(); Serial.println(entrada); if (entrada == 10) { // print the three numbers in one string as hexadecimal: digitalWrite(ledPin, HIGH); Serial.println("encendido"); } if (entrada==78) { // print the three numbers in one string as hexadecimal: digitalWrite(ledPin, LOW); Serial.println("apagado"); } } } |
Esto es todo por ahora.