Understanding and interfacing LDR – light dependent resistors

LDR (Light Dependent Resistor) is simple, cheap electronic device. Simply speaking this is a resistor which resistance varies depending on light intensity. You’ve probably seen typical LDR in some projects where light intensity has to be taken in to account. They can be used to activate light switches, alarms, adjust display brightness and more.

light dependent resistor

Light dependent resistors can be different types. They vary in light sensitive material used. Visible spectrum LDR is made using Cadmium Sulphide (CdS) or Cadmium Selenide (CdSe). This material is sensitive to wavelength range from 400nm – 850nm. For near infrared range (1μm – 3μm) there are PbS or PbSe materials used. For deeper infrared range (3μm – 1000μm) there are InSb and InAs.

Other important parameter of LDR is resistance in dark and light. Usually in dark resistance is in mega-ohms range. While in light resistance is few kilo-ohms.

LDR voltage dividerLDR’s are pretty inertial. It takes from tens to hundreds of ms to settle on sudden light level change. So they aren’t good choice for use as signal receivers – better go with semiconductors. LDR’s have their niche and they do good job there.

Lets build a simple project on Arduino board. We sill try to LDR resistance when in dark and room light. Firs of all we need to construct voltage divider using 10k resistor and LDR.

This circuit is very simple and easy to understand. When there is no light LDR resistance is ~5MΩ so simply speaking the voltage on analog pin is very close to 0V. And when there is light present – the resistance is couple kΩ or even less for very intense light. Then voltage on test pin gets closer to 5V. This is how majority LDR based circuits work. Lets connect this divider to Arduino Mega1280 analog pin A8 and do some measurements.

ldr connected to arduino

Lets write simple program which will output analog readings and calculated approximate resistance value to serial terminal.

int VCC = 5;
int R = 10000;
int ADCmax = 1023;
void setup() {
  Serial.begin(9600);
}
void loop() {
  // read the input on analog pin 8:
  int sensorValue = analogRead(A8);
  // print out the value:
  Serial.print("ADC Value: ");
  Serial.print(sensorValue);
  //calculate voltage on A8
  float voltageDrop = (float)VCC/1023*sensorValue; 
  Serial.print("; Voltage Drop: ");
  Serial.print(voltageDrop);
  Serial.print("V; ");
  //calculate LDR resistance
  float LDR = R/voltageDrop*(((float)VCC-voltageDrop)/1000);
  Serial.print("LDR: ");
  Serial.print(LDR);
  Serial.println("k");
  // delay in between reads
  delay(2000);        
}

This small program may be handy to see what typical LDR values you get on different ambient light:

LDR_read_results

As you can see when room light is ON we get ADC value about 650 and calculated voltage drop is around 3.15V. Having this data we get ~5.8kΩ resistance. When I cover LDR with my hand then I get ADC about 50 which is about 0.25V drop and calculated resistance ~190kΩ. With lighter close to LDR I get less than 1kΩ. Having such data you can start building smart systems with several threshold voltage drops if needed.

Having these empirical values we can build another quick project with motor control. Lets attach servo motor to to Arduino PWM pin 10. Lets take that 0º angle will match 0V drop. 180º will be 5V. Then we can move servo shaft according to ambient light on LDR. Lets make rotation resolution 1º. So 1º step will be 5/180 = 0.027V. Now we can write our program:

#include <Servo.h>
//create servo object
Servo servo1;
int VCC = 5;
int R = 10000;
int ADCmax = 1023;
float degstep= (float)VCC/180;
void setup() {
  Serial.begin(9600);
  //attach servo1 to pin 10
  servo1.attach(10); 
}
void loop() {
  // read the input on analog pin 8:
  int sensorValue = analogRead(A5);
  // print out the value:
  Serial.print("ADC Value: ");
  Serial.print(sensorValue);
  //calculate voltage on A8
  float voltageDrop = (float)VCC/1023*sensorValue; 
  Serial.print("; Voltage Drop: ");
  Serial.print(voltageDrop);
  Serial.print("V; ");
  //calculate LDR resistance
  float LDR = R/voltageDrop*(((float)VCC-voltageDrop)/1000);
  Serial.print("LDR: ");
  Serial.print(LDR);
  Serial.print("k; ");
  // delay in between reads
  int servoPos = (int)(voltageDrop/degstep);
  servo1.write(servoPos);
  Serial.print("servo: ");
  Serial.println(servoPos);
  delay(1000);        
}

And here is serial terminal results:

LDR_controlled servo

As you can see working with light dependent resistors is easy. In an hour you can put simple automation system with servo motor. Hope you enjoyed this walk through.

Leave a Reply

Your email address will not be published. Required fields are marked *