PyRaspBeta

Light sensor (LDR)

An LDR (light-dependent resistor, or photocell) is a two-lead part whose resistance falls as more light reaches it. The shop stocks the GL5528 — about 10–20 kΩ in ordinary room light and around 1 MΩ in the dark — for $0.75. The Pi has no analog inputs, so like every analog sensor the LDR is read as one half of a voltage divider feeding an ADC such as the MCP3008 or ADS1115; the light + ADC board kit is that divider pre-wired.

Light sensor (LDR)

Pins

PinWhat it isType
ALead Apassive
BLead Bpassive

In circuit.py:

The two leads are not polarised — a and b are interchangeable — and because it has only two terminals the LDR chains naturally: pi.V3_3 >> ldr >> adc.ch0 puts it on top of a divider.

Wiring it in circuit.py

An LDR divider on channel 0 of an MCP3008, with a 10 kΩ resistor below the tap. In this orientation the voltage rises as the light rises:

circuit.py
from wiring import *

pi = Pi()

ldr = LDR()
adc = MCP3008()

pi.V3_3 >> ldr.a                       # top of the divider
ldr.b >> adc.ch0                       # the tap: 0–3.3 V
adc.ch0 >> Resistor(10000) >> pi.GND   # bottom of the divider

pi.V3_3 >> adc.vdd
adc.vdd >> adc.vref                     # reference = 3.3 V
adc.agnd >> pi.GND
adc.dgnd >> pi.GND
pi.SCLK >> adc.clk
pi.MISO >> adc.dout
pi.MOSI >> adc.din
pi.CE0 >> adc.cs

Swap the LDR and the resistor and the reading is inverted — dark, not light, raises the voltage. Either direction works as long as main.py knows which one it has. The pre-wired light + ADC board uses the orientation above and exposes the SPI pins only.

Driving it in main.py

main.py
from gpiozero import MCP3008
from time import sleep

light = MCP3008(channel=0)     # 0.0 dark … 1.0 bright

while True:
    print(f"light {light.value:.2f}")
    sleep(1)

light.value is the tap voltage ÷ VREF, so 0.5 means the LDR's resistance equals the 10 kΩ resistor. To get lux you invert the power law below; for a night light it is enough to compare light.value with a threshold. The night light recipe does exactly that.

Electrical notes

  • The model is R = R₁₀ × (lux / 10)^−0.7, capped at the 1 MΩ dark resistance: ten times the light, about a fifth of the resistance.
  • At 10 lux a unit sits anywhere in the 8–20 kΩ band. With a 10 kΩ resistor the tap is about 3.3 × R / (R + 10 kΩ), so the useful range spans much of 0–3.3 V.
  • Power rating is 100 mW. The divider never comes close: 3.3 V across 10 kΩ is about 1.1 mW.
  • The response is slow — 20 ms rising, 30 ms falling — and a real cell "remembers" recent light for a while.
  • Keep the divider on 3.3 V. From 5 V the tap can exceed 3.6 V and the simulator raises an overvoltage warning; the MCP3008 notes cover the same trap for the ADC.

Simulator vs real hardware

  • The light falling on the cell is a datafeed field. By default it follows the illuminance of the LDR's zone (daylight and lamps); in the Lab you can pin it, drive it with a wave, or replay a recording — handy for testing a night light at 100× speed.
  • Unit-to-unit spread is a knob. datasheet range (the default) draws a fixed log-uniform value for this unit, so two LDRs in one run genuinely differ; typical unit pins it to the geometric middle.
  • The behaviour refreshes every 50 ms, so quick shadows arrive as smooth steps rather than instant jumps.
  • There is no spectral response: real CdS cells see green best and are nearly blind to infrared, while the model weights every photon alike. No aging, and no noise beyond the modelled response time.

Going deeper

Further reading