En este tutorial, exploraremos cómo detectar la luz usando un Arduino. La detección de luz es un aspecto fundamental en muchos proyectos, desde interruptores automáticos hasta sistemas de iluminación regulada. Al entender los principios detrás de la detección de luz, podrás crear aplicaciones innovadoras que respondan a cambios en los niveles de luz.
Usando una placa Arduino, podemos conectar fácilmente varios sensores y componentes para detectar la luz. Uno de los sensores más usados para esta tarea es la fotorresistencia, también conocida como resistor dependiente de luz (LDR). Midiendo la resistencia de la fotorresistencia, podemos determinar la intensidad de la luz que incide sobre ella.
En esta entrada del blog, te guiaremos en el proceso de construir un detector de luz usando un Arduino y una fotorresistencia. También exploraremos cómo ampliar esta configuración básica para crear proyectos más avanzados, como un interruptor automático, iluminación regulada e incluso un servo controlado por luz.
Ya seas principiante o un entusiasta experimentado de Arduino, este tutorial te proporcionará el conocimiento necesario para empezar a trabajar con detección de luz. ¡Así que vamos allá!
Partes necesarias
A continuación encontrarás los componentes necesarios para construir este proyecto. Si ya tienes resistencias, LEDs y potenciómetros, obviamente no necesitarás los kits listados. De lo contrario, vale la pena comprarlos, ya que será más barato que comprar las piezas por separado.

Arduino Uno

Juego de cables Dupont

Protoboard

Cable USB para Arduino UNO

Kit de resistencias y LEDs

Juego de resistencias variables

Juego de fotorresistencias

Servo posicional

Arduino IDE
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Qué es una fotorresistencia o LDR
Una fotorresistencia, también conocida como resistor dependiente de luz (LDR), es un tipo de resistencia cuya resistencia varía según la cantidad de luz a la que está expuesta. Es un componente pasivo ampliamente usado en diversas aplicaciones de detección y control de luz. La imagen a continuación muestra una fotorresistencia típica.

Ten en cuenta que no hay polaridad para los dos cables. Al ser solo una resistencia, puedes usarla en cualquier orientación. Para Arduino también puedes encontrar módulos con circuitos integrados adicionales que permiten ajustar la sensibilidad del sensor, pero nosotros lo construiremos nosotros mismos.
¿Cómo funciona una fotorresistencia?
Una fotorresistencia está hecha de un material semiconductor fotoconductivo. Cuando la luz incide sobre su superficie, los fotones excitan los electrones en el material semiconductor, permitiéndoles moverse con mayor libertad. Este movimiento reduce la resistencia de la fotorresistencia.
Por otro lado, cuando no hay luz o la intensidad es baja, el material semiconductor presenta una resistencia mayor. Esta característica hace que las fotorresistencias sean ideales para detectar niveles de luz.
Divisor de voltaje
Para medir la resistencia de una fotorresistencia y convertirla en un voltaje medible, se usa comúnmente un voltage divider circuito. Consiste en dos resistencias conectadas en serie, una de ellas la fotorresistencia. La otra suele ser un potenciómetro o trimmer para ajustar la sensibilidad o el umbral del circuito. Sin embargo, también existen circuitos más simples que usan una resistencia fija en lugar de un trimmer.
La imagen a continuación muestra el esquema del divisor de voltaje que usaremos en las siguientes secciones.

Puedes ver que la fotorresistencia (R1) y el trimmer (R2) están conectados en serie entre la fuente de alimentación (5V) y tierra (GND). El punto de unión entre la fotorresistencia (R1) y el trimmer está conectado a un pin de entrada analógica (A0) del Arduino. A medida que la resistencia de la fotorresistencia cambia con la intensidad de luz, afecta el voltaje en ese punto de unión.
La fórmula para calcular el voltaje de salida de un divisor de voltaje es:
V_A0 = Vin * (R1 / (R1 + R2))
Donde:
- V_A0 es el voltaje de salida
- Vin (+5V) es el voltaje de entrada
- R1 es la resistencia de la fotorresistencia
- R2 es la resistencia del trimmer
En la siguiente sección aprenderás cómo construir un detector de luz usando este circuito y un Arduino.
Construyendo un detector de luz
En esta sección te muestro cómo conectar un LDR a un Arduino y mostrar las intensidades de luz medidas en el Monitor Serial.
Construyendo el divisor de voltaje
El siguiente diagrama muestra cómo conectar las piezas para construir el divisor de voltaje que discutimos antes. Primero conectamos 5V al riel positivo de la protoboard con un cable rojo. Luego conectamos tierra (GND) al riel negativo usando un cable azul.

