Retardos de tiempo en Arduino: Delay, Millis y Micros

Los retrasos en Arduino son muy importantes. Sin ellos, incluso el ejemplo más simple de Blink, que parpadea con un LED en un momento dado, no funcionaría. Pero la mayoría de los programadores novatos saben poco acerca de los retardos de tiempo y sólo usan el retardo de Arduino, sin conocer los efectos secundarios de este comando. En este artículo analizaremos en detalle las funciones temporales y las peculiaridades de su uso en el IDE de Arduino.

Funciones de tiempo en Arduino

Hay varios comandos diferentes en el Arduino que son responsables de trabajar con tiempo y pausas:

  • delay()
  • delayMicroseconds()
  • millis()
  • micros()

Cada una de ellas difiere en su precisión y tienen sus propias peculiaridades que deben tenerse en cuenta al escribir el código.

Usando la función de retardo de arduino

Sintaxis

El delay de Arduino es el comando más fácil y el más utilizado por los principiantes. De hecho, es un retardo que detiene la operación del programa por el número de milisegundos especificado entre paréntesis. (Un segundo tiene 1000 milisegundos.) El valor máximo puede ser 4294967295 ms, que es aproximadamente el equivalente a 50 días. Veamos un ejemplo sencillo que muestra cómo funciona este comando.

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);   // Evía una señal HIGH al pin 13
  delay(10000);             // Pausa por 10000ms o 10 segundos
  digitalWrite13, LOW);     // Envía una señal LOW al pin 13
  delay(10000);             // Pausa por 10000ms o 10 segundos
}

En la configuración del método escribimos que el pin 13 se usará como salida. En la parte principal del programa, primero se da una señal alta al pin, luego hacemos un retardo de 10 segundos. En este momento, el programa se suspende. Entonces se da una señal baja y se repite el retardo y todo vuelve a empezar. Como resultado, obtenemos que el pin se alimenta alternativamente 5 V y luegocon 0 V, encendíendose y apagándose.

Debemos tener claro que durante la pausa con la funcion delay el programa se suspende, la aplicación no recibirá ningún dato de los sensores. Esta es la mayor desventaja de usar la función de retardo en Arduino. Este problema se puede eludir con la ayuda de interrupciones, de las que hablamos en este artículo.

Función DelayMicroseconds

Esta función funciona igual que Delay, salvo que su unidad de medida es en microsegundos en lugar de milisegundos (10000000000 microsegundos en 1 segundo). El valor máximo es 16383, que es de 16 milisegundos. La resolución es 4, es decir, el número siempre será múltiplo de cuatro. Un ejemplo se verá así:

digitalWrite(2, HIGH);    // Señal HIGH al pin 2
delayMicroseconds(16383); // Pausa por 16383 μs
digitalWrite(2, LOW);     // Señal LOW al pin 2
delayMicroseconds(16383); // Pausa por 16383 μs

El problema con delayMicroseconds es exactamente el mismo que con delay – estas funciones «cuelgan» completamente el programa y literalmente se detiene por un tiempo. En este momento es imposible trabajar con puertos, leer información de sensores y realizar operaciones matemáticas. Esta opción es adecuada para hacer parpadear un led, pero no se utilizan en proyectos grandes o avanzados, ya que no hay necesidad de limitarse de tal forma. Por lo tanto, es mucho mejor utilizar las funciones que describimos a continuación.

Función millis() en lugar de delay()

La función millis() nos permite hacer un retraso sin detener el programa de Arduino, evitando así las desventajas de los métodos anteriores. El valor máximo del parámetro millis es el mismo que para la función delay (4294967295ms o 50 días). Cuando se produce un desbordamiento, el valor se restablece a 0.

Con millis, no detenemos la ejecución de todo el sketch, sólo especificamos cuánto tiempo Arduino deberá «puentear» el bloque exacto  de código que queremos pausar. A diferencia de delay, millis no detiene nada.

Este comando simplemente devuelve el número de milisegundos transcurridos desde el inicio del microcontrolador desde el temporizador incorporado. Medimos el tiempo transcurrido desde la última llamada de nuestro código y si la diferencia horaria es menor que la pausa deseada, ignoramos el código.

Tan pronto como la diferencia sea mayor que la pausa requerida, ejecutamos el código, obtenemos la hora actual con la ayuda de los mismos milis y la recordamos – esta vez será un nuevo punto de referencia. En el siguiente bucle la cuenta atrás será desde el nuevo punto y volveremos a ignorar el código hasta que la nueva diferencia entre milis y nuestro valor previamente guardado alcance la pausa deseada.

El uso de millis requiere más código que delay, pero se puede utilizar para hacer parpadear el LED y pausar el sketch sin detener todo el sistema.

Aquí puedes ver un ejemplo de como funciona:

unsigned long timing; // Variable para almacenar el punto de referencia void setup()
void setup() {
 Serial.begin(9600);
}

void loop() {
/* Aquí es donde comienza a correr el retardo, calculando la diferencia entre el momento actual 
y el punto de referencia guardado anteriormente. 
Si la diferencia es mayor que el valor deseado, ejecutamos el código. 
Si no, no hacemos nada
*/
 if (millis() - timing > 10000){ // En lugar de 10000, ajusta el valor de pausa que deses
  timing = millis(); 
  Serial.println ("10 segundos");
 }
}

Primero introducimos una variable, que almacenará el número de milisegundos. Por defecto, el valor de la variable es 0. En la parte principal del programa comprobamos la siguiente condición: si el número de milisegundos desde el inicio del microcontrolador menos el número guardado en la variable de tiempo es más de 10000, entonces la acción de emitir el mensaje al monitor del puerto se realiza y el valor de tiempo actual se escribe en la variable. Como resultado de la operación del programa, cada 10 segundos se mostrará el mensaje en el monitor del puerto. Este método permite que el LED parpadee sin detener la ejecución del programa.

La función micros() en lugar de delay()

Esta función también puede ejecutar un retraso sin utilizar la función delay. Funciona de la misma manera que millis, pero no cuenta en milisegundos, sino en microsegundos con una resolución de 4μs. Su valor máximo es de 4294967295 microsegundos o 70 minutos. En caso de un desbordamiento, el valor se restablece a 0.

En Resumen

Arduino nos proporciona varias formas de realizar los retardos en nuestros proyectos. Con el delay se puede detener rápidamente la ejecución de un sketch, pero al mismo tiempo bloquear el microcontrolador. El uso del comando millis permite pausar un bloque de código sin detener completamente todo el programa, pero necesitaremos un poco más de programación. Elije la mejor opción dependiendo de la complejidad de tu proyecto. Por lo general, en los programas simples y con un retraso de menos de 10 segundos se utiliza delay. Si nuestro proyecto es más complejo y requiere más retardo, será mejor usar la función millis.