If you need a cheap, simple way to detect day/night transitions or measure relative ambient brightness, the light dependent resistor sensor (often called an LDR or photoresistor) is a staple of the hobbyist workbench. A standard 5mm GL5528 CdS cell costs around $0.10, requires no complex communication protocols, and interfaces directly with any microcontroller's analog-to-digital converter (ADC). However, moving from a simple 'dark vs. light' threshold to actual, repeatable lux measurements requires understanding voltage dividers, logarithmic scaling, and the physical quirks of cadmium sulfide.
How a Light Dependent Resistor Sensor Actually Works
A light dependent resistor sensor relies on the principle of photoconductivity. The active element is typically a thin film of cadmium sulfide (CdS) deposited in a serpentine pattern on a ceramic substrate. When photons with sufficient energy (usually visible light) strike the semiconductor, they excite electrons from the valence band into the conduction band. This increases the number of charge carriers, effectively lowering the electrical resistance of the material. In total darkness, a standard GL5528 exhibits a 'dark resistance' of 1 MΩ or higher. When exposed to 10 lux of light (roughly twilight), that resistance drops to about 10 kΩ, and in direct sunlight (10,000+ lux), it can fall below 1 kΩ.
The clear epoxy coating over the CdS element is not just for physical protection; it acts as a spectral bandpass filter. CdS cells are engineered to peak in sensitivity around 540 nm (green-yellow light), which closely mimics the photopic luminosity function of the human eye. This makes them excellent for applications where you want the sensor to 'see' light the way a person does, but it also means they are virtually blind to infrared (IR) emissions from remote controls or heat sources, and they under-report the intensity of deep-blue or UV-rich light sources compared to a calibrated silicon photodiode.
Wiring the Light Dependent Resistor Sensor to Microcontrollers
An LDR is a passive resistive component. It does not output a voltage or a digital signal on its own. To read it with a microcontroller, you must wire it into a voltage divider circuit to convert its changing resistance into a varying analog voltage. Alternatively, if you buy a pre-assembled 'LDR module', it likely includes an LM393 comparator chip that outputs a digital HIGH/LOW signal based on a potentiometer threshold. For precision and actual lux calculation, we will focus on the analog voltage divider method.
| Component / Node | Arduino Uno (5V Logic) | ESP32 DevKit (3.3V Logic) | Engineering Notes |
|---|---|---|---|
| LDR Leg 1 | 5V (VCC) | 3.3V (VCC) | Supply range is typically 2.5V to 5V. Keep it stable; VCC ripple directly ruins ADC accuracy. |
| LDR Leg 2 (Node) | Analog Pin (e.g., A0) | ADC1 Pin (e.g., GPIO 34) | This is the measurement node. Connect the fixed resistor here as well. |
| Fixed Resistor (10kΩ) | Between Node and GND | Between Node and GND | A 10kΩ pulldown is ideal for indoor lighting (10-500 lux). Use 1kΩ for bright outdoor sunlight. |
| Fixed Resistor Leg 2 | GND | GND | Ensure a clean ground connection to avoid ground-loop noise in the ADC reading. |
Converting Raw ADC Readings to Lux (The Math)
Getting a raw ADC number (like 512 or 2048) is useless for physical logging. You must mathematically convert that raw integer into a voltage, then into the LDR's resistance, and finally into Lux. This requires a three-step calculation.
Step 1: Raw ADC to Voltage
First, convert the microcontroller's raw integer into the actual voltage at the divider node. For a 10-bit Arduino Uno, the max value is 1023. For a 12-bit ESP32, it is 4095.
V_out = ADC_raw * (V_ref / Max_ADC_Value)
Example (ESP32, 3.3V reference, raw reading of 2048):
V_out = 2048 * (3.3 / 4095) = 1.65V
Step 2: Voltage to LDR Resistance
Using the standard voltage divider formula, we solve for the resistance of the LDR. Assuming the LDR is connected to VCC (top) and the fixed 10kΩ resistor is connected to GND (bottom):
R_ldr = R_fixed * ((V_in / V_out) - 1)
Example (10kΩ fixed resistor, 3.3V in, 1.65V out):
R_ldr = 10000 * ((3.3 / 1.65) - 1) = 10,000 Ω (10kΩ)
Step 3: Resistance to Lux (Logarithmic Scaling)
The relationship between a CdS cell's resistance and illuminance is not linear; it is logarithmic. The standard empirical formula used to model this is:
Lux = 10 ^ ((log10(R_10) - log10(R_ldr)) / Gamma) * 10
For a typical GL5528 sensor, R_10 (resistance at 10 lux) is nominally 10,000 Ω, and the Gamma (slope of the log-log curve) is approximately 0.7. If your calculated R_ldr is 1,000 Ω:
Lux = 10 ^ ((4.0 - 3.0) / 0.7) * 10 = 10 ^ (1.428) * 10 ≈ 268 Lux
Note: Because manufacturing tolerances on cheap CdS cells can vary by ±50%, you should calibrate your specific sensor by measuring its resistance at a known lux level (using a smartphone lux meter app in a controlled room) and adjusting the R_10 constant in your code.
Real-World Interference and Calibration Gotchas
When moving from the breadboard to a real-world deployment, you will encounter three major interference sources that corrupt light dependent resistor sensor data:
- Asymmetric Response to PWM Lighting: This is the most common failure mode in modern homes. CdS cells have a slow response time, but more importantly, their rise time (dark to light, ~20ms) is faster than their fall time (light to dark, ~50ms). When exposed to the 1kHz to 5kHz PWM dimming used in cheap LED bulbs, the LDR cannot fully recover its dark resistance during the microsecond 'off' cycles. This asymmetric integration causes the sensor to read a significantly lower resistance (higher perceived lux) than a steady-state DC light source of the exact same true brightness. Fix: Add a 10µF to 47µF electrolytic capacitor in parallel with your fixed pulldown resistor to hardware-low-pass the PWM ripple before it hits the ADC.
- Temperature Coefficient Drift: The resistance of cadmium sulfide is highly sensitive to ambient temperature. A temperature increase of 20°C can cause the dark resistance to drop by up to 20%, which your microcontroller will misinterpret as an increase in ambient light. If deploying outdoors or near heat-generating electronics, you must pair the LDR with a thermistor (like an NTC 10k) and apply temperature compensation in software.
- Dielectric Memory Effect: If an LDR is exposed to very bright light (like direct sunlight) and then moved into a dark room, it does not instantly return to its 1 MΩ dark resistance. The epoxy and semiconductor lattice exhibit a 'memory' effect, taking several seconds to fully stabilize. Software debounce or a moving-average filter spanning 3-5 seconds is mandatory for transition detection.
Frequently Asked Questions
Can I connect a light dependent resistor sensor directly to a Raspberry Pi?
No, you cannot wire an LDR directly to a Raspberry Pi's GPIO pins for analog measurement. The Raspberry Pi (including the Pi 4 and Pi 5) does not have a built-in analog-to-digital converter (ADC); its GPIO pins only read digital HIGH (3.3V) or LOW (0V). To use an LDR with a Pi, you must either route the voltage divider output through an external SPI ADC chip like the MCP3008, or use a 555 timer / RC timing circuit where the Pi measures the frequency of a square wave that changes based on the LDR's resistance.
Why are my readings erratic under modern LED room lighting?
Erratic readings under LEDs are almost always caused by the high-frequency Pulse Width Modulation (PWM) used by the LED driver circuitry to control brightness, combined with the 50/60Hz AC mains ripple. While the LDR's slow physical response time naturally filters out 120Hz mains flicker, the high-frequency switching noise can alias into the microcontroller's ADC sampling rate. Placing a 0.1µF ceramic capacitor directly across the ADC input pin and GND, alongside the 10µF bulk capacitor mentioned earlier, will create a robust hardware low-pass filter that smooths out these high-frequency spikes before the software even sees them.
Should I use an LDR or a BH1750 digital sensor for my project?
Choose the light dependent resistor sensor if your budget is strictly under $0.50, you only need a relative 'day vs. night' threshold, or you are building a simple analog circuit without a microcontroller. Choose the BH1750 (which costs around $2.00) if you need true, calibrated Lux measurements, linear output, and immunity to temperature drift. The BH1750 uses an I2C interface, contains an internal ADC and processing logic, and completely bypasses the messy logarithmic math and voltage divider calibration required by analog CdS cells. (All About Circuits: Photoresistors)






