Embedded Systems
How to use a photoresistor (LDR) with Arduino
A photoresistor, or LDR (light-dependent resistor), is a resistor whose resistance falls as light gets brighter. An Arduino can't measure resistance directly, so you put the LDR in a voltage divider with a fixed resistor and read the middle on an analog pin. With the LDR on top and 10 kΩ below, brighter light means a higher analogRead.
Wire it as a divider
Join the LDR from 5 V to A0, and a 10 kΩ resistor from A0 to GND. The two share the 5 V in proportion to their resistances, and A0 sees the share across the 10 kΩ:
At night the LDR might be 30 kΩ: A0 gets a quarter of the 5 V, about 1.25 V, and reads about 250. When the LDR happens to be 10 kΩ too, the split is even and it reads about 512. In bright sun it falls under 1 kΩ and the reading climbs toward 1023, though it never quite gets there.
Live experiment
Slide from night to full sun
Slide the light from a dark night to full sun. The LDR's resistance falls, it shares the 5 V with the 10 kΩ below it, and A0 reads the middle on the 0 to 1023 scale. The board prints dark or bright, with the line at 512.
“Light in, number out” is lesson 1 of 6 in Signal Shore, Embedded Systems World 3. Free with an account. Lessons unlock in order, so you’ll do the 14 before it first.
Read it
void setup() {
Serial.begin(9600);
}
void loop() {
int reading = analogRead(A0);
if (reading > 512) Serial.println("bright");
else Serial.println("dark");
delay(200);
}
Swap the LDR and the resistor and everything turns upside down: brighter then means a lower reading. Either way works; just know which you built.
Where should the line go? Print the reading in the conditions you care about, the room at night and the room by day, and put the threshold between them, with room to spare either side. A number read from your own sensor in your own room beats any value from a datasheet, because LDRs of the same type can differ by a factor of two.
Picking the resistor
The reading changes fastest when the two resistances are about equal. So choose a fixed resistor near the LDR's resistance at the light level where you need the most detail. 10 kΩ suits many common LDRs in ordinary indoor light; a dimmer scene suits a bigger resistor.
Making a night light
A single line at 512 works until dusk, when the reading wobbles across it and the light flickers. The cure is hysteresis: turn on below one level and off only above a higher one. LDRs also react slowly, in tens of milliseconds, which is perfect for street lights and garden lamps and useless for anything that flashes fast.
Free lesson
Now build it yourself
Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.
“Light in, number out” is lesson 1 of 6 in Signal Shore, Embedded Systems World 3. Free with an account. Lessons unlock in order, so you’ll do the 14 before it first.
Or start from the very first lesson, no account neededPractice questions
Three quick questions from the lessons. Pick an answer to check it.
Show the answer
Answer: About 1.25 V. The 10 kΩ gets its share of the 5 V: 10 ÷ (30 + 10) = a quarter, so about 1.25 V. The ruler reads that as about 250.
- Why not “About 2.5 V”? 2.5 V is an even split, which needs the LDR to equal the 10 kΩ below it, not 30 kΩ.
- Why not “5 V”? 5 V would need the LDR to be 0 Ω. At 30 kΩ it takes three quarters of the supply.
- Why not “About 3.8 V”? About 3.8 V would mean the 10 kΩ had the bigger share, but at night the 30 kΩ LDR takes most of the 5 V.
Show the answer
Answer: if (reading < 512) digitalWrite(9, HIGH);. Dark means a small reading, below the line. The second option lights it in daylight, the third almost never, and the last one writes a number where HIGH or LOW belongs.
- Why not “digitalWrite(9, reading);”? digitalWrite takes HIGH or LOW, not a reading from 0 to 1023.
- Why not “if (reading > 512) digitalWrite(9, HIGH);”? Above 512 is the bright side, so this lights the LED in daylight, the wrong way round.
- Why not “if (reading == 512) digitalWrite(9, HIGH);”? A reading of exactly 512 almost never happens, so the LED would almost never light.
Show the answer
Answer: High. Less light, fewer free charges, more resistance.
- Why not “Zero”? Even in bright sun an LDR keeps some resistance, and in the dark it climbs far above zero.
- Why not “Low”? Low resistance comes with bright light, when light frees plenty of charge inside the LDR.
- Why not “Negative”? Resistance can't be negative. In the dark an LDR's resistance is at its highest.
“Light in, number out” is lesson 1 of 6 in Signal Shore, Embedded Systems World 3. Free with an account. Lessons unlock in order, so you’ll do the 14 before it first.
Questions people ask
How does a photoresistor work?
Light frees charge carriers inside its strip of semiconductor, usually cadmium sulphide. More light, more free charge, so the resistance falls: from around a megohm in the dark to a few hundred ohms in bright sun, depending on the part.
What resistor should I use with an LDR?
One close to the LDR's resistance at the light level you care about most. 10 kΩ suits ordinary indoor light for many common LDRs. Near the middle, the reading changes most for each change in light, so you get the most detail where you need it.
Can an LDR measure lux accurately?
Not well. Its response curves, varies from part to part and drifts with temperature, and it reacts in tens of milliseconds. It's ideal for dark or bright decisions and rough levels. For real lux readings use a calibrated light sensor chip.
Related topics
- How to wire an LDR (photoresistor)A light-dependent resistor makes no voltage by itself: a divider turns its resistance into one you can read.
- Voltage divider explainedTwo resistors that split a voltage: the formula, potentiometers, and why a load drags the output down.
- How Arduino analogRead worksHow analogRead turns 0–5 V into 0–1023, and how to scale it for analogWrite.
- What is hysteresis, and how does it stop flicker?On below one line, off above another: the gap that stops a noisy reading flickering.