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 long siempre con millis() 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.