Me pregunta un alumno:

¿Arduino es multitarea? Es decir, si tenemos una aplicación que realiza dos o más tareas al mismo tiempo (por ejemplo, leer señales de entrada, encender un led…) y le aplicamos un retardo Delay() a alguna de las tareas ¿inevitablemente se detienen todas las tareas hasta que transcurre el tiempo de retardo? ¿Existe alguna forma de ejecutar varias acciones de forma independiente sin que el retardo de una afecte a la otra?

La respuesta a la pregunta es que se pueden hacer varias cosas, usando una programación algo más complicada que la normal, pero no mucho. Por más complilcada me refiero a que si detenemos el programa con un delay el procesador se detiene hasta que pase ese tiempo.

Existen varias formas de hacer varias cosas mientras esperamos que pase un tiempo pero todas ellas requieren algo más de programación. Vamos a verlas:

  • Podemos anotar el tiempo (como si miráramos la hora) actual usando una función que se llama millis() y calculamos en qué momento tenemos que hacer la siguiente tarea. Cada cierto tiempo miramos el tiempo y vemos si ya es el momento de hacerlo.

Este sería un ejemplo de cómo hacerlo:

long tiempoactual=millis();  // Anotamos el tiempo actual
long tiempoAlarma=tiempoactual+2000; // 2 segundos después
while(millis()<tiempoAlarma) // Mientras no sea el momento de la alarma haz otras cosas
{
 // Revisa la entradas
 // Activa las salidas
}
  • Podemos usar lo que se conoce como interrupciones: existen las interrupciones de software (que programamos para que se ejecuten cada cierto tiempo) y las de hardware (que se activan cuando determinado pulsador se activa) indicando qué codigo queremos que se ejecute cuando se produzcan estos eventos.
  • Podemos usar otro tipo de programación para arduino (basado en otro bootloader) que permite trabajar directamente con diferentes programas y/o tareas al mismo tiempo, como por ejemplo Duinos

Por supuesto que siempre se pueden combinar varios métodos: si se necesita una respuesta muy rápida a unos pulsadores se puede utilizar las interrupciones hardware (por ejemplo un botón de paro de emergencia), si además hay una tarea que realizar cada x milisegundos usaremos una interrupción software (que actúa como un temporizador), etc.

Por otro lado si tenemos una tarea lenta, como dices un acceso a internet, no es lenta porque haya que calcular nada, sino porque los datos llegan poco a poco y para eso no es necesario estar esperando sin hacer nada sino que podemos estar haciendo otras cosas. El esquema es el mismo que antes. Un código esquemático de ejemplo:

long tiempoactual=millis();  // Anotamos el tiempo actual
long tiempoAlarma=tiempoactual+2000; // 2 segundos después
while(millis()<tiempoAlarma) // Mientras no sea el momento de la alarma haz otras cosas
{
    recibeDatosInternet(); // Se comprueba se hay datos y si es así se lee 
    if(datosCompletosInternet) 
       ProcesaDAtos(); 
       verificaEntradas(); 
       activaSalidas(); 
}


Actualización: 25-5-2015: Existen librerías que permiten simular la multitarea utilizando el concepto de Thread o hilo, como por ejemplo la librería ArduinoThread y mThread. Por supuesto que no se trata de unos hilos reales (en el sentido de que funcionan como «procesos» separados), sino que lo simulan, facilitando el uso de ese paradigma de programación multitarea.

JAVACASM

AFAQ: ¿es Arduino multitarea?
Etiquetado en: