013
Interrupción del puerto serie
En el caso de utilizar, por ejemplo, la comunicación serie, tenemos algo parecido a una interrupción asociada a la recepción de datos. No es exactamente una interrupción porque, si recordamos, una interrupción detiene la ejecución normal del programa y ejecuta la función asociada a la interrupción.
En el caso de la interrupción del puerto serie, esto no sucede; lo que realmente ocurre es que el programa comprobará, cada vez que finalice el bucle void loop, si hay datos en el buffer de entrada del puerto serie y, si es así, se ejecuta una función:
•Existen unas funciones predefinidas para este tipo de uso, que son las funciones <<serialE-vent()>>.
•En el caso de que un Arduino tenga varios puertos, como es el Arduino Mega, cada puerto tiene su propia «interrupción», diferenciándose por la referencia del puerto serialEvent1(), serialE-vent2()…
•En el siguiente caso
•Esta función viene a sustituir el if (serial.available())
•Esto último podemos probarlo con dos simples casos:
•En el primero
•En el segundo
Visto todo esto, la conclusión sería que podemos programar una función para la recepción de datos por el puerto serie que nos permite liberar código del bucle principal.
Pero, en un Arduino, no hay únicamente un tipo de comunicación; en los siguientes capítulos trabajaremos con las comunicaciones I2C y SPI y aí veremos que también tienen funciones para la recepción de datos.
Antes de estudiar estas comunicaciones, profundizaremos en el lenguaje de programación de la comunicación serie. Son muchos los módulos que utilizan esta comunicación; para establecer una comunicación eficiente, será imprescindible un buen dominio del lenguaje de programación.
Aunque los módulos ya adaptados para Arduino seguro que tienen sus propias librerías con las que conseguimos establecer de forma fácil una comunicación, existen muchos otros dispositivos que no tendrán una librería para Arduino y es ahí donde será necesario conocer ciertas peculiaridades de la comunicación serie.
014
Comunicación serie Serial.flush, Serial.availableForWrite
Serial.flush():
Al usar «print», «println» o «write», la transmisión de datos se realiza de forma asíncrona. Esto quiere decir que se ejecuta la siguiente instrucción sin asegurarse de que se empiece el envío de datos.
Esta cuestión se soluciona si, después de cualquiera de las tres instrucciones anteriores (print, println o write), escribimos <<Serial.flush()>>. Esta instrucción no devuelve nada, pero bloquea el programa hasta que el buffer de salida se haya vaciado, lo que significa que se han enviado todos los datos:
1.Para comprobar esto, probamos a enviar un mensaje y capturar el tiempo que tarda en ejecutarse el programa.
2.El tiempo que tardaría el programa en escribir el mensaje en el buffer de salida serían de 220 microsegundos
3.Ahora haremos lo mismo pero añadiendo la instrucción <<Serial.flush()>>.
4.En este caso, el tiempo es notablemente superior, ya que se fuerza al programa a detenerse hasta que se haya enviado toda la información
Serial.availableForWrite():
Esta instrucción devuelve el número de bytes libres en el buffer de salida; esto nos va a permitir recalcar lo que hemos visto en el punto anterior: el buffer dispone de 63 posiciones y, al ejecutar las instrucciones <<Serial.print>>, <<println>> o <<write>>, lo que se hace es escribir datos en el buffer, pero ello no significa que se hayan enviado, cosa que sí conseguimos con <<Serial.flush();>>:
1.Volvemos a enviar el mensaje anterior, pero de esta vez sin añadir <<Serial.flush()>>.
2.Si, a continuación de la instrucción <<Serial.println()>>, comprobamos el número de caracteres libres que hay en el buffer de salida, nos indica que 33
3.Ahora hagamos lo mismo pero asegurándonos con la instrucciones <<Serial.flush()>> de que se vacía el buffer de salida.
4.En este caso, nos devuelve el valor 63, por lo que el buffer está completamente vacío, lo que significa que se ha enviado todo el mensaje
Con todo esto, acabamos de analizar en profundidad el proceso de transmisión de datos por parte de un Arduino utilizando la comunicación serie. Antes de continuar con el siguiente capítulo, cabe mencionar que, en caso de querer enviar un mensaje de más de 63 caracteres, pongamos, por ejemplo, que esté formado por 90, tanto la instrucción <<Serial.print()>> como <<Serial.println()>> sí que esperan a poder escribir los 90 caracteres en el buffer.
Esto implicaría que se escribirán los 63 primeros caracteres del mensaje y, según vayan quedando espacios libres porque el buffer los transmite, la instrucción va soltando los caracteres pendientes, así hasta que suelte los 27 que le quedan pendientes y, en ese caso si, que continúa con la ejecución del programa, quedando pendientes de envío en