Arduino – Capítulo 16 – Modificando el logo de Arduino

Processing Logo

 

Hasta ahora hemos hecho muchas cosas estupendas con el mundo físico, pero ha llegado el momento de controlar nuestro pc mediante Arduino. Cuando programamos nuestro Arduino, estamos abriendo una conexión entre el pc y el microcontrolador. Podemos utilizar dicho conexión para enviar y recibir información a otras aplicaciones.

Arduino tiene un chip que convierte la comunicación basada en usb que utiliza el pc, en la comunicación serie que utiliza Arduino. La comunicación en serie consiste en que dos computadoras, nuestro Arduino y el pc, están intercambiando bits de información en serie, o dicho de otro modo, un bit detrás de otro.

Cuando se comunican en serie, las computadoras necesitan decirse la una a la otra a que velocidad se están hablando. Seguramente os habréis percatado que cuando usamos el monitor serie hay un número en la esquina inferior derecha de la ventana. Este número, 9600 bits por segundo, o baudios, es el mismo valor que declaramos al utilizar la función Serial.begin(). Esta es la velocidad a la que Arduino y el pc intercambian datos.

Hemos usado el monitor serie para ver los valores provenientes de las entradas analógicas; nosotros utilizaremos un método similar para obtener valores en un programa que escribiremos en un entorno de programación llamado Processing. Processing está basado en Java y el entorno de desarrollo de Arduino está basado en Processing. Son muy parecidos, así que no nos será muy extraño trabajar con el.

Antes de empezar con este proyecto, descargaremos la última versión de Processing desde processing.org/download. Nos será muy útil echar un vistazo a la guías “Getting started” y “Overview“. Ellas nos ayudarán a familiarizarnos con Processing antes de que empecemos a escribir software para comunicarnos con nuestro Arduino.

La forma más eficiente de enviar datos entre Arduino y Processing es utilizando la función Serial.write() en Arduino. Es similar a la función Serial.print() utilizada con anterioridad en el sentido que también envía información al pc conectado, pero que en lugar de enviar información legible para los humanos como número y letras, envía valores comprendidos entre el 0 y 255 como un flujo puro de bytes. Esto limita los valores que pueden ser enviados por Arduino, pero permite una rápida transmisión de información.

Tanto en nuestro pc como en Arduino, existe algo llamado buffer serie, el cual, retiene la información hasta que sea leída por el programa. Nosotros enviaremos bytes desde el Arduino al buffer serie de Processing. Entonces Processing sacará dichos bytes del buffer para poder leerlos. Una vez que el programa haya leído la información del buffer, dejará el espacio libre para almacenar más información.

Cuando utilizamos la comunicación en serie entre dispositivos y programas, no solo es importante que ambas partes conozcan la velocidad de la comunicación, si no que también deben conocer que tipo de información están esperando. Cuando conocemos a alguien, probablemente esperemos un “¡Hola!”, si en lugar de eso la otra persona dice algo como “El gato está bufado”, seguramente pensaremos que está un poco loco. Con el software, tenemos que saber de ambas partes que tipo de información se ha enviado y cual se ha recibido, o lo que es lo mismo, asegurarnos de que el tipo de información que hemos enviado es del mismo tipo que la que hemos recibido.

 

Montando el circuito

Para montar el circuito de este proyecto necesitamos los siguientes componentes:

– 1 Potenciómetro.

Una vez tengamos dicho componente, debemos seguir los pasos siguientes.

1 – Conectamos la alimentación y la tierra a la protoboard.

2 – Unimos la patilla izquierda del potenciómetro a la alimentación, la derecha a tierra y la central al pin analógico 0.

Terminado de montar el circuito, deberíamos de tener algo parecido al mostrado en la siguiente figura.

Diseño de protoboard

El esquema eléctrico correspondiente sería:

Esquema de conexiones

 

El código de Arduino

En este proyecto vamos a tener dos tipos de código fuente, el de Arduino y el de Processing. Primeramente veremos como es el del Arduino ya que es más corto y estamos más familiarizados con el. Después veremos la parte correspondiente a Processing.

Primeramente, en la función setup(), iniciaremos la comunicación serie. El programa que hagamos posteriormente con Processing, deberá tener el mismo ratio de comunicación serie que nuestro Arduino.

void setup() {

    Serial.begin(9600);

}//Fin de la funcion setup.

