Etiquetas: ,

Para superar los problemas generados por el uso de la función delay(), una posible solución es utilizar la función millis(). Desde el primer uso del Arduino, la función delay() se utiliza para gestionar las instrucciones en función del tiempo. El mayor problema de la función delay() es que bloquea la ejecución de la secuencia de códigos. Esto se vuelve muy limitante cuando se trabaja con varios componentes (gestión de varios LEDs o sensores). Veremos en este tutorial cómo utilizar la función millis() para reemplazar la función delay().

Descripción de la función millis()

La función millis() no toma ningún parámetro y devuelve un valor que representa el número de milisegundos desde que se encendió el Arduino. El valor es largo sin signo (largo sin signo, 4 bytes o 32 bits). El valor máximo que puede tomar es de 4.294.967.295 o 49 días.

N.B.: También está la función micros() que funciona con el mismo principio pero devuelve microsegundos.

void setup() {}

void loop() {
  Serial.print("Milliseconds since ignition: ");
  Serial.println(millis())
  delay(200);
}

Reemplazar delay()

En los primeros ejemplos de Arduino, la función delay() se utiliza para ejecutar un bloque de código periódicamente pero no es su propia función ya que bloquea la ejecución del código. La función millis() es mucho más adecuada para esta función.

Tomemos el ejemplo de Blink otra vez. Utilizamos la función de retardo para hacer parpadear un LED cada 200 milisegundos.

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

void loop() {
  digitalWrite(13,HIGH);
  delay(200);
  digitalWrite(13,LOW);
  delay(200);
}

Para reemplazar este código por una estructura con millis(), la idea es crear una variable para mantener en memoria en cada iteración el valor de tiempo transcurrido y luego compararlo con el valor de tiempo actual. En cada intervalo, invertimos el estado del led con el operador «!».

unsigned long currentTime=0;
unsigned long previousTime=0;
bool ledState=LOW;

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}

void loop() {
  currentTime=millis();
  if((currentTime-previousTime)>200){
    previousTime=currentTime;
    ledState=!ledState;
    digitalWrite(13,ledState);
    Serial.print(F("LED State : "));Serial.println(ledState);
  }
}

Recreamos el ejemplo del parpadeo con, además, la posibilidad de ejecutar el código aunque el intervalo de tiempo no haya transcurrido. En este código, el led se encenderá y apagará cada 200ms.

Definir diferentes intervalos de tiempo

En caso de que desee tener ciclos de encendido y apagado del LED con tiempos diferentes, es posible cambiar el intervalo de tiempo dependiendo del estado del LED.

unsigned long currentTime=0;
unsigned long previousTime=0;
unsigned long interval,interval1=200, interval2=1000;
bool ledState=LOW;
void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}

void loop() {
  currentTime=millis();
  if(ledState){
    interval=interval2;
  }else{
    interval=interval1;
  }
  if((currentTime-previousTime)>interval){
    previousTime=currentTime;
    ledState=!ledState;
    digitalWrite(13,ledState);
    Serial.print(F("LED State : "));Serial.println(ledState);
  }
}

Este código permite que el LED se encienda durante 200ms cada segundo.

Ve más allá

Es importante señalar que la función millis() utiliza temporizadores internos del microcontrolador y puede ser interrumpida por el uso de interrupciones u otras librerías.

Para pasar a un nivel de programación más avanzado, es posible utilizar las bibliotecas de gestión de temporizadores (Timer.h,Timer2.h, TimerOne.h, etc.)

También es posible jugar con los registros del microcontrolador para configurar los temporizadores internos.

Fuentes