Comunicación Serie con el PC: Arduino recibe datos desde el PC

En la lección anterior, aprendimos como enviar datos al monitor serie, para poder monitorizar así las señales con las que trabaje arduino. Ahora que sabemos enviar  información y resultados al ordenador, vamos a ver cómo podemos operar con enteros y mostrar el resultado en el monitor serie.

  


Para esto solo vamos a necesitar el arduino conectado al PC, sin ningún circuito externo, ya que arduino va ha realizar su verdadero trabajo, procesar datos y enviar resultados, y esto lo haremos a través del monitor serie.

En C++ los operadores numéricos son:

 Suma:                 +
 Resta:                 –
 Multiplicación:     *
 División entera:   /              Cociente sin decimales (puesto que operamos con enteros)
 Resto o Módulo: %             Devuelve el resto de una división.

Dada una expresión, la precedencia o prioridad de operadores indica que operaciones se realizaran antes y cuales después en función de su rango.

1 Lo que está dentro de los paréntesis

2 Potencias y Raices

3 Multiplicaciones y divisiones

4 Sumas y restas

en caso de que las dos operaciones tengan el mismo rango, o la misma prioridad, se hará de izquierda a derecha.

Para los nuevos en C++ no es fácil saber que operadores tienen prioridad, por lo que es más seguro que ante la duda usar paréntesis.

Los paréntesis obligan a que las operaciones se hagan de una forma clara y conviene utilizarlos ante la duda porque de otro modo, detectar los errores de operación puede volverse muy complicado cuando uno empieza a programar.

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. Vamos con algunos ejemplos:

OperaciónResultadoComentario
int i = 3 * 2resultado = 6

int i = 4 * 3 / 2
resultado = 6
Porque desprecia los decimales al ser entero
int i = 17 % 5
resultado = 2El resto de 17 entre 5
Int i = 2 + 6 / 2resultado = 5Calcula primero la división.
Int i = (2+6) / 2resultado = 4El paréntesis fuerza a que se realice primero la suma

El operador resto o módulo es más útil de lo que parece 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:

 

Dando a la variable i distintos valores podemos comprobar cómo funciona el operador resto módulo % y usaremos el monitor serie para saber si el número guardado en la variable i es par o impar

En el siguiente programa vamos a ver la diferencia entre Seria.print() y Serial.println().  Lo vamos a hacer de un modo diferente, vamos a pasarle un dato tipo String, que no es más que una cadena de texto entrecomillada. Serial.print() envía el texto ( entrecomillado) que le pongamos pero no da salto de línea cuando termina con lo que escribe la misma cadena de forma continuada una a continuación de la otra. En cambio Serial.println() hace lo mismo e incluye al final ese salto de línea, con lo que cada repetición de la cadena la escribe en diferentes líneas. Para comprobarlo vamos a cargar el siguiente programa.

    

C++ dispone de variable tipo Strings, capaces de contener textos. Podemos operar con ellas simplemente definiéndolas como cualquier otro tipo de dato de C++, en el siguiente programa vamos a ver como se crea una variable String, la inicializaremos con una cadena entrecomillada y luego la imprimiremos.

    

Un tipo String se define simplemente poniendo entre comillas dobles un texto, y se puede operar con ellas de una forma similar a como operamos con enteros.  Es decir podemos sumar texto, pero en vez de suma se llama concatenación, y en el siguiente programa tenemos dos variables tipo String y en el Serial.println las concatenamos una a continuación de la otra, por eso al final de la hola se ha dejando un espacio en blanco para que no se impriman las dos juntas.


Y también podemos construir un String sobre la marcha en el siguiente programa vamos a ver como se convierte un valor entero en un valor String, el valor contenido el variable resultado, se imprimira como texto en el Serial.print, ya que String(resultado) convierte en texto, al valor entero contenido en resultado.



Recibiendo mensajes  a través del puerto Serie

Ya sabemos como enviar mensajes desde Arduino hacia el PC, ¿Pero como recibimos mensajes en Arduino?


En primer lugar, tenemos una función de Serial : Seria.available() que es un booleano. una función que lee el puerto serie para comprobar si hay algo que se haya envíado, si lo hay es True y en caso contrario es False.

Luego tenemos la función llamada Serial.parseInt() que nos entrega lo que se escribe en el monitor serie convertido a entero, si le pasamos texto nos devuelve un cero y si le pasamos un número decimal, nos devuelve la parte entera y a continuación como  si de un entero se trarara la parte decimal convertida en un número entero.

    

Este programa simplemente recibe en la variable x los números que se teclea en la consola del Monitor serie y (cuando pulsemos intro) la estamos enviando al interior de arduino que las va a procesar y devolverá el resultado al monitor serie

Para leer un String del puerto serie tenemos que complicarnos un poco más y hablar del tipo char. Es  importante comprender la diferencia, entre char y String.

char es un tipo que representa un único carácter y se define con comillas simples

String es un tipo que representa una cadena y se define con comillas dobles:

char  c = ‘a’  ;
String s =”a”  ;

Aunque parezca lo mismo no lo son, para C++ son muy distintos.

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:



En el siguiente programa utilizaremos una nueva intrucción bastante utilizada de C++ llamada while.

while al igual que if ... else es una intrucción que nos ayuda a modificar el flujo de intrucciones, su traducción viene a ser "mientras" y se trata de un bucle, repite el bloque de código de su interior mientras se cumpla la condición que tiene entre los paréntesis, y dejará de ejecutar dicho código cuando al condición ya no se cumpla.

     while ( condición)
                 {   ……… }
El siguente programa se crea dos variables, una tipo char y otra tipo String, La condición del primer if es que no se esté recibiendo nada desde arduino. Entonces se entra dentro de bucle de while, que se repetirá hasta que pulsemos intro y aparezca "\n". Con Serial.read() arduino lee cada caracter que le llega, espera 25ms y lo concatena dentro de la variable String, y repite el proceso. Cuando se pulsa el intro se ejecuta el Serial.println() imprimiendo el mensaje en el monitor serie, y vaciando la variable String para el siguiente mensaje.
IMPORTANTE     
El motivo del delay(25) es que a una velocidad tan lenta, enviar un char de 8 bits por el 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 (y os recomiendo la prueba) leerá un carácter bueno (de la palabra escrita y como 10 caracteres basura para un Arduino UNO o Mega que se reflejará en el monitor serie como muchos interrogantes entre cada letra).

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 y no sería necesario el delay(25)


y con todas estas prueba, habremos aprendido a utilizar el monitor serie en ambos sentidos, tanto para recibir datos de arduino como para enviarles datos a propio arduino cuando este está funcionando.