Hacer varias cosas sin bloquear el programa

Reemplaza delay() por millis() para leer un sensor y responder a un botón al mismo tiempo.

Nivel: intermedioarduinoprogramacion

Qué vas a construir

Un programa que lee la temperatura cada 2 segundos y, al mismo tiempo, responde de inmediato cuando presionas un botón. Ningún proceso espera al otro.

Lo que aprendes

  • Por qué delay() bloquea todo el programa mientras espera.
  • Cómo usar millis() para medir el tiempo sin detener el código.
  • Cómo usar unsigned long para guardar tiempos largos.
  • Cómo separar una tarea en su propia función.

Idea clave

delay(2000) detiene el Arduino durante dos segundos. Mientras tanto, no lee el botón. En cambio, millis() devuelve cuántos milisegundos han pasado desde que se encendió la placa. Si restamos ese tiempo con el último momento en que leímos el sensor, sabemos cuándo toca leer otra vez, sin esperar.

Materiales en Tinkercad

  • Arduino Uno R3
  • Sensor TMP36
  • Pulsador
  • LED y resistencia de 220 Ω
  • Protoboard y cables

Paso 1: Conecta todo

  • Sensor TMP36 en A0, como en Leer un sensor de temperatura.
  • Pulsador en pin 2 y GND, como en Leer un botón.
  • LED en pin 8 con resistencia de 220 Ω a GND, como en Leer un botón.

Paso 2: Escribe el código

const int SENSOR = A0;
const int BOTON = 2;
const int LED = 8;
const unsigned long INTERVALO = 2000;  // 2 segundos en milisegundos

unsigned long ultimaLectura = 0;

float leerCelsius() {
  int lectura = analogRead(SENSOR);
  float voltaje = lectura * 5.0 / 1024.0;
  return (voltaje - 0.5) * 100.0;
}

void setup() {
  pinMode(BOTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Tarea 1: responder al botón, sin esperar
  bool presionado = digitalRead(BOTON) == LOW;
  digitalWrite(LED, presionado ? HIGH : LOW);

  // Tarea 2: leer el sensor solo cuando haya pasado el intervalo
  unsigned long ahora = millis();
  if (ahora - ultimaLectura >= INTERVALO) {
    ultimaLectura = ahora;
    Serial.print("Temperatura: ");
    Serial.println(leerCelsius());
  }
}

La clave está en el if: el programa da una vuelta completa al loop() en microsegundos. El sensor solo se lee cuando la diferencia de tiempo supera 2000 ms.

Paso 3: Prueba la independencia de las tareas

  1. Inicia la simulación y abre el monitor serial.
  2. Presiona el botón varias veces entre dos lecturas de temperatura.
  3. El LED debe responder de inmediato, sin importar en qué momento del intervalo estés.

Cómo sabes que lo lograste

  • El LED responde al botón en menos de un instante, aunque la temperatura no se haya leído.
  • La temperatura aparece en el monitor serial cada 2 segundos, aproximadamente.
  • No usaste delay() dentro de loop().

Qué salió mal

El LED responde con retraso. Revisa que no quedó un delay() en el código. Si lo hay, el programa espera antes de volver a leer el botón.

La temperatura sale más seguido o más lento de lo esperado. Revisa el valor de INTERVALO. Recuerda que está en milisegundos: 2000 son 2 segundos.

El temporizador se comporta raro al inicio. Como ultimaLectura empieza en 0, la primera lectura ocurre casi de inmediato. Eso es normal.

Siguiente clase

En la siguiente clase vas a mostrar la temperatura en una pantalla LCD, sin depender de la computadora.