Voy a mostrarles a continuación un sencillo ejemplo de interacción y comunicación vía Serial con una placa Arduino (one). Tengo aproximadamente un mes jugando con mi arduino one y confirmo lo que me habían contado, «es sencillamente emocionante ver que haces encender y apagar un LED», como me comento una amiga «es un juego para adultos», no me queda mas que reirme y aceptar que en mi caso es así y disfruto del poco tiempo que he podido dedicarme a hacer ejemplos.
Ha sido de esta manera, haciendo ejemplos del libro Getting Started with Arduino y leyendo por internet que me nació el gusanillo (curiosidad) por hacer un sencillo ejemplo pero donde en vez de comunicar los lenguajes Processing y Arduino, lo hiciera usando Java, C o C++ (estos 2 últimos espero poder hacerlos y de ser posible publicarlos mas adelante). ¿Con qué finalidad? además de aprender, sencillamente poder gozar de las bondades y herramientas que nos ofrece el trabajar con los lenguajes anteriormente mencionados.
Ahora si vamos al grano, primero indicare los componentes utilizados:
- 1 Placa arduino one
- 1 bombillo LED
- 1 cable usb AM/BM (para cargar programa arduino)
La conexión es muy sencilla, consiste únicamente de colocar el LED (la pata mas larga) en el pin 13 y la otra pata en GND (tierra).
Una vez, hecho esto pasamos a hacer el sketch Arduino.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const int LED = 13; //LED connected to digital pin 13 int inByte = 0; void setup(){ Serial.begin(9600); //Open the serial port pinMode(LED, OUTPUT); //Set the digital pin as output } void loop(){ if(Serial.available() > 0){ inByte = Serial.read(); //read the incoming byte if(inByte == '1') digitalWrite(LED, HIGH); //turn the LED on else digitalWrite(LED, LOW); //turn the LED off } } |
Compilamos el sketch y lo cargamos en la placa Arduino. Cargado el sketch, procedemos entonces con el programa Java. Para poder conectarnos con la placa arduino será necesario que tengamos la biblioteca RXTX (una biblioteca semejante a la Java Communications API extension), esta biblioteca posee los jar necesarios para poder establecer comunicación vía serial con la placa. La instalación dependerá del sistema operativo que utilicen, así que les recomiendo seguir los pasos de instalación indicados en el fichero README de la versión de la biblioteca (así sea la versión con los binarios o los fuentes) que se descarguen, o en el sitio web en la sección de instalación.
Una vez descargada e instalada la biblioteca RXTX, seguimos con nuestro programa Java, que consistirá unicamente de una interfaz grafica sencilla (un JFrame) con 2 botones para encender o apagar el LED.
Aqui les dejo el código fuente 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 147 148 149 150 151 152 153 154 155 156 157 158 |
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; import gnu.io.CommPortIdentifier; import gnu.io.SerialPort; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; public class JPanelTurnOnOffLED extends JPanel implements ActionListener { private static final String ON = "On"; private static final String OFF = "Off"; private static final String TURN_ON = "1"; private static final String TURN_OFF = "0"; private JButton switchOnButton; private JButton switchOffButton; private JLabel label; private JFrame frame; /** The output stream to the port */ private OutputStream output = null; SerialPort serialPort; private final String PORT_NAME = "/dev/cu.usbmodem1d11"; /** Milliseconds to block while waiting for port open */ private static final int TIME_OUT = 2000; /** Default bits per second for COM port. */ private static final int DATA_RATE = 9600; public JPanelTurnOnOffLED(){ switchOnButton = new JButton(ON); switchOffButton = new JButton(OFF); switchOffButton.setEnabled(false); label = new JLabel("Turn On/Off LED:"); switchOnButton.addActionListener(this); switchOffButton.addActionListener(this); add(label); add(switchOnButton); add(switchOffButton); initializeArduinoConnection(); } public void initializeArduinoConnection(){ CommPortIdentifier portId = null; Enumeration portEnum = CommPortIdentifier. getPortIdentifiers(); // iterate through, looking for the port while (portEnum.hasMoreElements()) { CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement(); if (PORT_NAME.equals(currPortId.getName())) { portId = currPortId; break; } } if (portId == null) { showError("Could not find COM port."); System.exit(ERROR); return; } try { // open serial port, and use class name for the appName. serialPort = (SerialPort) portId.open(this.getClass() .getName(), TIME_OUT); // set port parameters serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); // open the streams output = serialPort.getOutputStream(); } catch (Exception e) { showError(e.getMessage()); System.exit(ERROR); } } public static void createAndShowGUI(){ JFrame frame = new JFrame("Turn On/Off LED example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JPanelTurnOnOffLED newContentPane = new JPanelTurnOnOffLED(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String args[]){ javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } @Override public void actionPerformed(ActionEvent e) { if(ON.equals(e.getActionCommand())){ switchOnButton.setEnabled(false); switchOffButton.setEnabled(true); sendData(TURN_ON); }else{ switchOnButton.setEnabled(true); switchOffButton.setEnabled(false); sendData(TURN_OFF); } } private void sendData(String data){ try { output.write(data.getBytes()); } catch (IOException e) { showError("Error sending data"); System.exit(ERROR); } } private void showError(String errorMessage){ JOptionPane.showMessageDialog(frame, errorMessage, "Error", JOptionPane.ERROR_MESSAGE); } } |
NOTA: Tener en cuenta que para programar en Java podremos usar el IDE de nuestra preferencia, en mi caso he utilizado Eclipse. [Actualización] En el código Java no olvidar editar la constante PORT_NAME e indicar el puerto que utilicen[/Actualización]
Para compilar escribir en consola:
javac -classpath path_instalacion_biblioteca/RXTXcomm.jar:. JPanelTurnOnOffLED.java
Después de haber compilado nuestro programa Java, procedemos a ejecutarlo, de la siguiente manera:
java -Djava.library.path=. -cp path_instalacion_biblioteca/RXTXcomm.jar:. JPanelTurnOnOffLED
path_instalacion_biblioteca: Ruta de instalación de la biblioteca, es decir, donde estarán alojados los jar.
Voilà!!!, ya deberíamos poder visualizar el JFrame con sus respectivos botones de encendido y apagado. Así que, ¿qué esperas? empieza ya a encender y apagar tu LED.
Recomendación: En el libro Getting Started with Arduino, nos sugieren que en caso de mantener el LED mucho tiempo encendido usar una resistencia de 270 ohm, en cuyo caso necesitaríamos adicionalmente para hacer nuestro ejemplo una breadboard y par de cables.
Puntos importantes a tener en cuenta para usuarios Mac OS X (snow leopard)
– Si colocas (copiar con el comando sudo) la biblioteca RXTX en /Library/Java/Extensions, nuestro programa java podrá ser compilado y ejecutado de la siguiente manera:
javac JPanelTurnOnOffLED.java
java JPanelTurnOnOffLED
Aunque esta quizás no es la forma más recomendada en caso de que se llegase a trabajar con distintas versiones de la biblioteca, ya que en ese caso lo adecuado sería tener una instalación para cada versión y compilar y ejecutar nuestro programa Java de la manera indicada en un principio para poder indicarle al compilador y a la maquina virtual con que versión de la biblioteca estamos trabajando.
– Puede que te sea necesario al momento de ejecutar el programa Java indicar que se ejecute en 32 bits, si obtienes una exception similar a la que te muestro a continuación
«java.lang.UnsatisfiedLinkError: /Library/Java/Extensions/librxtxSerial.jnilib: no suitable image found. Did find: /Library/Java/Extensions/librxtxSerial.jnilib: no matching architecture in universal wrapper thrown while loading gnu.io.RXTXCommDriver»
Lo que implicará que tengamos que añadir un argumento a nuestro comando de ejecución , quedando de la siguiente manera
java -d32 JPanelTurnOnOffLED
– Ir a la carpeta /var/lock (si no existe, crearla) y otorgarle permisos de escritura al o los usuarios que vayan a ejecutar el programa, esto podrás hacerlo desde el finder o por linea de comandos con el comando chmod.
Conclusión
Cada día que pasa y me involucro más con mi nuevo hobbie, me fascino con su versatilidad, pues además de ser una arquitectura abierta, nos permite interactuar con una gran gama de lenguajes de programación entre los que les puedo mencionar C, C++, Java, Objective-C, entre otros, de una gran lista, lo cual como les dije antes, nos permite gozar de las bondades (ventajas) de un lenguaje o plataforma de software, como lo es en este caso Java, ya que podríamos aprovechar el gran numero de bibliotecas existentes, así como también de su variedad de frameworks (que son unos cuantos). Este ejemplo ha resultado interesante para mi, ya que además de lo mencionado anteriormente, es un ejemplo que podemos extrapolar a algo mas complejo, es decir, podemos imaginar que en vez de ser 2 botones, podemos crear una interfaz mas compleja con unos 5 o 6 botones y cada uno de ellos con una instrucción distinta, que nos permita por ejemplo dado el botón pulsado, ver en una pantalla, la temperatura, posicionamiento global, etc…, o incluso controlar un servomotor.
En fin, como comente en un post anterior, aquí el limite es nuestra imaginación y mas aun cuando podemos interactuar con una variedad de lenguajes, lo que no resulta en un impedimento el no saber Processing, pues si tu fuerte es Perl, Python o Java, no importa, puedes empezar a programar ya!!!.
Video de la aplicación Java en ejecución