miércoles, 11 de enero de 2012

Comunicación Serial con Arduino

Abstract

(go to English Version)

Una de las principales ventajas de un micro es la posibilidad que tenemos de comunicarnos con el mismo vía puerto serial.

En este artículo y próximos tendremos un acercamiento a lo que podemos hacer, y algunas de las herramientas que he encontrado interesantes para interactuar con un microcontrolador, involucrando internet...

A menos que un micro se programe con una implementación standalone, es decir, que se su funcionamiento se circunscriba a acciones que no dependan de la interacción externa (más allá de sus entradas digitales o analógicas), no será necesario ejecutar los mecanismos que en este artículo se describen. Es cierto que muchas de las aplicaciones de los microcontroladores no requieren asomarse a su entorno, pero cada vez es más común pensar en la comunicación como herramienta de interacción con las aplicaciones que diseñamos para estos ambientes. Para muestra, veamos el siguiente ejemplo.
...
Comunicación con microControladores tipo Arduino

Si poseemos una casa con ventanas panorámicas (de estas que se abren deslizándolas horizontalmente), tal que una persona puede entrar sin inconvenientes a través del espacio disponible una vez abiertas, y nos gusta salir a menudo de vacaciones, tendremos un problema de seguridad. La probabilidad que irrumpan en nuestro hogar en esos momentos en que la casa está sola será muy alta.

Para alguien que quiera diseñar su sistema de seguridad, en primera instancia seguramente pensará en colocar sensores de movimiento o apertura para activar una alarma muy ruidosa al momento que haya una intrusión en la residencia. Esto puede ser una solución, pero la alarma alertará solo al entorno inmediato a la casa, y a los intrusos.

Ahora bien, también podemos pensar en un sistema de seguridad silencioso al entorno inmediato a la residencia, pero que a través de un sistema de comunicación al exterior vía internet, envíe un mensaje de texto con la alerta a algún medio de recepción, sea email, chat client (messenger) o a twitter!.

Otro ejemplo de comunicación remota es, por ejemplo, la posibilidad de crear un sistema de control de luces y electrodomésticos en nuestro hogar. El mismo puede ser automatizado desde el micro definiendo un horario de ejecución de eventos para encender o apagar luces, mover una celda solar orientándola al sol de forma eficiente, motorizar una ventana para la entrada de luz de acuerdo a la luminosidad del entorno o simplemente encender el aire acondicionado de nuestra habitación cercano a la hora de nuestra llegada.

Con este último ejemplo, que tal si llegamos más temprano a casa?. Pudiéramos comunicarnos con nuestro micro utilizando nuestro celular inteligente a través de messenger enviando un mensaje como el siguiente:

AC: encender

De esta forma y a través del software adecuado, este mensaje puede ser recibido y ejecutado, en línea.

Como estos ejemplos, existen muchos más que solo la imaginación y la necesidad particular pueden producir.

Para realizar tareas como estas, debemos empezar de lo sencillo a lo complejo. Lo primero que debemos saber es que con los microcontroladores como el arduino, pinguino, teensy, etc. podemos comunicarnos a un servidor vía puerto serial.

Con arduino o teensy la comunicación serial se establece a través de la interfaz USB de la cual disponemos para conectar el micro al computador. Al inicializar el puerto serial desde el micro, en ambientes linux/unix se mapeará un directorio en /dev/ttyXXXn que permitirá enviar o recibir información.

El siguiente código define la salida secuencial de un mensaje al puerto serie de nuestro computador.

int i=0;
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  Serial.print("mensaje de prueba: ");
  Serial.println(++i);
  delay(1000);
}

En el bloque setup() inicializamos el puerto serial a 9600 baudios con Serial.begin(9600). En el bloque loop() enviamos vía serial el mensaje seguido de un consecutivo el cual actualizamos secuencialmente con ++i.

Desde el computador podremos observar esta salida si interrogamos adecuadamente al puerto mapeado en /dev/ttyACMn. Donde n>=0.

