The Circuit Maker
Projects9 min read

Light Sensor Circuit: Build an Automatic LED with a Photoresistor

Build a light sensor circuit using a photoresistor (LDR) that automatically turns on an LED when it gets dark. Includes schematic, component list, and Arduino version.

·

A light sensor circuit uses a photoresistor (LDR) to detect ambient light and automatically turn on an LED when it gets dark. This is the same principle behind automatic night lights, street lights, and garden solar lamps. You can build the basic version with just a few components and no programming, or add an Arduino for precise control and adjustable thresholds.

What you need

Basic version (no Arduino)

ComponentValuePurpose
Photoresistor (LDR)Standard (GL5528 or similar)Light sensing
Fixed resistor10 kΩVoltage divider partner
NPN transistor2N2222 or BC547Switches the LED
LED (5mm)Any colorOutput indicator
LED resistor220Ω–330ΩCurrent limiting for LED
Power supply5V–9V battery or adapterPower source
Breadboard + wiresStandardPrototyping

Arduino version (adds precision)

Same components as above, but the transistor is optional — the Arduino can drive the LED directly from a digital pin and read the LDR on an analog pin.

How the photoresistor works

A photoresistor (light-dependent resistor, LDR) is made of a semiconductor material whose resistance changes with light exposure:

ConditionLDR resistanceBehavior
Bright sunlight~1 kΩ or lessVery low resistance
Indoor lighting~5–20 kΩMedium resistance
Dim light / dusk~50–200 kΩHigh resistance
Darkness~1 MΩ+Very high resistance

The LDR is not polarized — it works in either direction, just like a regular resistor.

The voltage divider principle

The LDR and a fixed resistor form a voltage divider. The midpoint voltage changes with light level:

V_mid = V_supply × R_fixed / (R_LDR + R_fixed)
  • Bright light: R_LDR is low (~1 kΩ). V_mid ≈ 5V × 10k / (1k + 10k) ≈ 4.5V (high).
  • Darkness: R_LDR is high (~1 MΩ). V_mid ≈ 5V × 10k / (1M + 10k) ≈ 0.05V (low).

To make the LED turn on in the dark, we swap the positions — put the LDR on top (connected to positive) and the fixed resistor on the bottom (connected to ground). Now V_mid is high when it's dark and low when it's bright:

V_mid = V_supply × R_LDR / (R_LDR + R_fixed)
  • Darkness: R_LDR is high → V_mid is high → transistor turns on → LED lights.
  • Bright: R_LDR is low → V_mid is low → transistor off → LED off.

Building the basic circuit (no Arduino)

  1. Set up power: connect your 5V supply to the breadboard power rails (positive and ground).
  2. Voltage divider: Connect the LDR between the positive rail and a row (call it row A). Connect the 10 kΩ resistor between row A and the ground rail. Row A is now the midpoint — its voltage varies with light.
  3. Transistor: Place the 2N2222 on the breadboard. Connect the base to row A through a 10 kΩ resistor (to limit base current). Connect the emitter to ground.
  4. LED: Connect the 220Ω resistor from the positive rail to the LED's anode (long leg). Connect the LED's cathode to the transistor's collector.
  5. Cover the LDR with your hand — the LED should light up. Uncover it — the LED should turn off.

Adjusting sensitivity

If the LED turns on/off at the wrong light level, change the 10 kΩ fixed resistor:

  • Higher value (47 kΩ): LED turns on in dimmer conditions (less sensitive).
  • Lower value (4.7 kΩ): LED turns on earlier, in brighter conditions (more sensitive).

For fine-tuning, replace the fixed resistor with a 100 kΩ potentiometer. Turn the pot to set the exact light level where the LED triggers.

Arduino version

Using an Arduino adds precision — you can read exact light levels, set thresholds in code, and add features like hysteresis (to prevent flickering at the threshold).

Wiring

  1. Connect the LDR between 5V and analog pin A0.
  2. Connect a 10 kΩ resistor between A0 and GND (completing the voltage divider).
  3. Connect an LED with a 220Ω resistor from digital pin 8 to GND.

Code

const int LDR_PIN = A0;
const int LED_PIN = 8;
const int DARK_THRESHOLD = 700;  // Adjust this value (0-1023)

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int lightLevel = analogRead(LDR_PIN);
  
  Serial.print("Light level: ");
  Serial.println(lightLevel);
  
  if (lightLevel > DARK_THRESHOLD) {
    digitalWrite(LED_PIN, HIGH);  // Dark - turn LED on
  } else {
    digitalWrite(LED_PIN, LOW);   // Bright - turn LED off
  }
  
  delay(200);
}

How to calibrate

  1. Upload the code and open the Serial Monitor (Tools → Serial Monitor).
  2. Observe the light level value in bright conditions (might be ~200–400).
  3. Cover the LDR and note the dark value (might be ~800–950).
  4. Set DARK_THRESHOLD to a value between the two (e.g., 700).
  5. Re-upload and test — the LED should turn on when you cover the LDR.

Adding hysteresis (preventing flicker)

Without hysteresis, the LED flickers when the light level is right at the threshold. Fix this by using two thresholds — one to turn on and a lower one to turn off:

const int THRESHOLD_ON = 700;   // Turn on when above this
const int THRESHOLD_OFF = 500;  // Turn off when below this
bool ledState = false;

void loop() {
  int lightLevel = analogRead(LDR_PIN);
  
  if (lightLevel > THRESHOLD_ON) {
    ledState = true;
  } else if (lightLevel < THRESHOLD_OFF) {
    ledState = false;
  }
  // Between thresholds: keep current state (hysteresis)
  
  digitalWrite(LED_PIN, ledState ? HIGH : LOW);
  delay(100);
}

Real-world applications

ApplicationHow it uses light sensing
Automatic night lightsLED or lamp turns on when room gets dark
Street lightsTurn on at dusk, off at dawn
Solar garden lightsCharge during day, light up at night
Screen brightnessPhones adjust display brightness to ambient light
Security systemsDetect when a beam of light is broken
Light metersMeasure light intensity for photography

Troubleshooting

ProblemCauseFix
LED is always onFixed resistor too low, or LDR getting no lightIncrease fixed resistor or check LDR placement
LED is always offFixed resistor too high, or LDR saturatedDecrease fixed resistor value
LED flickers at thresholdNo hysteresisAdd dual thresholds (Arduino) or RC filter
Very slow responseNormal — LDRs take 10-100ms to changeUse a phototransistor for faster response
Arduino reads 0 or 1023 alwaysWiring error — divider not connectedVerify LDR and resistor form a divider between 5V and GND

Summary

A light sensor circuit uses an LDR (photoresistor) whose resistance changes with light level. Paired with a fixed resistor in a voltage divider, it produces a variable voltage that can drive a transistor switch (basic version) or be read by an Arduino analog input (programmable version). The circuit turns an LED on in darkness and off in light. Adjust sensitivity by changing the fixed resistor value; add hysteresis to prevent flickering at the switching threshold.