Define una frecuencia de ejecución fija en Arduino

Ver en Github

Vamos a abordar un tema que he notado confunde a muchos principiantes en Arduino y la electrónica en general, el de cómo y por qué es preferible disponer de una frecuencia de trabajo fija a la que opere el loop de nuestro Arduino.

De por sí, Arduino ejecutará el código en el bucle, el loop, lo más rápido posible, ejecutando cada instrucción según su reloj interno, que sí funciona a una frecuencia fija. El problema surge cuando el código se complica y aparecen condiciones que no siempre ocupan el mismo número de pasos, y, por lo tanto, de tiempo. Cosas como:

  • Condicionales que dirigen el flujo de ejecución del programa por una rama u otra, tardando más o menos. Cosas como if, while, for
  • Trozos de código que esperan hasta que reciben un valor de un sensor u otra fuente;
  • interrupciones, por su propia naturaleza pueden ejecutarse en cualquier momento y alargar el tiempo de ejecución de un bucle en concreto.

Obviamente existen más condiciones, pero nos hacemos una idea, pero, ¿por qué es esto importante? Si dependemos de un ciclo de ejecución preciso, porque queremos que Arduino haga algo exactamente cada cierto tiempo determinado, esto nos podría causar problemas. Hablo de cosas desde implementar un lazo de control hasta de encender o apagar un LED cada exactamente 20ms.

¿Y Delay?

Es un error común entre los principiantes. El comando delayúnicamente pospone el siguiente comando el tiempo asignado, por lo que no tenemos control en absoluto sobre el tiempo de ejecución del resto del bucle. En principio, se deberían evitar los delayssiempre que se pueda, pues casi siempre se pueden sustituir por alternativas superiores. Aunque a veces si tiene sus usos, como cuando queremos sincronizar una serie de acciones y no nos importa la frecuencia de ejecución del bucle principal.

Millis

El método que utilizaremos está basado en el comando millis, que nos devuelve, en milisegundos, el tiempo transcurrido desde que el Arduino comenzó el programa.

millis() - Arduino Reference
The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.
Referencia del comando millis() de Arduino.

Podemos utilizar este comando para comparar el tiempo actual con una referencia tomada anteriormente y ver si se cumplen las condiciones para avanzar al siguiente bucle:

Ver en Github
unsigned long t0;

void setup(){
  t0=millis();
}

void loop(){
  //tu codigo aquí
  while(millis()-t0<20);
  t0=millis();
}
Ejecutamos loop cada 2 segundos.

Lo que hacemos es primero definir una variable de tipo «unsigned long» para almacenar el resultado de millis. Después utilizamos esta variable para comprobar si el número de milisegundos transcurridos (millis) menos el tiempo de referencia (t0) es mayor que el umbral que hemos definido, en este caso 20, así que 20 milisegundos. Introducimos esta condición dentro de un bucle while vacío, por lo que el programa esperará hasta que se cumpla esta condición antes de avanzar. Una vez se cumpla esta condición, establecemos t0como el tiempo en ese mommento y el bucle vuelve a comenzar.

Siempre que la ejecución del programa sea más rápida que el tiempo que usamos de umbral, el bucle se ejecutará cada tanto tiempo.

Podemos aplicar el mismo principio para encender y apagar un LED, como ejemplo de aplicación:

Conectamos un LED y una resistencia para controlar la frecuencia de encendido.
Ver en Github
unsigned long t0;

void setup(){
  pinMode(8, OUTPUT);
  t0=millis();
}

void loop(){
  digitalWrite(8, HIGH);
  while(millis()-t0<2000);
  t0=millis();
  digitalWrite(8, LOW);
  while(millis()-t0<2000);
  t0=millis();
}
Código para encender y apagar el LED cada 2 segundos.

Simplemente alternamos entre encender y apagar el LED cada 2000 milisegundos, es decir, cada 2 segundos, utilizando el mismo esquema explicado anteriormente.

Conclusiones

Eso es todo, recuerda utilizar este mecanismo para definir bucles en tus próximos proyectos.


💡
En calidad de Afiliado de Amazon, obtengo ingresos por las compras adscritas que cumplen los requisitos aplicables

Si estás buscando una alternativa económica a Arduino, sobre todo si es la segunda o tercera placa, recomiendo las alternativas económicas de Elegoo que puedes encontrar en Amazon, tal y como explico en mi guía de compras:

Elegoo compatible Arduino UNO

Ver en Amazon