Ahora el divisor de voltaje. Conecta un pin de la fotorresistencia (LDR) al riel positivo (cable rojo). El otro pin debe conectarse al pin central del trimmer. Asegúrate de hacerlo bien, de lo contrario el ajuste no funcionará.
Para el trimmer elegimos un valor de resistencia aproximadamente igual a la resistencia del LDR en condiciones normales de luz. En mi caso es alrededor de 20K Ohmios. El valor exacto no es crítico.
Luego conectamos el punto de unión entre el trimmer y la fotorresistencia con un cable amarillo al pin analógico A0 del Arduino.
La última conexión es entre uno de los otros pines del trimmer y el riel negativo (cable azul). No importa cuál pin uses para eso. Finalmente, gira el trimmer a su posición media y comenzamos a escribir el software.
Código para el detector de luz
El software para el detector de luz es muy simple. Definimos una constante ldrPin para el pin al que está conectado el LDR y una variable ldrValue para almacenar el brillo detectado.
const int ldrPin = A0;
int ldrValue = 0;
void setup() {
Serial.begin(9600);
pinMode(ldrPin, INPUT);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.print("LDR:");
Serial.println(ldrValue);
delay(100);
}
En la setup() función, iniciamos Serial la comunicación y luego configuramos el modo del ldrPin a INPUT, ya que vamos a leer de él.
En la función l oop() leemos el valor del LDR con analogRead() y luego lo imprimimos en el monitor serial. Ahora abre el Serial Plotter y mueve tu mano frente al LDR para cambiar la cantidad de luz que recibe. Deberías ver una curva fluctuante similar a la de abajo.

Si no obtienes señal (línea plana), revisa tu circuito y asegúrate de que el trimmer esté en su posición media.
La entrada analógica devuelve valores en el rango de 0 a 1023 en un Arduino UNO. Sin embargo, usualmente no veremos todo el rango, siempre que el sensor no esté expuesto a completa oscuridad o brillo extremo.
Para obtener buena sensibilidad del sensor, prueba con diferentes niveles de brillo/oscuridad y ajusta el trimmer para que no llegues al mínimo (0) ni al máximo (1023). Ten en cuenta que estos valores no están calibrados. Por ejemplo, si quieres medir la intensidad de luz en Lux, necesitarías una fuente de luz con intensidad conocida para calibrar las lecturas.
Construyendo un interruptor de luz automático
Ahora que podemos detectar luz, podemos construir un interruptor automático. Cuando oscurece, encendemos la luz. Para este ejemplo, añadimos un LED con una resistencia al circuito.

