Portada_millis_delay

En este articulo analizaremos dos funciones que son utilizadas para determinar intervalos de tiempo.Las cuales son millis() y delay().

En Arduino  hay una función millis() que se emplea para medir tiempo. Está función te devuelve el tiempo en milisegundos desde que se inicio la placa Arduino cualquiera fuese el modelo. Una de los principales usos es el determinar el tiempo que ha pasado entre dos o más procesos del programa principal.

imagen a modo ilustrativa

            imagenes a modo ilustrativa

Uno de los tantos usos de la función del Arduino millis es la de averiguar el tiempo de ejecución en etapas criticas del código. Esto es para asegurar un tiempo real en la aplicación.

Es importante mencionar que el dato que regresa la función de Arduino millis(), require de una variable del tipo unsigned long. Si se usará otra más pequeña pueden ocurrir errores de lógica.

Sintaxis:

Variable = millis();

Requiere como entrada: Ninguno.

Devuelve la función:
Variable unsigned long. El valor de desbordamiento ocurriría a los 50 días “aproximado”.

 

Algunos Casos de Uso de la función millis() 

A- Primer Caso

Verificar cuando pasa un determinado tiempo ( en este caso dos segundos)

Se va usar de la función millis, se usará para calcular si ha pasado dos segundos. Entonces para lograr este propósito se requieren dos variables del tipo unsigned long para guardar dos eventos de tiempo. La primera variable, tiempo_A, guardará el tiempo antes de ejecutar a la función loop indefinidamente. Posteriormente y en cada iteración de la función loop, se medirá el tiempo transcurrido y se guardará en la variable tiempo_B. Para luego en una sentencia “if” hacer una evaluación. Dicha evaluación permitirá ver si el tiempo_B (Que se actualiza regularmente) ha superado a el tiempo inicial + 2000 milisegundos más. Esto indicaría que ha pasado dos segundos de tiempo en el microcontrolador de Arduino.

Si esta sentencia es verdadera, entonces se harán tres cosas:

  • Actualizar el tiempo_A, para continuar con el siguiente dos segundos.
  • Calcular el tiempo en segundos desde que se ha encendido el Arduino, es decir, millis()/1000. Recordemos que 1000 misegundos son 1 segundo.
  • Imprimir el tiempo en segundos desde que se encendió el Arduino usando millis().
unsigned long tiempo_A = 0;
unsigned long tiempo_B = 0;
unsigned long tiempoSegundos = 0;

void setup() {
  Serial.begin(9600);
  tiempo_A = millis();

}

void loop() {

  tiempo_B = millis();
  if(tiempo_B > (tiempo_A+2000)){  //Si ha pasado 2 segundos ejecuta el IF
    tiempo_A = millis(); //Actualiza el tiempo actual
    tiempoSegundos = tiempo_A/1000;
    Serial.print("El tiempo que ha transcurrido es: ");
    Serial.print(tiempoSegundos);
    Serial.println("  segundos desde que se ha prendido el ARDUINO");
    
  }


}

B- Segundo Caso

Cronometrar el tiempo entre dos mensajes seriales

Para este caso de uso, se utilizará a la función millis() para calcular el tiempo que ha transcurrido desde que un usuario ingresa la letra “A” o “a” y hasta que ingresa la otra letra “Z” o “z”.

unsigned long tiempo_A = 0;
unsigned long tiempo_B = 0;
unsigned long diferenciaTiempo = 0;
void setup() {
  Serial.begin(9600);
  Serial.println("Teclee la letra A o a por la terminal serial");
}

void loop() {
  if(Serial.available() > 0){
     char LetraRecibida = Serial.read();
     if(LetraRecibida == 'A' || LetraRecibida == 'a'){
        tiempo_A = millis();
        Serial.println("Envie la letra Z o z por la terminal Serial");
     }
     else if(LetraRecibida == 'z' || LetraRecibida == 'Z'){
        tiempo_B = millis();
        diferenciaTiempo = tiempo_A-tiempo_B;
        Serial.print("El tiempo transcurrido entre la primera letra enviada y la ultima es: ");
        Serial.print(diferenciaTiempo);
        Serial.println("Envie la letra A o a por la terminal serial");
     }
     
    
  }
}

En cambio la función  delay()

Hace una pausa en el programa durante el tiempo en “milisegundos” especificado como parámetro de entrada. “Hay 1000 milisegundos en un segundo.”

Sintaxis

delay (ms)

Parámetros

Requiere como entrada

ms: el número de milisegundos para hacer una pausa. Es del tipo  unsigned long.

Devuelve :Ninguno

Algunos  Casos de Usos 

A- Apagar un led por un determinado tiempo (tres segundos en nuestro caso)

