Multi tarea en arduino

Mi pregunta es sencilla. Arduino soporta multitarea? Si es asi, cómo puedo abrir más de un proceso?

Bueno, tampoco es una pregunta tan sencilla.... :grin:

Existen RTOS para atmel.
En concreto hay un proyecto para Arduino llevado por RobotGroup (DuinOS).
http://www.multiplo.org/duinos/wiki/index.php?title=Main_Page
No es tan facil como lanzar un thread en un lenguaje de alto nivel para PC.... :wink:

Saludos

Igor R.

Como se han podido dar cuenta son bastante novato en esto de Arduino, mi pregunta es ¿Como que multitarea? hasta donde tengo entendido para manejar una arquitectura multitarea se necesitan dos procesadores. Un procesador no importa lo sofisticado que sea solo puede realizar una tarea al mismo tiempo, (sin tomar en cuenta los dual core y quad core que supongo que ya son dos procesadores en uno, pero físicamente DOS)

A lo que a mí me da entender los conocimientos de arquitectura computacional los procesadores pueden hacer miles de operaciones por segundo pero solamente una a la vez y nos da la impresión que pueden hacer dos o más pero en realidad es solamente una por cada vez

Y en arduino lo que creo que nos puede simular la multitarea sería la velocidad del reloj.

Corríjanme si estoy mal :slight_smile:

Lo dices bien. Como siempre, hay un "pero"..... :smiley:
Sin entrar en muchos detalles:

  1. La mayoria de veces un micro esta esperando sin hacer nada.
  2. Normalmente tu programa necesita ir atendiendo diferentes tareas a diferentes frecuencias (por ejemplo, refrescar un lcd cada 200 ms, leer pulsadores cada 50 ms, ... por decir algo).
  3. El micro es "tan rapido" que podria ir haciendo diferentes pequenyas partes de codigo, que no alteren el resultado final y tu programa no se quede "esperando" hasta poder hacer la siguiente tarea.
  4. Un microcontrolador es un micro + modulos hardware (UART,TIMERS, RTC,...) que son "independientes" entre si.

Ejemplo:
Serial.print(loquesea) => al final pasa por la funcion write que pongo abajo.

Extraido de HardwareSerial.cpp de Arduino core.

void HardwareSerial::write(uint8_t c)
{
  while (!((*_ucsra) & (1 << _udre)))
    ;

  *_udr = c;
}

Resulta que en Arduino, esa funcion se queda parada hasta que comprueba un flag del registro de la UART que dice que se ha enviado. Haz las cuentas lo que pasa a 9600 baudios si quieres enviar multitud de informacion....
Pues un "truco" seria ir comprobando dicho flag mediante "polling" si ya se ha enviado, y en el caso de que no, sigues haciendo mas cosas, pero si se ha enviado, pues copias el siguiente byte a enviar en la UART. En vez de tener un while que deja "parado" al micro. Ya que el micro y la UART pueden ir trabajando independientemente. Y no tiene sentido que el micro este esperando a que se termine de enviar el dato, cuando de mientras podria estar haciendo otras operaciones.

No se si me he explicado bien.... Aqui hice un post del Timer 2, conmutando dos pines de Arduino a diferentes frecuencias: Tinkering with Electronics...: Timer 2: Introducción
El ejemplo es la filosofia (en facil) de lo que hace un RTOS. Es decir, si puedes estar contando un evento con un timer, mientras envias datos por serie, mietras recibes por CAN y tu micro estar haciendo otra operacion.
En dicho ejemplo, el micro se pasa la mayoria del tiempo sin hacer nada!!

Saludos

Igor R.

con un único procesador se puede hacer trabajar en multitarea. Como dicer IGOR lo que tiene que hacer el soft es repartir el procesador entre todo lo que quieres hacer. Se puede hacer con interrupciones, con prioridades,... o como quieras. Por supuesto, cuanto más cosas hagas al "mismo" tiempo, más lento irá todo.

Hay que reconocer que si es cierto lo que dice RoAcHmx que un procesador solo puede ir haciendo secuencialmente una cosa detras de otra.
Pero hay que recordar, que no tenemos un procesador simplemente. Dicho procesador dispone de modulos independientes. Como son el ADC, UART, TIMERS, ...
Por lo que tu procesador puede estar haciendo una unica tarea, pero los otros modulos seguir haciendo otras. Y un porcentaje muy grande de tiempo, son dichos modulos los que estan haciendo el "trabajo duro" y el procesador esta de "siesta".

Por otro lado, todo esto es para cumplir un control en "tiempo real", que es algo que es dependiente del proceso a controlar. Si tengo que controlar la temperatura de una habitacion con un calefactor, mira si tengo minutos para seguir haciendo otras cosas antes de tener que "actuar" sobre el sistema. Es decir, estoy haciendo "multiples" tareas....

Ya dije, que no era una pregunta "sencilla" XD XD XD

:wink:

Pensaba que era sencillo de entender lo que preguntaba, asi que reexplicaré mi problema:

Lo que yo quiero es tener dos procesos que se ejecuten simultáneamente. El primero, que acceda a una matriz global que guarda el estado de los leds (si está encendido o no, y su color) y refresque la matriz de leds conforme a esa array. El segundo, controlará la animación que quiero ejecutar.

¿Hay alguna forma de hacerlo en procesos separados, o tengo que montármelo para que funcione todo en el mismo bucle?

Claro que es sencillo de entender....si no te satisfacen los post anteriores, entonces la respuesta a tu pregunta supongo que es "NO" se puede....

:wink:

Nota.- Si hay forma de hacerlo en procesos separados. Procesos separados != Procesos paralelos.
Puedes usar un timer para que controle el flujo de tu programa, que vaya haciendo cada vez parte de cada proceso y asi sea un "pseudoparalelo" (para entendernos).

Me temo que no entiendo esa nota. Sería algo así como: Si marca par me haces una cosa, si marca impar me haces otra. Algo así?

Para entendernos, se pueden hacer dos,tres,cuatro,.... tareas/procesos paralelos.
Todo depende del "refresco" que necesite cada una para cumplir dichas tareas en los tiempos apropiados (como bien dijo pacojarcia).

Que el micro haga una intrucción cada vez, no significa que no sea suficientemente rápido como para poder llevar acabo diferentes tareas. (esto solo hablando de micro, sin entrar en los otros modulos de los que dispone un microcontrolador).

Lo que no existe un comando como en un lenguaje en alto nivel que se encargue de hacer eso por ti, simplemente lanzando diferentes threads. Ten en cuenta que estas trabajando a muy bajo nivel, aunque el lenguaje Arduino haga la vida más sencilla.

Para entender ésto, intenta hacer un programa sencillo: Mediante comandos de digitalWrite ir conmutando dos pines de arduino a on/off a diferentes frecuencias. Asi entenderás la problemática (ya te aviso, que el típico error es usar al función delay()=parar el micro ).
Es decir, trata de sacar esto por dos pines:

:wink:

Truco.- Función millis()