Curso C para Arduino
🧠 ¿Por qué no usar delay()?
La función delay(ms) bloquea todo el código, es decir, mientras espera, no se ejecuta nada más. Esto es un problema cuando queremos, por ejemplo:
- Leer un sensor cada segundo,
- Parpadear un LED cada medio segundo,
- Y al mismo tiempo revisar un botón.
Solución: usar millis() como temporizador.
⏱️ ¿Qué es millis()?
La función millis() devuelve el número de milisegundos transcurridos desde que se encendió la placa. Al usarla, podemos medir el tiempo sin detener el programa.
🎯 Objetivo
Simular tareas simultáneas como:
- Parpadear varios LEDs a distinto ritmo.
- Leer sensores de forma periódica.
- Mostrar datos cada cierto tiempo.
- Controlar botones o eventos sin interferencias.
🔧 Estructura básica para múltiples tareas
1unsigned long tAnteriorTarea1 = 0; 2const unsigned long intervaloTarea1 = 1000; 3 4void loop() { 5 unsigned long ahora = millis(); 6 7 if (ahora - tAnteriorTarea1 >= intervaloTarea1) { 8 tAnteriorTarea1 = ahora; 9 // ejecutar tarea 1 10 } 11 12 // otras tareas... 13}
🧪 Ejemplo 1: Dos LEDs con tiempos distintos
1const int led1 = 8; 2const int led2 = 9; 3 4unsigned long tLed1 = 0, tLed2 = 0; 5const long intervalo1 = 500; // LED1 cada 0.5s 6const long intervalo2 = 1000; // LED2 cada 1s 7 8bool estadoLed1 = false; 9bool estadoLed2 = false; 10 11void setup() { 12 pinMode(led1, OUTPUT); 13 pinMode(led2, OUTPUT); 14} 15 16void loop() { 17 unsigned long ahora = millis(); 18 19 // Tarea LED1 20 if (ahora - tLed1 >= intervalo1) { 21 tLed1 = ahora; 22 estadoLed1 = !estadoLed1; 23 digitalWrite(led1, estadoLed1); 24 } 25 26 // Tarea LED2 27 if (ahora - tLed2 >= intervalo2) { 28 tLed2 = ahora; 29 estadoLed2 = !estadoLed2; 30 digitalWrite(led2, estadoLed2); 31 } 32}
🧪 Ejemplo 2: LED + sensor + botón
Simula:
- Parpadeo de un LED cada 500ms.
- Lectura de un potenciómetro cada 100ms.
- Lectura de un botón continuamente.
1const int led = 13; 2const int pot = A0; 3const int boton = 2; 4 5unsigned long tLED = 0, tSensor = 0; 6bool estadoLED = false; 7 8void setup() { 9 Serial.begin(9600); 10 pinMode(led, OUTPUT); 11 pinMode(boton, INPUT_PULLUP); 12} 13 14void loop() { 15 unsigned long ahora = millis(); 16 17 // LED intermitente 18 if (ahora - tLED >= 500) { 19 tLED = ahora; 20 estadoLED = !estadoLED; 21 digitalWrite(led, estadoLED); 22 } 23 24 // Leer potenciómetro 25 if (ahora - tSensor >= 100) { 26 tSensor = ahora; 27 int valor = analogRead(pot); 28 Serial.print("Potenciómetro: "); 29 Serial.println(valor); 30 } 31 32 // Leer botón (en tiempo real) 33 if (digitalRead(boton) == LOW) { 34 Serial.println("¡Botón presionado!"); 35 delay(200); // anti-rebote rápido 36 } 37}
🛠 Recomendaciones para múltiples tareas
- Crea una variable por tarea para controlar su tiempo (
tAnterior). - Usa
unsigned longsiempre conmillis()para evitar desbordamientos. - Nunca uses
delay()si estás manejando más de una tarea. - Si el código crece, organiza cada tarea en una función separada.
📦 Proyecto sugerido
Estación ambiental multitarea:
- LED parpadeante como latido del sistema.
- Sensor de temperatura/humedad que se lee cada 2 segundos.
- Muestra datos en monitor serial cada 5 segundos.
- Botón que guarda el umbral actual en EEPROM.