Arduino – Serial Monitor, Data Types and CheatSheet

Arduino CheatSheet

Para empezar y comprender bien qué estamos programando con Arduino nos será de muchísima ayuda una hoja de referencia con todas las operaciones, tipos de datos, bucles, librerías, funciones asociadas a los pines…

Esta chuleta la podemos descargar desde el siguiente enlace.

Data Types

Uno de los aspectos más importantes en programación es el tratamiento de datos que se manejan y que se comunican entre los distintos dispositivos que conectamos a nuestra placa.

Existen 3 tipos de datos a tener en cuenta.

El tipo Booleano

El tipo booelano solo permite 2 estados que se traducen a un cero o un uno y se puede traducir a verdadero o falso respectivamente. Este dato es el que usaremos para introducir en sentencias condicionales cuando se cumple una premisa utilizando la lógica booleana, que es la que está relacionada con el algebra de Boole.

Ejemplo: Si se cumple que un sensor detecta una señal, realizaremos determinada acción. En caso contrario o falso podremos realizar otra acción.

 

El tipo número

El tipo número tiene “infinitos” estados que nos permiten medir valores, ya sean números enteros o reales. En el caso de contar las vueltas que da un servomotor, utilizaremos un entero. Si tenemos que medir el valor de un sensor de orientación necesitaremos usar un valor real con decimales.

El tipo carácter

ASCII Code

Siguiendo con el tema anterior vamos a explicar la traducción de números a letras. Si hacemos una prueba con el Monitor serial e imprimimos números en lugar de letras observaremos que no aparecen números sino otros caracteres que pueden parecer extraños.

Los datos carácter pueden expresarse como un número entero de 0 a 127, como un número en hexadecimal de 0 a 7F o un octal de 0 a 177.

Todos estos caracteres son los disponibles en un teclado que pueden ser interpretados por un ordenador en su codificación numérica. Los primeros caracteres del 0 al 31 son aquellos caracteres que no pueden ser representados en una pantalla, pero se interpretan como acciones; como el enter, la tecla esc, el espacio, el tabulador…

Del 48 al 57 disponemos de los números en carácter; en esta interpretación hay que tener cuidado, porque el número 100 en su comunicación se traduce en un 1 (49), un 0 (48), seguido de otro 0 (48). Por lo que el número transmitido no será el 100, sino el 49-48-48.

Del 65 al 90 disponemos de las letras mayúsculas, y de la 97 a 122 de las letras minúsculas.

El tipo cadena

El tipo cadena o string es la manera que tenemos de unir la programación con nuestro lenguaje hablado. Por ejemplo si queremos escribir para mandar un mensaje utilizaremos este tipo de dato y lo manipularemos a nuestro gusto.

El tipo string dispone de un conjunto de herramientas que facilitan mucho su manipulación para obtener una respuesta deseada y que veremos más adelante en algunas lecciones que intervengan las comunicaciones remotas.

IMPORTANTE: Hay que tener cuidado al mezclar distintos tipos de dato, ya que nuestro compilador lanzará un error en el momento que asociemos un tipo de dato con otro.

Se pueden crear variables, que como su propio nombre indica, varían de valor en el programa según la circunstancia. Las variables han de ser de un tipo de dato concreto. Hay que tener cuidado de no manipular variables de distinto tipo entre sí, porque pueden resultar errores que a simple vista pueden pasar desapercibidos.

Por ejemplo un booleano puede ser tratado como un número, en el que se corresponde el valor verdadero como un 1, y falso como 0. Y de la misma manera un número puede ser tratado como una tipo cadena en el que el número 1 puede ser tratado como el carácter “1”.

 

Serial Monitor

Para programar en Arduino, como en cualquier otro lenguaje es muy útil disponer de una consola (Monitor Serial) que informe de lo que ocurre dentro de nuestros desarrollos.

Si tuviéramos un sistema de riego en la que la vida de nuestra planta favorita; estuviera en juego, deberíamos controlar todos los estados para informar si hay algún fallo en nuestro sistema. Realmente esta información debería guardarse en un fichero para poder consultarlo posteriormente, pero de todas maneras hacemos uso del Monitor Serial para depurar y conocer cómo funciona nuestro programa de Arduino por dentro. De esta manera podemos asegurarnos qué valores tienen algunas variables o qué entradas y salidas recibimos de otros componentes conectados a nuestra placa. Por ejemplo podemos aplicarlo para conocer el valor de los sensores que estamos utilizando o de los paquetes que estamos recibiendo a través de sus pines.

Por ello voy a explicar antes cómo utilizar el Monitor Serial de forma rápida y sencilla que posteriormente utilizaremos en otros tutoriales.