En la función loop(), usaremos el comando Serial.write() para enviar información a través de la conexión serie. Serial.write() solo puede enviar valores comprendidos entre 0 y 255. Para asegurarnos que los datos que enviamos se encuentran dentro de dicho rango, dividiremos el valor analógico leído entre 4.

void loop() {

    Serial.write(analogRead(A0)/4);

Tras haber enviado un byte, esperaremos un milisegundo para que el ADC (Analog to Digital Conversion) se haya establecido. Finalmente, subiremos nuestro programa al Arduino y lo dejaremos a un lado para empezar a escribir el programa con Processing.

    delay(1);

}//Fin de la funcion loop.

El código de Processing

El lenguaje Processing es parecido a Arduino, pero tiene suficientes diferencias como para tener que echarle un vistazo a los tutoriales de iniciación mencionados anteriormente y poder así familiarizarnos con él.

Abrimos un nuevo boceto de Processing. A diferencia de Arduino, Processing no sabe nada acerca de puertos serie a no ser que incluyamos una librería externa. El siguiente paso será importar la librería serie.

Necesitamos crear una instancia del objeto de la librería, tal y como hemos hecho en capítulos anteriores con la librería del servo motor. Este objeto de nombre único será el que utilicemos cada vez que queramos recurrir a la conexión serie.

import processing.serial.*;
Serial myPort;

A continuación, si queremos usar imágenes en Processing, necesitamos crear un objeto que almacene dicha imagen y tenga un nombre.

PImage logo;

Seguidamente, crearemos una variable que almacene la tonalidad de fondo del logo de Arduino. El logo es un archivo con extensión .png y está hecho sobre una transparencia, por lo que podemos ver los cambios en el color de fondo.

int bgcolor = 0;

Al igual que Arduino, Processing también tiene una función setup(). Aquí será donde abriremos la conexión serie y le daremos al programa toda una colección de parámetros que usará mientras se ejecuta.

void setup() {

Podemos cambiar la manera en que Processing trabaja con los colores. Normalmente trabaja con una paleta de colores RGB (Red, Green, Blue). Esto es parecido a lo que hicimos en el proyecto de la lámpara de colores, cuando usábamos valores comprendidos entre el 0 y 255 para cambiar el color de un led RGB. En este programa sin embargo, vamos a utilizar una paleta de colores llamada HSB (Hue, Saturation, Brightness), en donde cambiaremos el fondo (Hue en inglés) al hacer girar el potenciómetro.

La función colorMode() tiene dos argumentos: el tipo de modo y el valor máximo que puede esperar.

    colorMode(HSB, 255);

Para cargar la imagen en el boceto, tenemos que leerla mediante el objeto llamado logo que hemos creado anteriormente. Cuando proporcionamos la url de una imagen, Processing la descargará cuando ejecutemos el programa.

Con la función size(), le estamos diciendo a Processing como de grande ha de ser la ventana. Si utilizamos logo.width y logo.height como argumentos, la ventana del boceto se escalará automáticamente al tamaño de la imagen que estamos utilizando.

    logo = loadImage("http://arduino.cc/logo.png");
    size(logo.width, logo.height);

Processing tiene la habilidad de mostrar mensajes de estado utilizando el comando println(). Si utilizamos esto en conjunto con la función Serial.list(), obtendremos una lista de todos los puertos serie que nuestro pc tiene disponibles al empezar el programa por vez primera. Utilizaremos esto una vez que hayamos terminado de programar para ver en que puerto se encuentra nuestro Arduino.

    println("Puertos serie disponibles:");
    println(Serial.list());

A continuación, tenemos que darle a Processing la información necesaria sobre la conexión serie. Para poder pasar los datos necesarios a nuestro objeto serie myPort, el programa necesita saber que dicho objeto es una nueva instancia del objeto serie. Los parámetros que esperará son con que aplicación va a comunicarse, a través de que puerto va a realizar dicha comunicación y a que velocidad.

    myPort = new Serial(this, Serial.list()[0], 9600);

}//Fin de la funcion setup.

El atributo this le dice a Processing que vamos a utilizar la conexión serie en esa aplicación específica. El argumento Serial.list()[0], especifica que puerto serie estamos utilizando. Serial.list() contiene un array de todos los dispositivos serie conectados. El argumento 9600 nos tiene que resultar familiar, ya que define la velocidad a la que el programa va a comunicarse.

La función draw() es la equivalente a la loop() de Arduino, en el sentido de que es un bucle que se ejecuta una y otra vez sin parar. Es en esta función donde se dibujan los objetos en la ventana del programa.

