Acabo de descubrir tu canal y este video me encanto, una explicación clara y sencilla de entender, felicidades, un cursillo de programación de Arduino contigo tiene que ser una maravilla, un saludo
Espectacular! Eso es algo que todos dicen que no se puede hacer y veo que si. Esto permite poder tener un semáforo encendido al mismo tiempo que una barrera se puede abrir o cerrar con un sensor (hablo de una maqueta de una ciudad por ejemplo.
Muy bien explicado, muchas gracias, hace dias que vengo buscando como tener un control de temperatura independiente, pero tambien poder prender la calefaccion cuando quiera. Creo que ahora si me sale!
Es la tercera vez que veo tu video, y me sigue pareciendo muy bueno, tienes el don de la didactica, te agradeceran muchos amantes de arduino algunas clases tan claras como la que has hecho. Muchas gracias.
Esta muy bien explicado, hay muchos videos de este tema que ayudan poco a comprender cómo abordar este tema, sin embargo este es genial y completa la explicación. Necesitamos más vídeos de este tipo para saber cómo abordar la programación de Arduino.
Me gusta como piensas las cosas y como las explicas....bien desarrollado... Me gustaría que hicieras un control a tres LDR con tres contadores de horas y totalmente independientes cada uno de los canales.
Muy bien Joven Rodri, ojala y pudieras subir mas videos de este tipo, para los q iniciamos en el mundillo de Arduino, sin mas me despido y agradeciendo esta pequeña muestra de lo q sabes; hasta otro momentito............bonito dia
Hola buenas. Me encantó la explicación. Estoy haciendo un invernadero inteligente y quería ver de usar esta funcionando ya que tengo que controla húmedad y temperatura
Si no te es mucha molestia. Estoy interesado en tus conocimientos y me gustaría usar estás función, y sumarle memoria EPROM para hacer distintas funciones y con el reloj de tiempo real.
Muy claro y bien explicado. Ahora, entiendo que esta forma de gestionar funciones es más eficiente que el uso de delay, pero no es "multitasking" (ni siquiera entre comillas) ya que la duración de cada thread o hilo dependerá de la cantidad de instrucciones que haya en su interior. Es una gestión eficiente de tiempos. El "multitasking" (o pseudo multi tareas) gestiona recursos de cada thread en tiempos cortos para cada uno. Cuando requerimos gestionar el programa en tiempo real, son programas más complejos que manejar leds. Así, las estructuras muy complejas tardarán mucho más que estructuras simples. Esto a su vez afecta el control preciso de los tiempos (por eso también usamos el tiempo real), es decir, si requerimos tiempos largos no hay mayor problema, pero si requerimos pocos milisegundos podría verse afectado el curso del programa...
Muy bueno Rodri! excelente como lo explicas, sos una persona muy agradable. Si me lo poermites y con todo respeto quiero aclarar un detalle para aquel que se puso a encodear como yo. En la version de ide de Arduino 1.8.15 no se puede usar directamente OFF como reemplazo de LOW, como tampoco ON en lugar de HIGH pero si se puede usar 0 y 1. Saludos !!!
Excelente video! Muy buena explicación y con un ritmo adecuado!! Chequearé el resto del canal! Sigue así... PD: a riesgo de equivocarme, puedo hacerte saber una errata: los datos de tipo long son de 32bits no de 64
Realmente muy, muy buen video. Fantásticamente explicado!! . Ha sido clave para mi, poder seguir con mi proyecto. Sigue así por favor. PD. ¿Tienes algún video o lo puedes hacer de como hacer un botón de emergencia ? Que pare todas las multitareas, como un reset.
La solución dependerá de cuál es exactamente el comportamiento que esperas y qué significa en este contexto "reset". Si la idea es un reset propiamente tal, puedes googlear Arduino software reset. Si a eso sumas interrupciones, podrás implementar un botón de emergencia que reinicie el sistema inmediatamente
muy bien explicado me sirvió mucho para entender como se utiliza esta función aunque tengo una duda el proyecto que estoy armando es de una incubadora y como voy a usar un relé lo que necesito es que encienda por un tiempo ejemplo: 1000 encendido y apagado 500... Y ningún video que encuentro explica como hacer eso si pudieras hacer un video explicándolo o dándome una solución respondiendo este comentario seria de mucha ayuda.... desde ya muchas gracias y disculpe mi intriga e ignorancia y lo felicito porque explica muy bien los videos lo cual hace que me ayuden muchísimo!!!
muy buen video hno, podrias hacer uno pero con moteres PAP ( 3 al mismo tiempo), tengo unos estantes en mi casa y quiero darles movimientos , osea que pueda darle la VEL y los PASOS y con un pulsador darle inicio y final de linea(si se corta la tension sigue hasta que baje ) (seguiran funcionando con ups hasta que llegue al final de linea( abajo), ya que lo estoy intentando y no logro entender cual es error.
Muy buen video y muy bien explicado, gracias. Me surge una duda en cuanto a las variables que definís como "static". Veo que usás el mismo nombre de variables en las 2 funciones. ¿El usar static hace que el programa no las confunda e internamente le asigna nombres distintos? Muchas gracias.
Muy bien tu explicación me podrás orientar para realizar un semáforo que el color verde parpadee tres veces y después de 5oo milis entre a parpadear solo el rojo gracias este
Un aporte, en lugar de asignar la ultima hora a la variable ultimo_estado, sumar el valor del periodo cada vez que se cumple, de esta forma se obtiene una periocidad mas uniforme por ejemplo if (hora - ultimo_cambio > 500) { ultimo_cambio += 500; estado = !estado; digitalWrite(4, estado); } De pronto aquí se podría incluir un control de desborde cuando el millis() llegue a su valor máximo. Otro punto a revisar es millis() es un tipo de dato unsigned long
Muy buen aporte. El primer led parpadea cada segundo y el segundo cada 250ms. Por eso hay suficiente tiempo para que se ejecuten los demas loops. Pero si el loopA ell led parpadea cada 250ms y el loopB cada segundo, podria haber retrasos en el parpadeo del led A. No?
Hola Rodri. Excelente video. De cualquier manera, si el sistema funciona en forma constante, en algún momento habrá desbordamiento del millis. ¿ Se perderá el "sincronismo" no? - ¿Solución?
acabo de aprender el tema de las variables dentro y fuera la función , estatic no me quedo claro porque no lo lleva a cero cada vez que entra a la funcion¿?¿? es proque asi lo dice el lenguajes? solo se da si esta al principio dela función? gracias por la s explicaciones
buena explicación , pero el uso del mils es un truco un poco lento para algunas aplicaciones; se podría usar otra forma con un retardo mas pequeño como microsegundos?
Desde ya muy buena y clara la explicación. Lo que si me gustaría hacerte una consulta con respecto a la necesidad o no de usar interrupciones cuando se quiere hacer "multitasking" y hay eventos externos de por medio. Noté que para el pulsador que enciende el LED C no usaste ninguna interrupción ¿Si el código fuese mas extenso sería necesario conectar el pulsador a una "entrada de interrupción" para asegurarnos que el micro la lea durante los momentos en que la misma está activa?. Disculpa si lo que pregunto es muy desatinado, pero me cuesta entender como es que sin usar interrupciones evitas que un evento demasiado veloz no pase desapercibido por el micro. Muchas gracias y saludos!
Hola Mariano, en lo absoluto desatinado... Lo que explico en este video tiene como hipótesis que los estímulos a los que estamos respondiendo son lo suficientemente lentos como para que tomen varias vueltas del loop principal y así este pueda detectarlos... Esta estrategia de consultar si está apretado el botón a cada rato es lo que se llama polling. En contraste, una interrupción detectará inmediatamente el evento y ejecutará el código asociado a esta, habitualmente una función (interrupt service routine o ISR) para después volver al flujo normal... La decisión de si usar polling o interrupción no depende de qué tan largo sea el código, sino que más bien de qué tan crítico es atender al evento inmediatamente y la velocidad del evento mismo... Las interrupciones son geniales para atender algo inmediatamente pero tienen la tremenda desventaja de que te desvían el flujo del programa de forma inesperada, por eso en general se recomienda evitarlas a menos que sean estrictamente necesarias... Es súper fácil crear errores muy difíciles de replicar, encontrar y corregir cuando un evento que entra aleatoriamente en tu código (la interrupción) desvía las cosas. En desarrollo de firmware, mucho más que en programación regular para un computador, lo que buscamos es determinismo y saber cuándo revisas algo en vez de que pueda llegar en cualquier momento es valioso. Obviamente hay situaciones en las que las interrupciones son la única solución, pero hay que usarlas con cuidado.
@@Rodri-Tech Muchisimas gracias por tu respuesta, me has ayudado mucho a encaminar lo que debería hacer. Ese era mi dilema a la hs de usar un micro para atender una interfas hm (lcd y un esconder) mientras ademas debia controlar motores y otros acutuadores, justamente leer en todo momento o usar interrupciones. Muy amable de tu parte, saludos!!
Perdón me explique mal Realice un semáforo empezando con el olor verde el cual primero prende por 2000milis y después, parpadea tres veces y pasa a amarillo y finalmente a rojo , posteriormente parpadean el rojo y amarillo esto los realice con los delay y creo que con multitasking funcionaria mejor aquí es donde te pido que me orientes gracias
hola, soy Hernán y me estoy iniciando en este mundo, tengo la tarea de asignar un tiempo a un motor, me explico, al presionar un botón quiero que un motor funcione un tiempo determinado y cuente ese pulso del botón y no encuentro como hacerlo, si pudieras ayudarme se agradecería
Rapasando el codigo, no entiendo para q se dieron de alta los #define (ON, OFF, TRUE, FALSE), supongo q es para q los recuerde el micro y los tenga presente, cuando se necesiten....muchas gracias
Esas definiciones son para hacer más fácil la lectura del código abajo por parte de un ser humano :)... El micro no llega a ver nada de eso, recuerda que los #define ALGO otra_cosa funciona como buscar y reemplazar como paso previo al proceso de compilación. Es decir, en el caso del ejemplo busca todas las apariciones de "ALGO" y las reemplaza con "otra_cosa", después de completar esa etapa se inicia la compilación propiamente tal.
Pero esto no es multiasking. Arduino no puede hacer multitarea. Es un simil multitarea, si, ahi estamos de acuerdo pero no es multitarea. RTOS o Freetos son opciones multtarea. Eso es simplemente usar millis() en un programa secuencial no bloqueante. Lo unico que has hecho es no bloquear el programa cosa que ocurre con delay(). Ademas hay un pequeño error no significativo porque el codigo va a funcionar pero siempre las varialbes relacionadas con millis() deben definirse como unsigned long no solo como long. Un long es 2^31 = 2 147 483 647 eso en dias seran algo como 49.7/2 o sea, cuando millis() tenga mas de 25 dias tu código falla. Aclaro que se que lo tienes claro, porque al final lo dices, pero es importante indicar que SI es la forma de programar en lo cual estoy 100% de acuerdo pero no es multitarea estricto.
Acabo de descubrir tu canal y este video me encanto, una explicación clara y sencilla de entender, felicidades, un cursillo de programación de Arduino contigo tiene que ser una maravilla, un saludo
excelente video!! muy bien explicado, hace ver todo esto mas sencillo. mil gracias. por favor continúa subiendo mas videos son muy buenos.
Te felicito de verdad. Gracias es genial. Espero ver muchos vídeos de Usted, Rodri.
Hermano agradecido explicación maravillosa exelente
Muy buena explicación te felicito, tanto por lo completo como por lo sencillo de trasmitir la idea. Sigue haciendo...
Espectacular! Eso es algo que todos dicen que no se puede hacer y veo que si. Esto permite poder tener un semáforo encendido al mismo tiempo que una barrera se puede abrir o cerrar con un sensor (hablo de una maqueta de una ciudad por ejemplo.
Encantado de haber encontrado este videotutorial.
Me han encantado sus explicaciones. Enhorabuena por su trabajo ;)
Muy bien explicado, muchas gracias, hace dias que vengo buscando como tener un control de temperatura independiente, pero tambien poder prender la calefaccion cuando quiera. Creo que ahora si me sale!
Rodri, muy buen trabajo, me ha gustado tu empatía a la hora de transmitir tus conocimientos, sigue así. Gracias y cuídate.
Es la tercera vez que veo tu video, y me sigue pareciendo muy bueno, tienes el don de la didactica, te agradeceran muchos amantes de arduino algunas clases tan claras como la que has hecho. Muchas gracias.
Esta muy bien explicado, hay muchos videos de este tema que ayudan poco a comprender cómo abordar este tema, sin embargo este es genial y completa la explicación. Necesitamos más vídeos de este tipo para saber cómo abordar la programación de Arduino.
Avia visto otros videos que la verdad nada que ver a la calidad de tu video lo explicas muy bien!!!
Clarísimo!!! Nunca mejor explicado! Gracias!
Felicitaciones, excelente desenvolvimiento en tu explicación, Muchas gracias
Porfin un tutorial donde no tengas que definir n variables de tiempo... Excelente.... Saludos
Excelente y clara explicación, evidentemente usted sabe y mucho de lo que habla. Muchas gracias por videos de esta calidad.
Me ha encantado la forma que lo explica y con la amabilidad que lo hace. Sin duda muy contento de haber encontrado este vídeo.
Fascinante tu sabiduría y tú humildad. Gracias!
Muy buena tu explicacion. Saludos desde Argentina
Me gusta como piensas las cosas y como las explicas....bien desarrollado...
Me gustaría que hicieras un control a tres LDR con tres contadores de horas y totalmente independientes cada uno de los canales.
Perfectamente explicado Gracias!!! He aprendido algo muy valioso
Muy bien Joven Rodri, ojala y pudieras subir mas videos de este tipo, para los q iniciamos en el mundillo de Arduino, sin mas me despido y agradeciendo esta pequeña muestra de lo q sabes; hasta otro momentito............bonito dia
¡Muchas gracias por la excelente explicación y por el ejemplo! Me han servido muchísimo.
ahora si entendí la función void loop, muchas gracias! no entendía su estructura hasta ahora! XD
Muy buena explicación, felicitaciones.
Excelente, me ayudo mucho tu explicación gracias por compartir conocimientos!!
Excelente explicación, muy claro, muchas gracias!!!
Felicitaciones un buen video y gracias por compartir tu conocimiento. Saludos.
muy buena explicación, 👍
Hola buenas.
Me encantó la explicación.
Estoy haciendo un invernadero inteligente y quería ver de usar esta funcionando ya que tengo que controla húmedad y temperatura
Si no te es mucha molestia.
Estoy interesado en tus conocimientos y me gustaría usar estás función, y sumarle memoria EPROM para hacer distintas funciones y con el reloj de tiempo real.
Muy buena metodología, una consulta que pasa cuando el timer se desborda y que resultado da la formula hora - ultimo cambio
excelente tutorial, gracias x compartir conocimientos verdaderamente utiles
Muy claro y bien explicado. Ahora, entiendo que esta forma de gestionar funciones es más eficiente que el uso de delay, pero no es "multitasking" (ni siquiera entre comillas) ya que la duración de cada thread o hilo dependerá de la cantidad de instrucciones que haya en su interior. Es una gestión eficiente de tiempos. El "multitasking" (o pseudo multi tareas) gestiona recursos de cada thread en tiempos cortos para cada uno. Cuando requerimos gestionar el programa en tiempo real, son programas más complejos que manejar leds. Así, las estructuras muy complejas tardarán mucho más que estructuras simples. Esto a su vez afecta el control preciso de los tiempos (por eso también usamos el tiempo real), es decir, si requerimos tiempos largos no hay mayor problema, pero si requerimos pocos milisegundos podría verse afectado el curso del programa...
Muy bueno Rodri! excelente como lo explicas, sos una persona muy agradable. Si me lo poermites y con todo respeto quiero aclarar un detalle para aquel que se puso a encodear como yo. En la version de ide de Arduino 1.8.15 no se puede usar directamente OFF como reemplazo de LOW, como tampoco ON en lugar de HIGH pero si se puede usar 0 y 1. Saludos !!!
Muchas gracias, me ayudo de mucho.
Gracias! justo justo lo que necesitaba.
Excelente video! Muy buena explicación y con un ritmo adecuado!! Chequearé el resto del canal! Sigue así...
PD: a riesgo de equivocarme, puedo hacerte saber una errata: los datos de tipo long son de 32bits no de 64
Muy bueno, gracias por compartir el conocimiento
Realmente muy, muy buen video. Fantásticamente explicado!! . Ha sido clave para mi, poder seguir con mi proyecto.
Sigue así por favor.
PD. ¿Tienes algún video o lo puedes hacer de como hacer un botón de emergencia ? Que pare todas las multitareas, como un reset.
La solución dependerá de cuál es exactamente el comportamiento que esperas y qué significa en este contexto "reset". Si la idea es un reset propiamente tal, puedes googlear Arduino software reset. Si a eso sumas interrupciones, podrás implementar un botón de emergencia que reinicie el sistema inmediatamente
Explicacion genial gracias!
Muy bien explicado simple y claro . Gracias!!
Que herramienta de software utilizo para el ejemplo de arduino ??
muy bien explicado me sirvió mucho para entender como se utiliza esta función aunque tengo una duda
el proyecto que estoy armando es de una incubadora y como voy a usar un relé lo que necesito es que encienda por un tiempo ejemplo: 1000 encendido y apagado 500... Y ningún video que encuentro explica como hacer eso si pudieras hacer un video explicándolo o dándome una solución respondiendo este comentario seria de mucha ayuda....
desde ya muchas gracias y disculpe mi intriga e ignorancia y lo felicito porque explica muy bien los videos lo cual hace que me ayuden muchísimo!!!
excelente explicación💯
muy bueno, gracias
Excelente! Gracias por el aporte!
Muy muy muy bueno !
muy buen video hno, podrias hacer uno pero con moteres PAP ( 3 al mismo tiempo), tengo unos estantes en mi casa y quiero darles movimientos , osea que pueda darle la VEL y los PASOS y con un pulsador darle inicio y final de linea(si se corta la tension sigue hasta que baje ) (seguiran funcionando con ups hasta que llegue al final de linea( abajo), ya que lo estoy intentando y no logro entender cual es error.
muy buena su explicacion y por que no hacer un curso para aprender mas de sus conocimientos
Muy buen video y muy bien explicado, gracias.
Me surge una duda en cuanto a las variables que definís como "static". Veo que usás el mismo nombre de variables en las 2 funciones. ¿El usar static hace que el programa no las confunda e internamente le asigna nombres distintos?
Muchas gracias.
Muy bien tu explicación me podrás orientar para realizar un semáforo que el color verde parpadee tres veces y después de 5oo milis entre a parpadear solo el rojo gracias este
hay algún video donde expliques lo de las variables en forma mas extensa?
Un aporte, en lugar de asignar la ultima hora a la variable ultimo_estado, sumar el valor del periodo cada vez que se cumple, de esta forma se obtiene una periocidad mas uniforme por ejemplo
if (hora - ultimo_cambio > 500)
{
ultimo_cambio += 500;
estado = !estado;
digitalWrite(4, estado);
}
De pronto aquí se podría incluir un control de desborde cuando el millis() llegue a su valor máximo.
Otro punto a revisar es millis() es un tipo de dato unsigned long
Muy buen video , tengo una duda es el mismo proceso usar millis si deseo leer varias lecturas simultánea ( ya sean analógicas o digitales ) ?
Muy buen aporte. El primer led parpadea cada segundo y el segundo cada 250ms. Por eso hay suficiente tiempo para que se ejecuten los demas loops. Pero si el loopA ell led parpadea cada 250ms y el loopB cada segundo, podria haber retrasos en el parpadeo del led A. No?
Buen código, saludos 👍
Buen video!!!
HOLA SE PUEDE HACER UNA SECUENCIA DE LEDS EN DIFERENTES VOID LOOP?
Hola kompadre muy bien explicado gracias. Pero como serian así como tipo clases. Podrías mostrarnos. @rre...cues
Thank you very much
Hola Rodri. Excelente video. De cualquier manera, si el sistema funciona en forma constante, en algún momento habrá desbordamiento del millis. ¿ Se perderá el "sincronismo" no? - ¿Solución?
acabo de aprender el tema de las variables dentro y fuera la función , estatic no me quedo claro porque no lo lleva a cero cada vez que entra a la funcion¿?¿? es proque asi lo dice el lenguajes? solo se da si esta al principio dela función? gracias por la s explicaciones
buena explicación , pero el uso del mils es un truco un poco lento para algunas aplicaciones; se podría usar otra forma con un retardo mas pequeño como microsegundos?
Desde ya muy buena y clara la explicación. Lo que si me gustaría hacerte una consulta con respecto a la necesidad o no de usar interrupciones cuando se quiere hacer "multitasking" y hay eventos externos de por medio. Noté que para el pulsador que enciende el LED C no usaste ninguna interrupción ¿Si el código fuese mas extenso sería necesario conectar el pulsador a una "entrada de interrupción" para asegurarnos que el micro la lea durante los momentos en que la misma está activa?.
Disculpa si lo que pregunto es muy desatinado, pero me cuesta entender como es que sin usar interrupciones evitas que un evento demasiado veloz no pase desapercibido por el micro.
Muchas gracias y saludos!
Hola Mariano, en lo absoluto desatinado... Lo que explico en este video tiene como hipótesis que los estímulos a los que estamos respondiendo son lo suficientemente lentos como para que tomen varias vueltas del loop principal y así este pueda detectarlos... Esta estrategia de consultar si está apretado el botón a cada rato es lo que se llama polling.
En contraste, una interrupción detectará inmediatamente el evento y ejecutará el código asociado a esta, habitualmente una función (interrupt service routine o ISR) para después volver al flujo normal...
La decisión de si usar polling o interrupción no depende de qué tan largo sea el código, sino que más bien de qué tan crítico es atender al evento inmediatamente y la velocidad del evento mismo... Las interrupciones son geniales para atender algo inmediatamente pero tienen la tremenda desventaja de que te desvían el flujo del programa de forma inesperada, por eso en general se recomienda evitarlas a menos que sean estrictamente necesarias... Es súper fácil crear errores muy difíciles de replicar, encontrar y corregir cuando un evento que entra aleatoriamente en tu código (la interrupción) desvía las cosas.
En desarrollo de firmware, mucho más que en programación regular para un computador, lo que buscamos es determinismo y saber cuándo revisas algo en vez de que pueda llegar en cualquier momento es valioso. Obviamente hay situaciones en las que las interrupciones son la única solución, pero hay que usarlas con cuidado.
@@Rodri-Tech Muchisimas gracias por tu respuesta, me has ayudado mucho a encaminar lo que debería hacer.
Ese era mi dilema a la hs de usar un micro para atender una interfas hm (lcd y un esconder) mientras ademas debia controlar motores y otros acutuadores, justamente leer en todo momento o usar interrupciones. Muy amable de tu parte, saludos!!
como harias un semaforo aplicando eso?
Gracias.
Cual es el propósito de la variable último cambio?
Una pregunta, porque en vez de usar static long no se utiliza unsigned long?
Y si necesito que sea un parpadeo asimetrico por ejemplo el led A encendido por 1 segundo y apagado por 2 segundos??
como hago para que el ultrasonico reciba lectura cuando activo un boton y esta activo un motor
te amo
Disculpen alguien me diria que app usó para eso
por favor
Perdón me explique mal Realice un semáforo empezando con el olor verde el cual primero prende por 2000milis y después, parpadea tres veces y pasa a amarillo y finalmente a rojo , posteriormente parpadean el rojo y amarillo esto los realice con los delay y creo que con multitasking funcionaria mejor aquí es donde te pido que me orientes gracias
hola, soy Hernán y me estoy iniciando en este mundo, tengo la tarea de asignar un tiempo a un motor, me explico, al presionar un botón quiero que un motor funcione un tiempo determinado y cuente ese pulso del botón y no encuentro como hacerlo, si pudieras ayudarme se agradecería
Porque no utilizas la pantalla en blanco se ve mejor el video
Rapasando el codigo, no entiendo para q se dieron de alta los #define (ON, OFF, TRUE, FALSE), supongo q es para q los recuerde el micro y los tenga presente, cuando se necesiten....muchas gracias
Esas definiciones son para hacer más fácil la lectura del código abajo por parte de un ser humano :)... El micro no llega a ver nada de eso, recuerda que los #define ALGO otra_cosa funciona como buscar y reemplazar como paso previo al proceso de compilación. Es decir, en el caso del ejemplo busca todas las apariciones de "ALGO" y las reemplaza con "otra_cosa", después de completar esa etapa se inicia la compilación propiamente tal.
@@Rodri-Tech Muy bien Rodri, esperando y nos des mas luz, a aquellos q no sabemos de esto, de todos muchas gracias por compartir tu tiempo....gracias
Hi Mr Rodri :)
Hi Mr. Sky! :)
Borro todos los demas y solo dejo este video para aprender.
Pero esto no es multiasking. Arduino no puede hacer multitarea.
Es un simil multitarea, si, ahi estamos de acuerdo pero no es multitarea. RTOS o Freetos son opciones multtarea.
Eso es simplemente usar millis() en un programa secuencial no bloqueante.
Lo unico que has hecho es no bloquear el programa cosa que ocurre con delay().
Ademas hay un pequeño error no significativo porque el codigo va a funcionar pero siempre las varialbes relacionadas con millis() deben definirse como unsigned long no solo como long. Un long es 2^31 = 2 147 483 647 eso en dias seran algo como 49.7/2 o sea, cuando millis() tenga mas de 25 dias tu código falla.
Aclaro que se que lo tienes claro, porque al final lo dices, pero es importante indicar que SI es la forma de programar en lo cual estoy 100% de acuerdo pero no es multitarea estricto.
Excelente explicación, felicitaciones..