Curso Arduino y robótica: Eventos temporales

Antes en un ejercio anterior, definíamos un evento puntual discreto como aquel que era independiente del tiempo. En este tutorial vamos a ver todo lo contrario, vamos a ejecutar una serie de eventos definidos temporalmente y qué tipos de eventos podemos realizar.

Recordamos que nuestro objetivo principal es ejecutar correctamente el programa sin bloqueos, sin delays y que las instrucciones no se ejecuten siempre dentro del bucle.

Eventos temporales

Los eventos temporales son aquellos que dependen del tiempo y deben ejecutarse dentro del bucle, pero requieren de un control de tiempos, ya que nuestra placa Arduino estándar realiza operaciones a 16Mhz ( 16 millones de operaciones por segundo ).

Aunque realmente no sepamos cuántas operaciones se realizan en cada instrucción, asumiremos en un principio que son suficientemente rápidas, como para ejecutarse de forma instantánea. De todas formas, podríamos medir los tiempos entre una y otra para comprobar  cuanto dura cada instrucción.

Estos modelos son la base de los sistemas de tiempo real.

Medir el tiempo

Para medir el tiempo, debemos hacer uso de variables auxiliares de memoria para que nuestra placa sepa en todo momento cuánto tiempo ha invertido en la última iteración del bucle.

A modo demostrativo, usaremos una función que representará que una instrucción tarda en ejecutarse dos segundos. Aunque aquí utilizamos un delay, queremos evitar precisamente esos bloqueos.

long current_time;

// Describe this function...
void process() {
  delay(2000);
}


void setup() {
  Serial.begin(9600);

  current_time = (long)(0);

}

void loop() {
  current_time = millis();
  process();
  Serial.println(current_time);

}

Por poner un ejemplo, los procesos que consumen más tiempo, son aquellos que realizan búsquedas en una lista de datos si el número de datos es muy grande, aunque también hay dispositivos de comunicación externos que invierten un tiempo en recibir y transmitir la información.

Ejecutar acción en un momento determinado

Si podemos medir el tiempo, entonces podríamos crear una especie de cronómetro para ejecutar una acción en el momento oportuno.

IMPORTANTE: para almacenar las variables temporales en milisegundos es conveniente utilizar el tipo de dato long, ya que si elegimos un tipo de dato con menor espacio de memoria saturara muy rapido. Un int solo almacenaría 32 segundos. Consultar el siguiente enlace, el timeline de Arduino.

En este primer ejemplo, podemos realizar un control en el que la acción no se ejecuta hasta que pasan 5 segundos, pero podremos observar que si solo ha de cumplir que el valor de tiempo leido sea mayor de 5000 milisegundos, la acción se repetirá indefinidamente pasados esos 5 segundos.

Por lo que la siguiente solución siguiente a realizar será una mezcla entre un evento temporal y un estado discreto, como podemos ver en el tutorial de eventos discretos.

Para simplificar disponemos de un bloque en Ardublockly que nos facilita todo este sistema y el código será el mismo que hemos creado anterioriormente.



int LEDpin;
boolean flag;
long current_time;

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

  LEDpin = (int)(3);
  flag = (boolean)(true);
  current_time = (long)(0);

}

void loop() {
  current_time = millis();
  if (current_time > 5000 && flag) {
    flag = false;
    digitalWrite(LEDpin, HIGH);
    Serial.println("LED ON");
  }

}

Cabe recordar que no tenemos referencia temporal. La placa empieza a contar el tiempo desde el momento que encendemos la placa. Para resolver esta cuestión de definir una hora, día, mes y año concretos necesitariamos avanzar con un reloj RTC.

 

Repetir en un intervalo de tiempo

Para repetir la acción en cada intervalo de tiempo es aún más sencillo para programar, pero en este caso definiremos una temporalidad en el valor de espera relativo al estado anterior.

En este caso ofrecemos dos soluciones que funcionan por igual.

En este caso definiremos la referencia relativa como la resta entre el estado actual y el estado anterior.


 

Pero para simplificar este modelo de eventos, hemos añadido un bloque adicional en Ardublockly para definir este salto de ejecuciones y así diseñar nuestros programas más fácilmente.



unsigned long flag;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if( millis() - flag > 5000){
    flag = millis();
    Serial.print("Time: ");
    Serial.println(millis());
  };

}


 

 


Una vez completado este tutorial, puedes acceder al siguiente nivel.

Puedes acceder además a los ejemplos de código que desarrollaremos durante el curso a través de nuestro Github.

Documentacion ZaragozaMakerSpace Github

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

14 + uno =

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.