Puerto Serie (Ordenador -> Arduino)

Esta segunda entrada es una continuación donde se trata de explicar el funcionamiento de la comunicación serie entre Arduino y el ordenador.

En esta ocasión veremos como el ordenador puede mandar información (datos) hacia nuestro arduino en tiempo de ejecución. Es importante haber revisado y entendido la entrada donde se explica dicho comunicación en el sentido de Arduino->Ordenador.

Recibiendo mensajes

Hasta ahora solo hemos enviado mensajes desde Arduino hacia el ordenador, ¿Pero como recibimos mensajes en Arduino?

En primer lugar disponemos de una función llamada Serial.parseInt() que nos entrega lo que se escribe en el monitor serie convertido a entero:

void loop(){
int x;
if (Serial.available() > 0){
   x = Serial.parseInt();
   Serial.println(x) ;
}
}

Este programa simplemente recibe en x los datos que nos tecleen en la consola (cuando pulsemos intro) y si son enteros los almacena en x y si es un texto, lo interpreta como cero.

Hemos utilizado otra función de Serial : Available() que devuelve un valor boleado (true o false). Es conviene comprobar que antes de leer del puerto serie hay algo que nos han enviado. Si lo hay Available() es True y en caso contrario es False.

Para leer un String del puerto serie tenemos que complicarnos un poco más y hablar del tipo char.

El tipo char representa un único carácter y se define con comillas simples, a diferencia de String que necesita comillas dobles:

char c = 'a';
String s ="a";

Para leer una cadena desde el puerto serie necesitamos leer un carácter cada vez y después montar un String a partir de ellos, pero antes, asegúrate de seleccionar ambos NL & CR en la parte inferior del monitor serie, para garantizar que se envía el carácter de fin de línea:

fin_linea

Un programa para leer la consola sería algo así:

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

void loop(){
char c =' ';
String mensaje ="";
//Comprobamos si hay algo
If (Serial.available()){
    //Si lo hay, lo leemos hasta el intro
    while( c != '\n'){
          mensaje = mensaje + c ; // Añadimos
          c = Serial.read(); //Leer 1 carácter
          delay(25);
    }
    Serial.println(mensaje);
    mensaje=""; //Bórralo para la próxima vez
   }
}

Aquí usamos otra instrucción de C++ llamada while. Ejecuta repetidamente el bloque que le sigue mientras se cumpla la condición que le pasamos entre paréntesis:

while (condición){
      ......... // instrucciones que se repiten
}

Cuando lee el intro final de lo que escribimos, La condición c != ‘\n’ se vuelve falso y sale del while.

Por lo demás, comprobamos si hay algo disponible en el puerto serie y de ser así lo concatenamos en el mensaje leyendo un char (carácter) cada vez y sumándoselo a mensaje para construir un String que podamos imprimir al salir.

El motivo del delay(25) es que a una velocidad tan lenta, enviar un char de 8 bits por la puerto serie, tarda mucho más de lo que tarda Arduino en ejecutar las instrucciones del while y volver a empezar. Por eso si se suprime el delay leerá un carácter bueno (de la palabra escrita y como 10 caracteres basura para un Arduino UNO o Mega).

Si subimos la velocidad de comunicación a 115200 bits por segundo, comprobareis que no hay este problema ya que al multiplicar la velocidad de envío por más de 10, Arduino ya no tiene tiempo de volver a por más caracteres antes de que lleguen.

Por ejemplo:

Utilizando el puerto de serie encender o apagar un LED. Para ello enviamos un carácter a la placa Arduino, empleando el monitor serial. En caso de enviar ‘a’ la placa Arduino apaga el LED, y en caso de enviar ‘b’ lo enciende.

El circuito se puede ver en los esquemas básicos de como conectar un led: esquemas básicos.

Y el programa será así:

int option;
// suponemos conectado el led al pin 12
int led = 12;
void setup(){
    Serial.begin(9600);
    pinMode(led, OUTPUT);
}

void loop(){
  //si existe datos disponibles los leemos
  if(Serial.available()>0){
    //leemos la opcion enviada
    option=Serial.read();
    if(option=='a') {
        digitalWrite(led, LOW);
        Serial.println("OFF");
    }
    if(option=='b') {
        digitalWrite(led, HIGH);
        Serial.println("ON");
    }
  }
}

Actividad sugerida:

Enviamos un número entre 1 a 9 a través del monitor serial, y la placa Ardunino hace parpadear el LED integrado el número de veces indicado.

Desde la versión 1.6.6 del IDE de Arduino, una de las novedades más celebradas es la inclusión de una ventana para hacer gráficos con los valores recibidos por el puerto de serie.