Para este ejemplo el puerto fue mapeado contra /dev/ttyACM0. En mi caso utilizo ubuntu, pero para cualquier linux/MAC debe ser muy similar.

Cuando el micro es conectado a cualquier puerto USB de nuestro computador el mismo puede ser accedido vía línea de comando desde un terminal o a través de algún programa hecho para este fin. Una tercera opción es crear nuestro propio programa de lectura y/o escritura al puerto serial. Esta última opción es la adecuada si quisiéramos interactuar con el puerto para obtener información del puerto o instruir al micro a ejecutar alguna acción.

Para nuestro sencillo ejemplo podemos interrogar inicialmente al puerto utilizando el terminal serial que viene como herramienta del IDE de Arduino o a través de gtkterminal o minicom.

VIDEO: Comunicación Serial 1

Desde el micro podemos también leer desde el puerto serial y así poder tomar decisiones de que ejecutar de acuerdo a la entrada.

El siguiente programa permite simplemente leer la entrada serial y devolver la cadena de caracteres obtenida, detectando el fin de línea.

char caracter;
byte i=0;
char cadena[100];
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if (Serial.available())
  {
    caracter=Serial.read();
    if (caracter == 10)
    {
      cadena[i++]='\0';
      i=0;
      Serial.println(cadena);
    }
    else
      cadena[i++]=caracter;
  }
}

En el bloque setup() inicializamos el puerto, seguidamente en el bloque loop() chequeamos el buffer del puerto con Serial.available().

Si hay caracteres disponibles los leemos secuencialmente con Serial.read(). Si detectamos el fin de línea agregamos a la cadena de caracteres el caracter de fin de cadena y reseteamos el contador, enviando de vuelta la cadena de caracteres al puerto.

En caso que no sea un fin de linea (10) entonces vamos anexando a la cadena cada catacter recibido actualizando el indice i.

VIDEO: Comunicación Serial 2

Ahora veamos como utilizar este último programa para adecuarlo para accionar el encendido o el apagado el aire acondicionado del segundo ejemplo mostrado en este artículo.

#include string.h
#define ENCENDER 1
#define APAGAR 0
char caracter;
byte i=0;
char cadena[100];

void AC_Action(int accion)
{
  

    if (accion == ENCENDER)  
    {
        Serial.println("Encendiendo el Aire Acondicionado Principal... ");
        //Accion de encender
        //esperar resultado
        delay(500);
        Serial.println("Aire Acondicionado Encendido... Status OK");
    }   
    if (accion == APAGAR)  
    {    
        Serial.println("Apagando el Aire Acondicionado Principal... ");
        //Accion de apagado
        //esperar resultado
        delay(500);
        Serial.println("Aire Acondicionado Apagado... Status OK");
    
}
void setup()
{

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

    if (Serial.available())  
    {    
        caracter=Serial.read();
        if (caracter == 10)
        {
              cadena[i++]='\0';
              i=0;
              if (!strcmp(cadena,"AC: Encender"))
                AC_Action(ENCENDER);
              if (!strcmp(cadena,"AC: Apagar"))
                AC_Action(APAGAR); 
        
        else
          cadena[i++]=caracter; 
      }
}

Hemos creado una procedimiento que dependiendo del parámetro acción encenderá o apagará el aire acondicionado, asumiendo que tenemos un dispositivo conectado al micro capaz de hacerlo. En nuestro caso el micro devolverá vía serial el mensaje de encendido y apagado correspondiente.

El bloque loop() mantiene el mismo esquema, solo que cuando se hace match con una cadena específica se ejecuta la función AC_Action() pasándole el parámetro ENCENDER o APAGAR definidos al principio del programa.

VIDEO: Comunicación Serial 3

El próximo paso va a ser comunicarnos desde el exterior del PC a través de diferentes medios para poder interactuar con el micro.

En próximos artículos seguiremos explorando posibilidades de comunicación, interacción y ejecución.

No hay comentarios:

Publicar un comentario