Luz según la luz: el sensor LDR
Recorrido del nivel
Esa barra de arriba te dice en qué paso estás. Tocala para ver el índice completo y saltar a cualquier paso.
Conectar la fotorresistencia (sensor LDR)
Para poder medir la luz del exterior es necesario conectar una fotorresistencia (sensor LDRLDR (fotorresistencia)Componente cuya resistencia varía con la intensidad de la luz que recibe: baja (hasta 50 ohm) con luz incidiendo y muy alta (1 megaohm o más) a oscuras. Se usa en control automático de iluminación, robots seguidores de luz o barreras láser.).
Un sensor LDR o fotorresistencia es un componente electrónico cuya resistenciaResistenciaComponente que se opone al paso de la corriente eléctrica. Su valor se mide en ohm (Ω). Se usa para determinar la cantidad de corriente de una rama del circuito, por ejemplo para evitar que un LED se queme por exceso de corriente. varía de acuerdo al cambio que perciba en la intensidad de la luz a la que está expuesto. El valor de resistencia de un LDR es bajo cuando hay luz incidiendo en él (puede descender hasta 50 ohm) y muy alto cuando está a oscuras (1 megaohm o más).
Usamos un módulo LDR de tres pines: alimentación (VCC), tierra (GND) y salida de señal. A
diferencia del PIR, que entrega 1 o 0, esta salida es analógica: entrega un voltaje que
varía con la luz, así que va conectada a la entrada analógica de la placa indicada por la
constante PIN_LDR al comienzo del código de los pasos siguientes.
Obtener la lectura del sensor LDR
Al igual que hicimos con el sensor PIR, primero prepararemos nuestro programa para leer el pin y visualizar sus mediciones en el monitor serie.
Como el LDR es un sensor analógico, su lectura nos brindará valores entre 0 (cuando no haya luz) y 1023 (cuando haya mucha luz). Las entradas analógicas del ArduinoArduinoPlaca electrónica con un microcontrolador programable y comunicación USB/serial. Desde la computadora, un IDE permite escribir el código, compilarlo y cargarlo en la placa. Tiene entradas y salidas digitales (0 a 13) y entradas analógicas (A0 a A5). UNO, que van desde el pin A0 al A5, nos permiten saber el voltaje de la entrada con una resolución que va de 0 cuando hay 0 V a 1023 cuando hay 5 V. Si, por ejemplo, el voltaje en la entrada es de 1,25 V, estos pines leen un valor intermedio de 255.
Como el LDR es un sensor analógico, su lectura nos brindará un número que crece con la luz. En el ESP32ESP32Placa con un microcontrolador de Espressif que trae WiFi (y Bluetooth) integrados. Se programa desde el Arduino IDE igual que un Arduino, con pines llamados GPIO. En este proyecto reemplaza al conjunto Arduino UNO + módulo OBLOQ para el nivel IoT. el conversor analógico trabaja con más resolución que en el UNO: entrega valores entre 0 (0 V) y 4095 (3,3 V). La idea es la misma, solo cambia la escala: tenelo en cuenta cuando compares tus mediciones con las del resto del grupo o elijas el umbral del paso siguiente.
Ver el código completo · lectura-ldr.ino
// Lectura de la fotorresistencia (LDR) por consola serial.
// A diferencia del PIR (que solo dice 1 o 0), el LDR es un sensor
// ANALÓGICO: en el UNO, analogRead() devuelve un valor entre 0 (0 V,
// oscuridad total en nuestro divisor) y 1023 (5 V, mucha luz).
// Medir en distintos momentos del día y anotar los valores es lo que
// después permite elegir un umbral con fundamento, no a ojo.
//
// Plataforma: Arduino UNO.
// Conexión: divisor resistivo LDR + resistencia de 10 kohm; el punto
// medio del divisor → pin A0. Con este cableado, más luz = valor más alto.
// Consola: Monitor Serie del IDE de Arduino a 9600 baudios.
//
// Basado en: código del Paso 2, Nivel Avanzado — Automatización de Sistema
// Lumínico, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: se reemplazaron los bloques de mBlock3 por Serial.println()
// con una pausa entre lecturas para que la consola sea legible.
const int PIN_LDR = A0;
const long VELOCIDAD_SERIAL = 9600;
// Dos lecturas por segundo: suficiente para ver cómo cambia la luz
// ambiente sin inundar la consola.
const unsigned long INTERVALO_LECTURA_MS = 500;
void setup() {
pinMode(PIN_LDR, INPUT);
Serial.begin(VELOCIDAD_SERIAL);
}
void loop() {
// Tapá el sensor con la mano, iluminalo con una linterna, y observá
// el rango real de valores de TU aula: ese experimento es el que
// define el umbral del paso siguiente (luz-nocturna.ino).
Serial.println(analogRead(PIN_LDR));
delay(INTERVALO_LECTURA_MS);
} // Lectura de la fotorresistencia (LDR) por consola serial.
// A diferencia del PIR (que solo dice 1 o 0), el LDR es un sensor
// ANALÓGICO. OJO con esta diferencia didáctica: el conversor del ESP32
// es de 12 bits, así que analogRead() devuelve valores entre 0 (0 V) y
// 4095 (3,3 V), NO el 0-1023 (10 bits) del Arduino UNO. Mismo fenómeno
// físico, distinta "regla de medir": por eso los umbrales de un programa
// no se copian entre placas sin pensar.
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: divisor resistivo LDR + resistencia de 10 kohm alimentado con
// 3,3 V; el punto medio del divisor → GPIO 34. Con este cableado, más luz
// = valor más alto.
// IMPORTANTE: el GPIO 34 es de SOLO ENTRADA y no tiene resistencias
// internas de pull-up/pull-down, por lo que el divisor resistivo externo
// es OBLIGATORIO: sin él, el pin queda "flotando" y lee cualquier cosa.
// (Es un GPIO del ADC1, que sigue funcionando aunque se use WiFi; los
// pines del ADC2 dejan de medir con WiFi activo.)
// Consola: Monitor Serie del IDE de Arduino a 9600 baudios.
//
// Basado en: código del Paso 2, Nivel Avanzado — Automatización de Sistema
// Lumínico, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: portado a ESP32 (LDR en GPIO 34; el original usaba A0 del
// UNO) y Serial.println() con pausa entre lecturas en lugar de los bloques
// de mBlock3.
const int PIN_LDR = 34;
const long VELOCIDAD_SERIAL = 9600;
// Dos lecturas por segundo: suficiente para ver cómo cambia la luz
// ambiente sin inundar la consola.
const unsigned long INTERVALO_LECTURA_MS = 500;
void setup() {
pinMode(PIN_LDR, INPUT);
Serial.begin(VELOCIDAD_SERIAL);
}
void loop() {
// Tapá el sensor con la mano, iluminalo con una linterna, y observá
// el rango real de valores de TU aula (acá entre 0 y 4095): ese
// experimento es el que define el umbral del paso siguiente
// (luz-nocturna.ino).
Serial.println(analogRead(PIN_LDR));
delay(INTERVALO_LECTURA_MS);
} Como nuestro objetivo es detectar el nivel de luz natural presente en el exterior, sería recomendable poder realizar mediciones en distintos momentos del día e ir observando qué valores obtenemos en cada uno de ellos. De todas formas, para probar el funcionamiento del sensor LDR, se puede utilizar una luz artificial variando su intensidad.
Encender y apagar las luces en función del sensor LDR
Tomando los valores que obtuvimos al medir los niveles de la luz del exterior, podemos
establecer ante qué valor queremos que se enciendan y se apaguen las luces: ese valor es
nuestro umbral. Para poder programarlo, debemos utilizar la siguiente condición: si el
valor de la lectura del sensor es menor al valor que determinamos, la luz se encenderá;
si no, se apagará. Es la misma estructura if... else del nivel inicial, ahora comparando
un número contra el umbral en lugar de preguntar por un 1 o un 0.
El original propone como punto de partida un umbral de 600 (sobre la escala de 0 a 1023 del UNO). Ajustalo con los valores que anotaste en el paso 2.
Sobre la escala del ESP32 (0 a 4095), el punto de partida equivalente al 600 del original ronda el valor que indica la constante del umbral en el código. Ajustalo con los valores que anotaste en el paso 2.
Ver el código completo · luz-nocturna.ino
// Luz nocturna: el relé enciende la lámpara cuando el nivel de luz
// exterior es bajo, y la apaga cuando es alto.
// Lógica exacta del original: si la lectura del LDR es MENOR que el
// umbral, enciende; si no, apaga. El código de este paso usa SOLO el
// LDR (la combinación con el PIR queda como extensión propuesta por
// la prosa de la guía, no como código del original).
//
// SEGURIDAD: esta práctica se realiza con una lámpara LED de baja tensión.
// La conexión a 220 V queda reservada al docente o a una instalación
// supervisada, y NUNCA sobre la protoboard (desvío pedagógico acordado
// sobre la advertencia de 220 V de la guía original).
//
// Plataforma: Arduino UNO.
// Conexión: divisor resistivo del LDR → pin A0 (más luz = valor más alto);
// entrada IN del módulo relé → pin 7.
//
// Basado en: código del Paso 3, Nivel Avanzado — Automatización de Sistema
// Lumínico, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas en lugar del C generado por mBlock3;
// el relé se mueve del pin 2 (original) al pin 7 (contrato de pines de la
// reedición).
const int PIN_LDR = A0;
const int PIN_RELE = 7;
// Módulo relé activo-alto, como lo explica el original (HIGH = enciende).
// Si tu módulo es activo-bajo, invertí solo estas dos constantes.
const int RELE_ENCENDIDO = HIGH;
const int RELE_APAGADO = LOW;
// Umbral del original: 600 sobre un rango de 0 a 1023 (10 bits del UNO).
// No es un número mágico: sale de haber MEDIDO la luz del lugar con
// lectura-ldr.ino. Si tus mediciones dieron otro rango, ajustalo acá.
const int UMBRAL_LUZ = 600;
void setup() {
pinMode(PIN_LDR, INPUT);
pinMode(PIN_RELE, OUTPUT);
}
void loop() {
// Menos luz que el umbral → está oscureciendo → encender la lámpara.
if (analogRead(PIN_LDR) < UMBRAL_LUZ) {
digitalWrite(PIN_RELE, RELE_ENCENDIDO);
} else {
digitalWrite(PIN_RELE, RELE_APAGADO);
}
// Sin delay(): este programa ya es naturalmente no bloqueante, igual
// que el original. El relé solo conmuta cuando la condición cambia.
} // Luz nocturna: el relé enciende la lámpara cuando el nivel de luz
// exterior es bajo, y la apaga cuando es alto.
// Lógica exacta del original: si la lectura del LDR es MENOR que el
// umbral, enciende; si no, apaga. El código de este paso usa SOLO el
// LDR (la combinación con el PIR queda como extensión propuesta por
// la prosa de la guía, no como código del original).
//
// SEGURIDAD: esta práctica se realiza con una lámpara LED de baja tensión.
// La conexión a 220 V queda reservada al docente o a una instalación
// supervisada, y NUNCA sobre la protoboard (desvío pedagógico acordado
// sobre la advertencia de 220 V de la guía original).
//
// Plataforma: ESP32 (DevKit v1).
// Conexión: divisor resistivo del LDR (obligatorio: el GPIO 34 es de solo
// entrada y no tiene pull-up interno) → GPIO 34, con más luz = valor más
// alto; entrada IN del módulo relé → GPIO 16.
// Nota eléctrica: el ESP32 trabaja a 3,3 V (no 5 V como el UNO); nunca
// inyectar 5 V en un GPIO.
//
// Basado en: código del Paso 3, Nivel Avanzado — Automatización de Sistema
// Lumínico, Saberes Digitales (INET/EDUCAR 2019)
// Modernización: constantes nombradas en lugar del C generado por mBlock3;
// portado a ESP32 (el original usaba A0 y relé en pin 2 del UNO) y umbral
// reescalado al ADC de 12 bits del ESP32.
const int PIN_LDR = 34;
const int PIN_RELE = 16;
// Módulo relé activo-alto, como lo explica el original (HIGH = enciende).
// Si tu módulo es activo-bajo, invertí solo estas dos constantes.
const int RELE_ENCENDIDO = HIGH;
const int RELE_APAGADO = LOW;
// El original usa 600 sobre el rango 0-1023 del UNO (ADC de 10 bits).
// El ADC del ESP32 es de 12 bits (0-4095): para que el umbral represente
// el MISMO nivel de luz hay que reescalarlo en la misma proporción:
// 600/1023 ≈ 2400/4095. Mismo fenómeno, distinta resolución: por eso los
// umbrales nunca se copian entre placas sin ajustar. Y como siempre,
// el valor definitivo sale de medir con lectura-ldr.ino en tu lugar.
const int UMBRAL_LUZ = 2400;
void setup() {
pinMode(PIN_LDR, INPUT);
pinMode(PIN_RELE, OUTPUT);
}
void loop() {
// Menos luz que el umbral → está oscureciendo → encender la lámpara.
if (analogRead(PIN_LDR) < UMBRAL_LUZ) {
digitalWrite(PIN_RELE, RELE_ENCENDIDO);
} else {
digitalWrite(PIN_RELE, RELE_APAGADO);
}
// Sin delay(): este programa ya es naturalmente no bloqueante, igual
// que el original. El relé solo conmuta cuando la condición cambia.
} Compará el comportamiento de tu circuito con el del simulador, variando el nivel de luz:
Simulación del comportamiento
La misma máquina de estados del firmware, portada a TypeScript, maneja el
comportamiento del dispositivo. No se ejecuta el binario real: la ejecución
del .hex con avr8js está en el roadmap.
Simulación lista. Presioná «Iniciar» para arrancar la secuencia.
El sistema completo de Agustín
La historia dice que el sistema tiene en cuenta las dos cosas: la presencia de personas
y el nivel de luz exterior. Combiná lo que construiste en los dos niveles: la lámpara debe
encenderse solamente si el PIR detecta movimiento y además está oscuro según el LDR.
Pista: las condiciones se pueden combinar dentro de un mismo if. ¿En qué ambiente de la
casa este comportamiento es el correcto, y en cuál convendría que la luz encienda con
movimiento aunque sea de día?
Verificá
Con el umbral ya ajustado: al tapar el sensor (simulando la noche) el relé hace clic y la lámpara se enciende; al iluminarlo (simulando el día), se apaga. Si la lámpara parpadea sin que cambie la luz ambiente, estás viendo la oscilación: alejá el sensor de la propia lámpara y volvé a probar.
Cierre del nivel
Al terminar este nivel, el sistema decide solo cuándo vale la pena gastar energía: el LDR mide el nivel de luz en una entrada analógica, vos elegiste el umbral con mediciones reales —no con un número mágico— y la condición del programa enciende la lámpara únicamente cuando está oscuro. Si además resolviste el desafío, tu sistema es el de Agustín completo: movimiento y oscuridad, las dos condiciones del ahorro. Con esto queda cerrado el recorrido del proyecto. Si el grupo quiere seguir, en la ficha están las extensiones sugeridas: display LCD con el estado de los ambientes, “modo de vacaciones” con módulo reloj, y control de las luces a través de IoT (para eso, el proyecto Sistema de Semaforización te espera con su nivel avanzado).
Evidencia de cierre
Al terminar este nivel, esto tiene que estar funcionando:
- El sensor LDR está conectado a una entrada analógica y sus lecturas se ven en el monitor serie, variando al tapar e iluminar el sensor.
- Registraste mediciones en distintas condiciones de luz y elegiste un umbral de encendido con criterio, basándote en esos valores.
- El sistema enciende la lámpara cuando el nivel de luz es menor al umbral y la apaga cuando es mayor.