Puerto Serie (Arduino -> Ordenador)

Objetivos

  • Comprender la comunicación vía puerto serie.
  • Utilizar la librería Serial.
  • Operaciones con enteros.
  • Los tipos String y char.
  • Operando con Strings.
  • La instrucción while.

Material requerido.

arduino
  • Arduino Uno o similar. Un PC con el entorno de Arduino correctamente instalado y configurado.

Comunicar Arduino con el PC

Necesitaremos comunicar nuestro Arduino con nuestro ordenador  para enviarle órdenes o recibir información,  o para depurar nuestros programas, mostrando el valor que toman las variables.

La comunicación en serie es muy sencilla, bastan dos hilos para enviar una diferencia de tensión entre ellos y poder marcar niveles alto (5V) y bajo(0V) y con esto podemos transmitir información digital. Ahora solo nos falta pactar dos cosas entre quien envía y quien recibe:

  • Un código común para codificar los caracteres que enviamos.
  • Un acuerdo de velocidad para saber a qué ritmo hay que leer los datos.

El código común que vamos a usar con Arduino se llama código ASCII y es estándar en todos los ordenadores. Es una forma de codificar las letras mediantes números que representas estos caracteres.  Así por ejemplo la letra A se representa por el numero 65, la B con el 66, C el 67… Prácticamente todos los ordenadores actuales utilizan este código y eso incluye a Windows, Mac y Linux, pero es importante comprender que esté es uno más entre varios códigos de caracteres posibles (EBCDIC por ejemplo).

Actualmente, en realidad, se suele usar una extensión del código ASCII (llamada Unicode) que permite el uso de caracteres no incluidos en la tabla original, y que permite representar caracteres como las Ñ, o los acentos para el español, pero también alfabetos distintos como el Kanji chino o el alfabeto cirílico. Y este es el motivo por el que podéis leer las letras chinas o rusas en las páginas de internet de estos países.

El otro factor a pactar para realizar una comunicación serie es la velocidad. Dado que solo disponemos de dos hilos para transmitir, necesitamos saber cuándo hay que leer la línea y esto se hace estableciendo un acuerdo de velocidad. Si la velocidad de envío es distinta de la velocidad de lectura, el mensaje final será irreconocible.

Esta velocidad se mide en bits por segundo y vamos a ver que Arduino soporta diferentes velocidades de comunicación serie.

comunicacion_serie_ii_practico

Establecer comunicación

Arduino dispone de una librería serie incluida llamada Serial, que nos permite enviar información al ordenador, para usarla simplemente tenemos que pedirle en nuestro setup() que la incluya. La instrucción que se encarga es:

Serial.begin( velocidad ) ;

La velocidad es un valor entre 300 y 115.200 bits por segundo. Y suele ser costumbre establecerla en 9600 (el valor por defecto) pero no hay ninguna razón para ello y esta no es una velocidad especialmente alta.

Para enviar un mensaje desde Arduino a nuestro ordenador podemos usar las funciones Serial.print() y Serial.println().

Veamos un ejemplo:

int led = 10 ;

int boton = 6 ;
bool estado = false ;
void setup()
{
    Serial.begin(9600) ; // Inicializa el Puerto seria 9600 bits /s
}
void loop()
{
    int i = 54 ;
    Serial.println( i );
}

El println() enviara el valor de i al puerto serie de Arduino (repetidamente). Para leerlo en nuestro ordenador necesitamos un monitor de puerto serie. El IDE de Arduino incluye uno muy sencillo, pero suficiente que se invoca con el botón del monitor:

monitor_serie

Necesitamos además asegurarnos de que la velocidad de conexión es la misma en ambos extremos. Fíjate en la parte inferior derecha del monitor serie:

monitor_serie_velocidad

 Normalmente la velocidad por defecto son los 9600 bits por segundo o baudios y si lo desplegáis, veréis las diferentes velocidades aceptables para Arduino. Aunque estrictamente hablando, bits por segundo y baudios no son exactamente lo mismo salvo bajo ciertas condiciones particulares que en Arduino se cumplen, por lo que aquí podemos usarlos como sinónimos.

Ahora que sabemos enviar información y resultados al ordenador, vamos a ver cómo podemos operar con enteros y mostrar el resultado en monitor serie. En C++ los operadores numéricos son los normales en cálculo (y algunos menos frecuentes):

  • Adición: + (símbolo más)
  • Resta: – (símbolo guión)
  • Multiplicación: * (símbolo asterisco)
  • División entera: / (símbolo barra) cociente sin decimales (puesto que operamos con enteros)
  • Resto: % (símbolo tanto por ciento) devuelve el resto de una división.

En C++ tenemos que expresar las operaciones matemáticas en una sola línea y utilizar paréntesis para garantizar que se opera como necesitamos.

Los paréntesis fuerzan las operaciones de una forma clara y conviene utilizarlos ante la duda porque de otro modo, detectar los errores de operación puede volverse muy difícil especialmente cuando uno empieza a programar.

El operador resto es más útil de lo que parece a primera vista porque nos permite saber si un numero es múltiplo de otro. Supongamos que queremos saber si un número dado es par.

Podríamos escribir un programa como este:

void setup()
{
    Serial.begin(9600) ; // Inicializa el Puerto serie
}
void loop()
{
  int i = 27 ; //El número en cuestión
  if ( i % 2 == 0)
       Serial.println(“Es par.”) ;
 else
      Serial.println(“Es impar”);
}

Dando a la variable i distintos valores podemos comprobar cómo funciona el operador resto %.

En este programa hemos usado de un modo diferente el Serial.println() pasándole un String de texto entrecomillada.

Serial.print() envía el texto (entrecomillado) que le pongamos pero no da salto de línea cuando termina. En cambio Serial.println() hace lo mismo e incluye al final ese salto de línea.

void setup()
{
   Serial.begin(9600) ; // Inicializa el Puerto serie
}
void loop()
{
   Serial.print(“Buenos “) ;
   Serial.print(“Dias “) ;
   Serial.println(“a todos.”) ;
}

C++ dispone de un tipo de variables llamadas String, capaces de contener textos. Podemos operar con ellas simplemente definiéndolas como cualquier otro tipo de C++:

void loop()
{
   int resultado = 25 ;
   String  cadena = ” El resultado es: ” ;
   Serial.print( cadena) ;
   Serial.println( resultado);
}

Un tipo String se inicializa simplemente poniendo entre comillas dobles un texto, y se puede operar con ellas de una forma similar a como operamos con enteros. Prueba:

void loop()
{
   String a = “hola ” ;
   String b = “a todos.” ;
   Serial.println( a + b);
}

Y también podemos construir un String sobre la marcha así:

void loop()
{
   int resultado = 25 ;
   String s = “El resultado es: ” ;
   Serial.println( s + String( resultado ));
}

Donde imprimimos el resultado de concatenar s String, y la conversión de un int a String (El operador + añade un String al final de otro).