Mantenemos el divisor de voltaje como está. Solo añade el LED y una resistencia de 220 Ohmios a la protoboard como se muestra arriba. Luego conecta el pin largo del LED con un cable naranja al Pin 9 del Arduino. Finalmente, conecta el pin de la resistencia con un cable azul al riel negativo de la protoboard. ¡Listo!
Extender el código también es muy fácil. Solo añade una constante adicional ledPin para el pin de salida al que está conectado el LED y configura el pinMode a OUTPUT en la función setup().
const int ldrPin = A0;
const int ledPin = 9;
int ldrValue = 0;
void setup() {
Serial.begin(9600);
pinMode(ldrPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
ldrValue = analogRead(ldrPin);
digitalWrite(ledPin, ldrValue > 500 ? HIGH: LOW);
delay(1000);
}
En la función loop() leemos el ldrValue como antes. Pero luego, según el valor, encendemos o apagamos el LED usando digitalWrite. Si el ldrValue es mayor que 500, hay bastante luz y apagamos el LED (LOW). Si el valor es menor, está oscuro y encendemos el LED (HIGH).
¡Ahí lo tienes! Ahora tienes una luz automática que se enciende cuando oscurece. Puedes ajustar el umbral cambiando el valor 500 por uno mayor o menor (en el rango de 0 a 1023). Si quieres controlar luces más potentes, puedes reemplazar el LED por un relé y así controlar las luces de tu habitación, por ejemplo.
Construyendo una luz regulada o dimmer
En la sección anterior construimos un interruptor automático que enciende o apaga el LED completamente. En esta sección te muestro cómo regular suavemente el brillo del LED según la luminosidad. En lugar de encender o apagar, vamos a atenuar el LED.
Aquí está el código para ello. Empezamos añadiendo una variable brightness pero dejamos la función setup() sin cambios.
const int ldrPin = A0;
const int ledPin = 9;
int ldrValue = 0;
int brightness = 0;
void setup() {
Serial.begin(9600);
pinMode(ldrPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
ldrValue = analogRead(ldrPin);
brightness = map(ldrValue, 50, 300, 255, 0);
brightness = constrain(brightness, 0, 255);
analogWrite(ledPin, brightness);
delay(10);
}
En la función loop() leemos el ldrValue como antes pero luego map su valor al rango de 255 a 0. Nota que el rango está invertido (255 a 0 en lugar de 0 a 255), porque queremos que el LED se ilumine más cuanto más oscuro esté el entorno.
El ldrValue tiene un rango posible de 0 a 1023. Pero en el código usamos solo el rango de 50 a 300. Así el LED reacciona a cambios pequeños en la iluminación. De lo contrario, tendría que estar muy brillante u oscuro para notar cambios en el brillo del LED.
Sin embargo, esto causa un pequeño problema. La función map no garantiza que su valor de salida esté realmente en el rango 255 a 0. Si la luz es más brillante o más oscura que 50 o 300 en el rango de entrada, el valor de salida será menor o mayor que 0 o 255. Pero la función analogWrite() solo acepta valores entre 0 y 255. Por eso usamos constrain() para asegurar ese rango.
La función analogWrite() usa PWM (Modulación por Ancho de Pulso) para controlar el brillo del LED. Si quieres saber más, consulta nuestro tutorial sobre How use Arduino to control an LED with a Potentiometer.
¡Listo! Ahora tienes una luz regulada que se ilumina más cuanto más oscuro esté el entorno. Si quieres menos o más sensibilidad, ajusta los valores del rango de entrada (50, 300).
Construyendo un detector de dirección de luz
Podemos modificar fácilmente nuestro circuito de detección de luz para convertirlo en un detector de dirección de luz. Para ello simplemente reemplazamos el trimmer por un segundo LDR. Como ves abajo, el nuevo circuito sigue siendo un divisor de voltaje pero con dos LDRs.

Dependiendo de cuál de los LDRs recibe más luz, el voltaje en A0 aumentará o disminuirá. Ten en cuenta que no importa cuánta luz reciban los LDRs. Brillante u oscuro, el voltaje en A0 será aproximadamente el mismo. Lo que importa es la proporción. Cuanto mayor sea la diferencia de luz recibida, más cambiará A0 desde su valor medio de unos 2.5 V.
Construyamos este circuito en la protoboard. Como es esencialmente el mismo circuito que antes, solo quitamos el trimmer y lo reemplazamos por un LDR.

La corriente fluye desde el riel positivo a través de la serie de los dos LDRs hacia el riel negativo. Como antes, tomamos la señal (cable amarillo) del punto de unión y la conectamos al Pin A0 del Arduino.
A continuación puedes ver el código que usaremos.
const int ldrPin = A0;
const int midValue = 500;
const int midRange = 10;
int ldrValue = 0;
void setup() {
Serial.begin(9600);
pinMode(ldrPin, INPUT);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.print("LDR:");
Serial.println(ldrValue);
if (ldrValue > midValue + midRange) {
Serial.println("Left");
} else if (ldrValue < midValue - midRange) {
Serial.println("Right");
} else {
Serial.println("Middle");
}
delay(100);
}
Extendemos el código simple del detector de luz anterior añadiendo dos variables. midValue es el valor que esperamos leer de A0 cuando ambos LDRs están expuestos a la misma cantidad de luz. En teoría ese valor debería ser 1023/2 = 512 (la mitad del rango de entrada). En la práctica, la resistencia de los dos LDRs nunca es idéntica y el valor real será ligeramente diferente.
const int midValue = 500; const int midRange = 10;
Para encontrar ese punto medio, acerca ambos LDRs a una fuente de luz con el mismo ángulo y distancia y lee el ldrValue desde el monitor serial. Ese será tu valor para midValue. En mi caso, leí alrededor de 500, bastante cercano al valor teórico.
La constante midRange define cuánto desviación esperamos de midValue antes de considerar una dirección. Define un margen o tolerancia. Para cualquier valor dentro de ese rango, imprimiremos que la luz está en posición media, ni a la izquierda ni a la derecha.
La función setup() permanece sin cambios. Solo iniciamos el Monitor Serial y configuramos el modo del pin.
En la función loop() leemos ldrValue como antes y luego lo comparamos con midValue.
if (ldrValue > midValue + midRange) {
Serial.println("Left");
} else if (ldrValue < midValue - midRange) {
Serial.println("Right");
} else {
Serial.println("Middle");
}
Si el valor del sensor es mayor que el valor medio más la tolerancia, sabemos que el LDR izquierdo recibió más luz y mostramos «Izquierda». Si el valor es menor que el valor medio menos la tolerancia, mostramos «Derecha». En el caso restante, ambos LDRs reciben aproximadamente la misma luz y mostramos «Centro». Ten en cuenta que «izquierda» y «derecha» dependen de hacia dónde esté orientado tu circuito.
Una nota final: puedes mejorar mucho la sensibilidad direccional colocando los LDRs en tubos para que solo reciban luz direccional. Abajo hay una foto de mi solución casera para probar eso:

Al añadir los tubos puedo detectar con precisión la dirección de la luz y en la siguiente sección te mostraré cómo controlar un servo con ello.
Construyendo un servo controlado por luz
Los servos posicionales están diseñados para girar a un ángulo específico. Esto los hace ideales para probar nuestro detector de dirección de luz. Podremos controlar el ángulo del servo para que apunte hacia la dirección de la luz.
Primero añade el servo conectando su alimentación a los rieles de energía (marrón es negativo y rojo positivo). Luego conecta la entrada de señal del servo (amarillo) con un cable naranja al Pin 9 del Arduino. ¡Listo!

A continuación encontrarás el código para controlar el servo. Es una pequeña extensión del código anterior. Si tienes dificultades para entender el código y su explicación, consulta nuestro tutorial sobre How to Control Servo Motors with Arduino, que ofrece más detalles sobre servos.
#include "Servo.h"
#define IR_RECEIVE_PIN 8
const int ldrPin = A0;
const int servoPin = 9;
const int range = 780;
const int mid = 1600;
const int midValue = 500;
const int midRange = 10;
int ldrValue = 0;
int angle = 0;
Servo servo;
void rotate(int angle) {
angle = map(angle, 0, 180, mid - range, mid + range);
servo.writeMicroseconds(angle);
}
void setup() {
Serial.begin(9600);
pinMode(ldrPin, INPUT);
servo.attach(servoPin);
}
void loop() {
ldrValue = analogRead(ldrPin);
int angle = (ldrValue - midValue) * 0.8;
angle = constrain(angle, -90, +90);
if (angle > midRange) {
rotate(90 + angle);
} else if (angle < -midRange) {
rotate(90 + angle);
} else {
rotate(90);
}
delay(100);
}
El código tiene algunas constantes adicionales como range y mid que se usan en la función rotate(), que rota el servo a un ángulo dado. Aparte de las constantes y funciones relacionadas con el servo, el resto del código es muy similar al que viste antes.
Lo interesante ocurre en la función loop(). Allí convertimos el ldrValue en un ángulo restando el midValue de ldrValue y multiplicando por un factor de 0.8.
int angle = (ldrValue - midValue) * 0.8;
El factor 0.8 es algo que debes ajustar según las dimensiones/física de tu sistema; específicamente la distancia entre los LDRs. Como antes, no hay garantía de que el valor del ángulo esté en el rango de -90 a +90 grados. Por eso lo limitamos:
angle = constrain(angle, -90, +90);
Finalmente, decidimos si girar el servo a la izquierda o derecha según el ángulo detectado. Si el cambio de ángulo es pequeño (-midRange… +midRange), mantenemos el servo en 90 grados.
if (angle > midRange) {
rotate(90 + angle);
} else if (angle < -midRange) {
rotate(90 + angle);
} else {
rotate(90);
}
Con este circuito y código ahora puedes controlar el ángulo del servo según la dirección de la luz. Podrías usar esto para construir un coche que se dirija hacia la luz. Con dos de estos detectores de dirección de luz en orientación perpendicular, podrías construir un panel solar que siga el movimiento del sol para un rendimiento óptimo.
Sin embargo, para aplicaciones de seguimiento de luz deberías preferir un servo continuo en lugar del servo posicional usado aquí. Esto permitiría girar el servo en dirección negativa o positiva hasta alcanzar el punto medio. Para más detalles, lee nuestro tutorial sobre las diferencias de Positional versus Continuous Servos.
Algunas otras aplicaciones de detectores de luz se describen a continuación.
Aplicaciones
Automatización del hogar
Usando un detector de luz, puedes automatizar varias tareas en tu hogar. Por ejemplo, puedes programar tu Arduino para encender las luces cuando detecte oscuridad y apagarlas cuando detecte luz. Esto ayuda a ahorrar energía y proporciona comodidad.
Sistemas de seguridad
Los detectores de luz pueden usarse en sistemas de seguridad para activar alarmas o cámaras cuando hay un cambio repentino en la intensidad de luz. Esto ayuda a detectar intrusos o actividades inusuales en un área específica.
Monitoreo de plantas
La luz es crucial para el crecimiento de las plantas. Usando un detector de luz, puedes monitorear la cantidad de luz que reciben tus plantas y asegurarte de que tengan las condiciones óptimas para crecer. Esto es especialmente útil para jardinería interior o invernaderos.
Estaciones meteorológicas
Los detectores de luz también pueden usarse en estaciones meteorológicas para medir la intensidad de la luz solar. Esta información puede usarse para analizar patrones climáticos, calcular radiación solar o incluso predecir condiciones meteorológicas.
Instalaciones artísticas
Los detectores de luz pueden incorporarse en instalaciones artísticas interactivas para crear efectos de iluminación dinámicos y sensibles. Al detectar cambios en la luz ambiental, el Arduino puede controlar el brillo, color o patrón de las luces, creando una experiencia inmersiva para los espectadores.
Estos son solo algunos ejemplos de las muchas aplicaciones de la detección de luz con Arduino. La versatilidad de Arduino y su compatibilidad con varios sensores lo hacen una excelente opción para proyectos basados en luz.
Resumen
En este tutorial, aprendimos cómo detectar luz usando un Arduino y exploramos varias aplicaciones de sensores de luz en proyectos maker. Usando una fotorresistencia, podemos medir fácilmente la intensidad de luz en nuestro entorno.
Comenzamos entendiendo el concepto básico de una fotorresistencia y cómo funciona. Una fotorresistencia es un tipo de resistencia que cambia su valor según la cantidad de luz que recibe. Esta propiedad la hace ideal para detección de luz.
Luego construimos un detector de luz simple usando un Arduino y una fotorresistencia. Conectando la fotorresistencia a un pin analógico del Arduino, pudimos leer el valor de resistencia y convertirlo en un valor de intensidad de luz correspondiente. Esto nos permitió crear un sistema básico de detección de luz.
Después exploramos aplicaciones más avanzadas. Construimos un interruptor automático que enciende o apaga una fuente de luz según las condiciones de luz ambiental. Esto puede ayudar a ahorrar energía controlando automáticamente la iluminación de una habitación.
También construimos un sistema de luz regulada, donde la intensidad de una fuente de luz se ajusta según las condiciones de luz del entorno. Esto ayuda a mantener un nivel constante de iluminación en un área específica.
Finalmente, construimos un sistema de servo controlado por luz. Usando los valores de intensidad de luz de la fotorresistencia, pudimos controlar el movimiento de un motor servo. Esto abre posibilidades para crear proyectos interactivos que respondan a cambios de luz.
Esperamos que este tutorial te haya dado una base sólida para trabajar con sensores de luz y Arduino. ¡Siéntete libre de explorar las aplicaciones mencionadas y deja que tu creatividad brille!
Preguntas frecuentes
Aquí tienes algunas preguntas frecuentes sobre la detección de luz con Arduino:
¿Puedo usar otra placa microcontroladora en lugar de Arduino?
Sí, puedes usar otras placas como ESP32, Raspberry Pi o STM32 para detectar luz. Los principios y técnicas discutidos aquí se aplican a cualquier placa que soporte entrada analógica.
¿Cómo determino la polaridad de una fotorresistencia?
Las fotorresistencias o LDRs son componentes no polarizados. Esto significa que no tienen terminal positivo o negativo específico. Puedes conectarlas en cualquier orientación sin preocuparte por la polaridad.
¿Cuál es el rango de resistencia de una fotorresistencia?
La resistencia de una fotorresistencia varía con la intensidad de luz. En luz brillante, la resistencia disminuye; en oscuridad, aumenta. El rango típico va desde unos cientos de ohmios en luz brillante hasta varios megaohmios en oscuridad. Es importante elegir valores adecuados de resistencias en tu circuito para asegurar una detección precisa.
¿Cómo puedo calibrar el circuito de detección de luz?
Para calibrar el circuito, puedes ajustar los valores de las resistencias en el divisor de voltaje conectado a la fotorresistencia. Midiendo el voltaje de salida a diferentes niveles de luz, puedes determinar los valores umbral para la detección. Este proceso asegura que el circuito responda con precisión a los niveles deseados.
¿Puedo usar varias fotorresistencias en un solo proyecto?
Sí, puedes usar varias fotorresistencias conectándolas a diferentes pines analógicos del Arduino u otros microcontroladores. Esto permite monitorear niveles de luz desde distintas ubicaciones o direcciones. Es útil en sistemas de seguridad, iluminación automatizada o monitoreo ambiental.
¿Puedo usar un módulo sensor de luz en lugar de una fotorresistencia?
Sí, puedes usar módulos sensores de luz que incluyen fotorresistencias u otros sensores. Estos módulos suelen ofrecer características adicionales como sensibilidad ajustable o salida digital. Consulta su hoja de datos o documentación para entender su pinout y características de operación.
¿En qué se diferencian las fotorresistencias de los sensores de movimiento PIR?
Las fotorresistencias y los sensores de movimiento infrarrojo pasivo (PIR) se usan para detectar cambios ambientales, pero funcionan con principios diferentes. Las primeras detectan cambios en la intensidad de luz, mientras que los PIR detectan cambios en radiación infrarroja causados por objetos en movimiento. Las fotorresistencias son adecuadas para monitorear niveles de luz, mientras que los PIR son ideales para detectar movimiento de personas o animales.
Si tienes más preguntas o necesitas ayuda, no dudes en preguntar en la sección de comentarios abajo.
Enlaces
A continuación algunos enlaces útiles para ampliar la información
- Light Sensor (Photoresistor) With Arduino in Tinkercad
- How to Use Photoresistors to Detect Light on an Arduino
- Arduino Photo Resistor Tutorial (Step by Step) – YouTube
- Understanding this photoresistor circuit – General Electronics
- How to Use a Photoresistor (or Photocell) – Arduino Tutorial
- photoresistor how to use it – General Electronics
- Photoresistor: Basics and Arduino Tutorial