void draw() {

Lo que vamos a hacer ahora es comprobar si hemos recibido información desde el Arduino. El comando myPort.available() nos dirá si hay algo en el buffer serie. Si hay bytes, los guardaremos en la variable bgcolor y los mostraremos por la pantalla de debug.

    if (myPort.available() > 0) {
        bgcolor = myPort.read();
        println(bgcolor);
    }

La función background() establece el color de la ventana. Requiere tres argumentos.  El primero es la tonalidad (hue en inglés), el segundo el brillo (brightness) y el último la saturación (saturation). Nosotros utilizaremos el contenido de la variable bgcolor para el parámetro de tonalidad, pero el brillo y la saturación la estableceremos a su valor máximo, 255.

Dibujaremos el logo con el comando image(). Para ello, necesitamos decirle que dibujar y cuales son las coordenadas de inicio para empezar a dibujar en la ventana. Nosotros empezaremos con las coordenadas 0,0, que indican la esquina superior izquierda.

    background(bgcolor, 255, 255);
    image(logo, 0, 0);


}//Fin de la funcion draw.

 

Puesta en marcha

Primeramente conectaremos nuestro Arduino y abriremos el monitor serie. Seguidamente, giraremos el potenciómetro y al hacerlo, veremos una serie de caracteres. El monitor serie espera recibir caracteres ASCII, no un flujo de bytes. Lo que vemos en la ventana es al monitor serie intentando interpretar los bytes como ASCII.

Cuando usamos el comando Serial.println(), estamos enviando información formateada para el monitor serie. En cambio, cuando utilizamos el comando Serial.write(), estamos enviando un flujo de información que solo programas como Processing pueden entender.

A continuación, cerraremos el monitor serie. Ejecutamos el boceto de Processing y observamos la ventana de salida. Deberíamos ver una lista de todos los puertos serie de nuestro pc. Si estamos usando OSX, buscaremos una línea que diga “/dev/tty.usbmodem411”, la cual suele ser la primera de la lista. En Linux será una línea que diga más o menos “/dev/ttyUSB0” o similar. En Windows, aparecerá como un puerto COM. El número que hay al principio de cada línea es el índice del array Serial.list()[]. Vista esta información, cambiaremos el número que hemos puesto en nuestro boceto de Processing para que coincida con el puerto correcto de nuestro pc.

El paso siguiente será reiniciar el boceto de Processing. Cuando el programa empiece a funcionar, giraremos el potenciómetro conectado al Arduino. Al hacer esto, deberíamos ver como el color de fondo del logo de Arduino cambia en función de como giremos el potenciómetro. También deberíamos ver valores mostrándose en la ventana de Processing. Dichos números corresponden al flujo de bytes enviados desde nuestro Arduino.

 

Conclusión

En este proyecto hemos aprendido que es la comunicación serie y el lenguaje de programación Processing, y como podemos combinar ambos para realizar tareas entre Arduino y un pc.

Con respecto a la comunicación serie, tenemos que tener en cuenta que cuando usamos dicho sistema, solo una aplicación puede hablar con Arduino al mismo tiempo. Si estamos ejecutando un boceto de Processing que se conecta con Arduino, no podremos ejecutar una nueva aplicación de Arduino o usar el monitor serie hasta que hayamos cerrado la aplicación activa.

Con Processing y otros entornos de programación, podemos controlar elementos multimedia en nuestro pc de múltiples maneras. Si nos entusiasma la cantidad de posibilidades que hay de controlar contenido de nuestro pc, tomémonos un tiempo en aprender con Processing. Existen multitud de ejemplos de comunicación serie tanto en el IDE de Arduino como en el de Processing que nos pueden ayudar a explorar todo su potencial.

Para interactuar entre ambos sistemas hemos utilizado un potenciómetro como elemento de entrada, pero… ¿podríamos usar otro tipo de sensor analógico?

 

 

Espero que os haya gustado.

Un saludo y muchas gracias por leer este artículo.  ^_^

 

Referencias

– Artículo basado en el capítulo “Project 14 – Tweak the Arduino Logo” del libro “Arduino Projects Book” distribuido por Arduino.cc junto con su “The Arduino Starter Kit“.

– Más información acerca de la conversión analógico-digital (ADC) en Arduino: Analog to Digital Conversion.

– Arduino.cc: Arduino and Processing

– Página oficial de Processing: processing.org

– Wikipedia: código ASCII

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s