Ejercicio 03 — Detector de movimiento
Dificultad: verde · Módulo 06 (Sensores comunes)
Enunciado
Detector de movimiento: encender un LED mientras el PIR detecte presencia.
Montaje (Arduino UNO)
PIR (VCC→5V, OUT→pin 2, GND→GND) + LED en pin 8 con R 220 ohm a GND Librería: ninguna (el PIR es una simple salida digital HIGH/LOW)
Cómo se resuelve
Después del protocolo del DHT22 y del cronometraje del HC-SR04, este ejercicio sorprende por lo poco que hay que escribir. Y ese es exactamente su contenido: comprobar que un sensor sofisticado por dentro puede ser trivial por fuera.
Un PIR (Passive InfraRed) detecta calor en movimiento. Los cuerpos emiten radiación infrarroja; el sensor vigila su campo de visión y, cuando el patrón de calor se desplaza, lo interpreta como presencia. Es pasivo porque no emite nada, solo mira. Toda la electrónica que compara señales, filtra ruido y decide si eso ha sido movimiento o no está dentro del propio módulo. Lo que sale por su pin OUT es la conclusión, ya digerida: HIGH cuando detecta, LOW cuando no. Por eso no necesita librería y por eso, para tu código, un PIR es indistinguible de un botón.
El programa declara los dos pines con nombre:
const int PIR = 2; // salida del sensor: HIGH = hay movimiento
const int LED = 8; // LED indicadorEn setup(), PIR se configura como INPUT y LED como OUTPUT, y se abre el serie a 9600. Aquí conviene detenerse un segundo en la simetría: el pin 2 es una entrada porque la información entra desde el sensor hacia la placa, y el pin 8 es una salida porque la corriente sale de la placa hacia el LED. El mismo pinMode que ya usabas en el módulo 01, aplicado ahora en las dos direcciones dentro del mismo programa.
El loop() entero son cinco líneas:
if (digitalRead(PIR) == HIGH) {
digitalWrite(LED, HIGH);
Serial.println("Movimiento detectado");
} else {
digitalWrite(LED, LOW);
}
delay(100);Es un if/else que traduce directamente el enunciado: si hay movimiento, LED encendido y aviso por serie; si no, LED apagado. Nota que el else no es opcional aquí. El enunciado dice “encender el LED mientras el PIR detecte presencia”, y ese mientras es lo que obliga a apagarlo cuando la condición deja de cumplirse. Si quitas el else, el LED se enciende con el primer movimiento y ya no se apaga jamás, porque nada le dice que vuelva a LOW. Es el mismo razonamiento del semáforo del módulo 01: el estado no es “lo que acabo de encender”, es el conjunto completo de lo que debe estar encendido y lo que debe estar apagado en cada momento.
Fíjate también en dónde está el Serial.println. Está dentro de la rama del if, así que solo se imprime mientras hay detección, no continuamente. Y como el loop() da una vuelta cada 100 ms, mientras el PIR esté en HIGH verás la línea “Movimiento detectado” repetida diez veces por segundo. Eso es intencionadamente tosco: hace evidente cuánto dura realmente una detección. Si te molesta, el arreglo natural es guardar el estado anterior en una variable e imprimir solo cuando cambie, que es el paso previo a la detección de flancos.
El delay(100) del final no lo impone el sensor. El PIR mantiene su salida estable durante segundos, así que no hay ninguna prisa por leerlo; esas diez lecturas por segundo son de sobra para que la respuesta parezca instantánea al ojo, y evitan que el bucle gire a máxima velocidad inundando el Monitor Serie.
Del montaje solo hay que recordar dos cosas. El LED del pin 8 lleva su resistencia de 220 Ω en serie hacia GND, igual que en el módulo 01 y por la misma razón: sin ella el LED deja pasar toda la corriente que puede, se degrada y castiga al pin. Y el PIR se alimenta a 5 V con su OUT al pin 2.
Por último, las dos rarezas del PIR que parecen bugs del programa y no lo son. La primera es el calentamiento: recién alimentado, el sensor necesita unas decenas de segundos para calibrar el nivel de infrarrojo de fondo de la habitación, y durante ese rato dispara falsos positivos. Si nada más subir el sketch el LED se enciende solo, espera un poco antes de sospechar del if. La segunda es que el PIR no es instantáneo al soltar: tras detectar, mantiene su salida en HIGH un tiempo fijo, del orden de segundos, ajustable con los potenciómetros del propio módulo. Así que si te mueves y te quedas quieto, el LED seguirá encendido un rato. No es que tu else no funcione; es que el sensor todavía dice HIGH.
Para practicar — cópialo y complétalo
Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.
/*
* Curso de Arduino — Módulo 06: Sensores comunes
* Ejercicio 03 — PRÁCTICA (rellena los TODO)
* Enunciado: Detector de movimiento: encender un LED mientras el PIR detecte presencia.
* Dificultad: verde
* Placa: Arduino UNO Montaje: PIR (VCC->5V, OUT->pin 2, GND->GND) + LED en pin 8 con R 220 ohm a GND
* Librería: ninguna (el PIR es una simple salida digital HIGH/LOW)
* Correr: Arduino IDE / Wokwi (wokwi/ej03) / arduino-cli (ver README)
*/
const int PIR = 2; // salida del sensor: HIGH = hay movimiento
const int LED = 8; // LED indicador
void setup() {
// TODO: configura PIR como INPUT y LED como OUTPUT
// TODO: abre el serie a 9600
}
void loop() {
// TODO: si digitalRead(PIR) == HIGH -> enciende el LED e imprime "Movimiento detectado"
// TODO: si no -> apaga el LED
delay(100);
}Solución — cópiala y ejecútala
/*
* Curso de Arduino — Módulo 06: Sensores comunes
* Ejercicio 03 — MODELO (resuelto)
* Enunciado: Detector de movimiento: encender un LED mientras el PIR detecte presencia.
* Dificultad: verde
* Placa: Arduino UNO Montaje: PIR (VCC->5V, OUT->pin 2, GND->GND) + LED en pin 8 con R 220 ohm a GND
* Librería: ninguna (el PIR es una simple salida digital HIGH/LOW)
* Correr: Arduino IDE / Wokwi (wokwi/ej03) / arduino-cli (ver README)
*/
const int PIR = 2; // salida del sensor: HIGH = hay movimiento
const int LED = 8; // LED indicador
void setup() {
pinMode(PIR, INPUT);
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (digitalRead(PIR) == HIGH) { // el PIR detecta movimiento
digitalWrite(LED, HIGH);
Serial.println("Movimiento detectado");
} else {
digitalWrite(LED, LOW);
}
delay(100);
}Cómo ejecutar la simulación
Sin instalar nada, en el navegador
- Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
- Pega la solución (o tu intento) en la pestaña
sketch.ino. - Abre la pestaña
diagram.json, borra lo que haya y pega el circuito de aquí abajo. - Dale al play. Verás el circuito funcionando: LEDs, pantallas y monitor serie.
Circuito del ejercicio (diagram.json)
{
"version": 1,
"author": "ESIBot",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
{ "type": "wokwi-pir-motion-sensor", "id": "pir", "top": -130, "left": 180, "attrs": {} },
{ "type": "wokwi-led", "id": "led", "top": -40, "left": 250, "attrs": { "color": "red" } },
{ "type": "wokwi-resistor", "id": "r1", "top": 100, "left": 250, "attrs": { "value": "220" } }
],
"connections": [
[ "pir:VCC", "uno:5V", "red", [ "v0" ] ],
[ "pir:GND", "uno:GND.1", "black", [ "v0" ] ],
[ "pir:OUT", "uno:2", "green", [ "v0" ] ],
[ "uno:8", "led:A", "orange", [ "v0" ] ],
[ "led:C", "r1:1", "black", [ "v0" ] ],
[ "r1:2", "uno:GND.2", "black", [ "v0" ] ]
],
"dependencies": {}
}En VS Code, con el repo del curso
El paquete de simulación de este ejercicio está en practica/06-sensores-comunes/wokwi/ej03/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):
make sim EJ=06-sensores-comunes/ej03y después, en VS Code, Ctrl+Shift+P → Wokwi: Start Simulator. La extensión no compila: simula un firmware ya compilado, y de compilarlo se encarga ese make.
Cómo usarlo
Con placa: abre el .ino en el Arduino IDE, elige placa y puerto y pulsa Subir. Sin placa: simulalo en Wokwi con cualquiera de las dos vias de arriba. Antes de mirar la solucion, intenta completar tu el esqueleto: es la mejor forma de aprender.