Turn-key PCB assembly services in prototype quantities or low-volume to mid-volume production runs

Understanding and interfacing LDR – light dependent resistors

LDR (Light Dependent Resistor) is a simple, cheap electronic device. Simply speaking this is a resistor in 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 the wavelength range from 400nm – 850nm. For near infrared spectrum (1μm – 3μm) there are PbS or PbSe materials used. For deeper infrared range (3μm – 1000μm) there are InSb and InAs.

Another 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 the right choice for use as signal receivers – better go with semiconductors. LDR’s have their niche, and they do a good job there.

Let’s build a simple project on the Arduino board. We sill try to LDR resistance when in dark and room light. First of all, we need to construct voltage divider using a 10k resistor and LDR.

This circuit is straightforward and easy to understand. When there is no light LDR resistance is ~5MΩ so directly speaking the voltage on the 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 the majority of LDR based circuits work. Let’s connect this divider to Arduino Mega1280 analog pin A8 and do some measurements.

ldr connected to arduino

Let’s write a simple program which will output analog readings and calculated approximate resistance value to the 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 the room light is ON we get ADC value about 650 and the 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 approximately 0.25V drop and calculated resistance ~190kΩ. With a 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 experimental values we can build another quick project with motor control. Let us attach servo motor to Arduino PWM pin 10. Let us take that 0º angle will match 0V drop. 180º will be 5V. Then we can move servo shaft according to ambient light on LDR. Let’s 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 are serial terminal results: As you can see

LDR_controlled servo

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

Leave a Reply