int ledPin = 13;    // LED conectado al pin digital 13 
void.setup () 
{ 
pinMode (ledPin, OUTPUT);   // se define el pin digital como salida 

void.loop() 
{ 
digitalWrite(ledPin, HIGH);      // enciende el LED 
delay(3000);                            // espera tres segundos 
digitalWrite(ledPin, LOW);      //apaga el LED 
delay( 3000 );                         // espera por tres segundos
}

B- Prender un Led con un botón un determinado tiempo  (en nuestro caso diez segundos)

En este caso de uso, se usará a la función de Arduino  delay() que al pulsar un botón se encienda un led durante 10 segundos, y luego se apague.

int pinBoton=10;
int pinLed=13;

void setup() {
  pinMode(pinBoton, INPUT_PULLUP); // boton

  pinMode(pinLed, OUTPUT);       //led 
}

void loop() {
  if (digitalRead(pinBoton) == LOW) // boton pulsado
  {
    digitalWrite(pinLed, HIGH); // encender led
    delay(10000); // esperamos diez segundos
    digitalWrite(pinLed, LOW); // apagamos led
  }
}

Este caso de uso  funciona correctamente, y en el caso de… ¿que pasa si queremos añadir un segundo botón que haga lo mismo con otro led?

int pinBotonA = 10;
int pinBotonB= 11;
int pinLedA= 12; 
int pinLedB= 13;


void setup() {
  pinMode(pinBotonA, INPUT_PULLUP); // boton A
  pinMode(pinBotonB, INPUT_PULLUP); // boton B
  pinMode(pinLedA, LOW);            //led A
  pinMode(pinLedB, LOW);            //led B
}

void loop() {
  if (digitalRead(pinBotonA) == LOW) // boton A pulsado
  {
    digitalWrite(pinLedA, HIGH); //encender led A
    delay(10000); // esperamos diez segundos
    digitalWrite(pinLedA, LOW); // apagamos el led A
  }
  
  if (digitalRead(pinBotonB) == LOW) // boton B pulsado
  {
    digitalWrite(pinLedB, HIGH); //encender led B
    delay(10000); // esperamos diez segundos
    digitalWrite(pinLedB, LOW); // apagamos led B
  }


}

Esto ya no funcionaría puesto que al pulsar el  botón A el código se quedaría esperando 10 segundos en el delay()  y durante ese tiempo no va a hacernos caso si pulsamos el botón B.

Para solucionar esto podemos utilizar la función millis(), esta función nos devuelve el número de milisegundos que han pasado desde que se encendió el arduino, de esta forma podemos comprobar periódicamente si ya ha pasado el tiempo suficiente para apagar el led.

int pinBotonA = 10;
int pinBotonB= 11;
int pinLedA= 12; 
int pinLedB= 13;
void setup() {
  pinMode(pinBotonA, INPUT_PULLUP); // boton A
  pinMode(pinBotonB, INPUT_PULLUP); // boton B
  pinMode(pinLedA , LOW);           //Led A apagado
  pinMode(pinLedB , LOW); //Led B apagado
}

unsigned long timerLedA = 0;
unsigned long timerLedB = 0;

void loop() {
  if (digitalRead(pinBotonA) == LOW) // boton A pulsado
  {
    digitalWrite(pinLedA, HIGH); //encender led A
    timerLedA = millis(); // asignamos los ms actuales al cronometro A
  }
  
  if (millis() - timerLedA > 10000) // comprobamos si han pasado mas de 10000 ms
  {
    digitalWrite(pinLedA, LOW); // si ya han pasado diez segundos apagamos el led A
  }
  
  if (digitalRead(pinBotonB) == LOW) // boton B pulsado
  {
    digitalWrite(pinLedB, HIGH); //encender led B
    timerLedB = millis(); // asignamos los ms actuales al cronometro B
  }
  
  if (millis() - timerLedB > 10000) // comprobamos si han pasado mas de 10000 ms
  {
    digitalWrite(pinLedB, LOW); // si ya han pasado 10s apagamos el led B
  }
}

Ahora si que funciona bien, al no utilizar delay() el bucle principal loop() no se interrumpe y por lo tanto sigue respondiendo al resto de botones y otras cosas que tengamos en nuestro programa. Fijate que para los cronometros he usado el tipo de dato unsigned long, es importante usar este tipo de dato ya que la función millis() devuelve valores muy grandes y no caben en una variable de tipo int, por lo tanto puede producir resultados no esperados.

Aclaración:
Si bien es fácil utilizar la función delay(), y muchos programas utilizan retardos cortos para tareas tales como supresión de rebotes de un interruptor, el uso delay() en un programa tiene inconvenientes significativos. Ninguna lectura de los sensores, cálculos matemáticos, o la manipulación de pines puede seguir durante la función delay(). Para enfoques alternativos para controlar del tiempo ver la función millis (). Los programadores con más conocimientos por lo general evitan el uso de delay () para la sincronización de los eventos de más de 10 milisegundos a menos que el programa Arduino sea muy simple.

Ciertas cosas no funcionan mientras que la función delay () está controlando el chip ATmega, debido a que la función delay() no deshabilita las interrupciones. La comunicación serie que aparece en el pin RX se registra, PWM ( valores analogWrite) y los estados de los pines se mantienen, y las interrupciones funcionarán como es debido.

Conclusión
La función delay() es una manera rápida y sencilla que nos permite hacer esperar al arduino un tiempo determinado, sin embargo tiene los inconvenientes de que bloquea el bucle principal del programa y además no ahorra energía. Usa esta función siempre que esto no sea un problema en tu proyecto, de lo contrario debes buscar una alternativa de las que hemos comentado en este artículo.

Saludos Ditecno Makers . Hasta la próxima Daniel 

views
605


ElectroMercado

  • : tutorial_de_proyecto
  • arduino
1 Comentario
  1. Maqui
    Maqui 8 meses

    Hay también una librería Time la desarrollo Arduino, aunque no viene por defecto en el ide de Arduino. Para usarla solo hay que instalarla según el procedimiento normal de instalación de librerías. https://github.com/PaulStoffregen/Time

    1+

Contesta

CONTACTANOS

Esta es su red social de tecnología para compartir tus ideas y proyectos .Puedes enviarnos un correo si tienes dudas.Nos vemos

Enviando

Inicia Sesión con tu Usuario y Contraseña

o    

¿Olvidó sus datos?

Create Account