El código básico para comunicar con este monitor es muy sencillo:


void setup() {
 Serial.begin(9600);
 Serial.println("Monitor Serial"); /* This message initialize with
 a message. Typpicaly is used "Hello World".*/
}

void loop(){
}

Es exactamente el mismo ejercicio que el típico “Hello World” que se enseña habitualmente; solo hay que especificar la velocidad de la comunicación con el puerto serie que suele ser de 9600 baudios y el String o valor que se quiere comunicar. Para ejecutar este programa una y otra vez solo hay que darle al botón de reset de Arduino y se iniciara cada vez la función Setup.

Cuidado con el tipo de valor que se intercambia de un lado a otro, no es lo mismo pasar un String, que un Integer, que un float y dependiendo de nuestra aplicación habremos de ser cautos, porque si no, tendremos errores en nuestro programa y puede que algún disgusto. Para saber qué tipo de dato estamos pasando deberemos hacer una conversión de un tipo a otro o utilizar bien las funciones de escritura.

Print y println imprime datos ASCII; por lo que si introducimos un número y lo igualamos a una variable de tipo numero (int, float, double), éste no lo aceptará, porque es de tipo texto.

Write por otra parte escribe en binario como un byte o serie de bytes en el monitor. Es útil cuando hay que trabajar con protocolos de transmisión de datos, solo hay que sustituir la función “print” por “write” y aunque parezca que escriben lo mismo que no os engañen. Probad a escribir un número.

Ahora vamos a dar un paso más. Ahora queremos introducir un valor por teclado enviárselo al Arduino y que ésta imprima su valor numérico. Este programa lo utilizaremos para dar ordenes a otros elementos a través de alguno de sus pines de salida y así poder controlar un servomotor, encender Leds por teclado y lo que se nos ocurra.

String readString;

void setup() {
   Serial.begin(9600);
   Serial.println("Write a number");
}

void loop() {

   while (Serial.available()) {
      delay(3); /*delay to allow buffer to fill*/
      if (Serial.available() ) {
         char c = Serial.read(); /*gets one byte from serial buffer*/
         readString += c; /*makes the string readString*/
      }
   }

   if (readString.length() > 0) {
      Serial.println("The String is \""+readString+"\""); /*see what was received*/

      int number = readString.toInt();

      Serial.print("The Number is :");
      Serial.println(number); /*print to serial monitor to see number results*/

      readString="";
   }
}

Ahora lo que hacemos es leer la serie de números que introducimos. Lo que hacemos es leer uno a uno cada carácter dejando un pequeño espacio de tiempo para ir llenando el buffer. Con la función Serial.read leemos los datos de teclado y los añadimos a un string para visualizarlos como un conjunto. Después pasamos este número a un valor entero que es el valor con el que operaremos con otros dispositivos. Por ahora utilizamos enteros y más adelante nos complicaremos la vida para introducir números reales (float).

Por último comentaré que dependiendo de cómo se declare la variable que se iguala a la función Serial.read(), si es un char obtendremos la representación de teclado, pero si la variable es entera, nos aparecerá el valor decimal asociado a esa tecla.

NOTA: Serial.read() vacia el buffer de entrada cada vez que se invoca para proceder a la lectura del siguiente dato en bucle. Esto quiere decir que no se puede asociar la variable Serial.read() a un tipo distinto de variable en un mismo programa. Serial.read() se asignará al primer tipo que se ha asociado, en este caso a un char y el num será todo el rato igual a -1. Si cambiamos el orden y la asignamos primero al tipo entero, nos dará el valor numérico de teclado, mientras que el carácter será todo el rato igual .

Si queremos que esto no ocurra, podemos utilizar otra función de lectura que se llama Serial.peek(). En esencia Serial.peek() lee el valor, pero no avanza para leer el siguiente. Esto es útil si queremos leer más de una vez desde un mismo caracter de entrada.


char charByte = 0; /* Si usas un char,
aparece el caracter que escribes por teclado*/
int numByte = 0; /* Si usas un entero,
aparece el número que corresponde con el valor ASCII en Decimal*/
void setup() {
   Serial.begin(9600); /* abre el puerto serie a 9600 bps */
}

void loop() {

   /* envia datos solamente cuando recibe datos */
   if (Serial.available()) {
      /* lee el byte entrante*/
      charByte = Serial.peek();
      numByte = Serial.read();
      /* dice lo que ha recibido */
      Serial.print("He recibido un caracter: ");
      Serial.println(charByte);
      Serial.print("He recibido un numero: ");
      Serial.println(numByte);
   }
}