Introduction: Photocell Tutorial!


Photocells a.k.a CdS cells, photoresistors, LDR (light dependent resistor)...

What is a photocell?

Photocells are sensors that allow you to detect light. They are small, inexpensive, low-power, easy to use and don't wear out. For that reason they often appear in toys, gadgets and appliances. They are are often referred to a CdS cells (they are made of Cadmium-Sulfide), light-dependent resistors (LDR), and photoresistors.

A Photocell is basically a resistor that changes its resistive value (in ohms) depending on how much light is shining onto the squiggly face. They are very low cost, easy to get in many sizes and specifications, but are very inaccurate. Each photocell sensor will act a little differently than the other, even if they are from the same batch. The variations can be really large, 50% or higher! For this reason, they shouldn't be used to try to determine precise light levels in lux or millicandela. Instead, you can expect to only be able to determine basic light changes

For most light-sensitive applications like "is it light or dark out", "is there something in front of the sensor (that would block light)", "is there something interrupting a laser beam" (break-beam sensors), or "which of multiple sensors has the most light hitting it", photocells can be a good choice!

Some basic stats

These stats are for the photocell in the Adafruit shop which is very much like the PDV-P8001. Nearly all photocells will have slightly different specifications, although they all pretty much work the same. If there's a datasheet, you'll want to refer to it

  • Size: Round, 5mm (0.2") diameter. (Other photocells can get up to 11mm/0.4" diameter!)
  • Price$1.50 at the Adafruit shop
  • Resistance range: 200K ohm (dark) to 10K ohm (10 lux brightness)
  • Sensitivity range: CdS cells respond to light between 400nm (violet) and 600nm (orange) wavelengths, peaking at about 520nm (green).
  • Power supply: pretty much anything up to 100V, uses less than 1mA of current on average (depends on power supply voltage)
  • Datasheet and another Datasheet
  • Two application notes on using and selecting photocells where nearly all of these graphs are taken from

Step 1: How to Measure Light Using a Photocell


As we've said, a photocell's resistance changes as the face is exposed to more light. When it's dark, the sensor looks like an large resistor up to 10M ohms, as the light level increases, the resistance goes down. This graph indicates approximately the resistance of the sensor at different light levels. Remember each photocell will be a little different so use this as a guide only!

(See Resistance Vs. Illumination graph below)
Note that the graph is not linear, its a log-log graph!

Photocells, particularly the common CdS cells that you're likely to find, are not sensitive to all light. In particular they tend to be sensitive to light between 700nm (red) and 500nm (green) light.

Basically, blue light wont be nearly as effective at triggering the sensor as green/yellow light!

What the heck is lux?

Most datasheets use lux to indicate the resistance at certain light levels. But what is lux? It's not a method we tend to use to describe brightness so it's tough to gauge. Here is a table adapted from a Wikipedia article on the topic!
(See Illumination table below)

Step 2: Testing and Connecting Your Photocell


Testing your photocell

The easiest way to determine how your photocell works is to connect a multimeter in resistance-measurement mode to the two leads and see how the resistance changes when shading the sensor with your hand, turning off lights, etc. Because the resistance changes a lot, an auto-ranging meter works well here. Otherwise, just make sure you try different ranges, between 1M ohms and 1K ohms before 'giving up'

Connecting to your photocell

Because photocells are basically resistors, they are non-polarized. That means you can connect them up 'either way' and they'll work just fine!

Photocells are pretty hardy, you can easily solder to them, clip the leads, plug them into breadboards, use alligator clips, etc. The only care you should take is to avoid bending the leads right at the epoxied sensor, as they could break off if flexed too often.

Step 3: Project Examples



Noisemaker that changes frequency based on light level.


Motor value and directional control with photoresistors and microcontroller


Line-following robot that uses photocells to detect the light bouncing off of white/black stripes

Another robot, this one has two sensors and moves towards light (they're called Braitenberg vehicles)


Using a photocell and pocket laser pointer to create a breakbeam sensor

Step 4: Analog Voltage Read Method


The easiest way to measure a resistive sensor is to connect one end to Power and the other to a pull-down resistor to ground. Then the point between the fixed pulldown resistor and the variable photocell resistor is connected to the analog input of a microcontroller such as an Arduino (shown)
(See circuit diagram below)

For this example I'm showing it with a 5V supply but note that you can use this with a 3.3v supply just as easily. In this configuration the analog voltage reading ranges from 0V (ground) to about 5V (or about the same as the power supply voltage).

The way this works is that as the resistance of the photocell decreases, the total resistance of the photocell and the pulldown resistor decreases from over 600K ohms to 10K ohms. That means that the current flowing through both resistors increases which in turn causes the voltage across the fixed 10K ohm resistor to increase. Its quite a trick!

(See first table below)
This table indicates the approximate analog voltage based on the sensor light/resistance w/a 5V supply and 10K ohm pulldown resistor

If you're planning to have the sensor in a bright area and use a 10K ohm pulldown, it will quickly saturate. That means that it will hit the 'ceiling' of 5V and not be able to differentiate between kinda bright and really bright. In that case, you should replace the 10K ohm pulldown with a 1K ohm pulldown. In that case, it will not be able to detect dark level differences as well but it will be able to detect bright light differences better. This is a tradeoff that you will have to decide upon!

(See second table below)
This table indicates the approximate analog voltage based on the sensor light/resistance w/a 5V supply and 1K pulldown resistor

Note that our method does not provide linear voltage with respect to brightness! Also, each sensor will be different. As the light level increases, the analog voltage goes up even though the resistance goes down:

Vo = Vcc ( R / (R + Photocell) )

That is, the voltage is proportional to the inverse of the photocell resistance which is, in turn, inversely proportional to light levels

Step 5: Simple Demonstration of Use


This sketch will take the analog voltage reading and use that to determine how bright the red LED is. The darker it is, the brighter the LED will be! Remember that the LED has to be connected to a PWM pin for this to work, I use pin 11 in this example.

These examples assume you know some basic Arduino programming. If you don't, maybe spend some time reviewing the basics at the Arduino tutorial?

/* Photocell simple testing sketch.

Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground
Connect LED from pin 11 through a resistor to ground
For more information see www.ladyada.net/learn/sensors/cds.html */

int photocellPin = 0; // the cell and 10K pulldown are connected to a0
int photocellReading; // the analog reading from the sensor divider
int LEDpin = 11; // connect Red LED to pin 11 (PWM pin)
int LEDbrightness; //
void setup(void) {
// We'll send debugging information via the Serial monitor
Serial.begin(9600);
}

void loop(void) {
photocellReading = analogRead(photocellPin);

Serial.print("Analog reading = ");
Serial.println(photocellReading); // the raw analog reading

// LED gets brighter the darker it is at the sensor
// that means we have to -invert- the reading from 0-1023 back to 1023-0
photocellReading = 1023 - photocellReading;
//now we have to map 0-1023 to 0-255 since thats the range analogWrite uses
LEDbrightness = map(photocellReading, 0, 1023, 0, 255);
analogWrite(LEDpin, LEDbrightness);

delay(100);
}

You may want to try different pulldown resistors depending on the light level range you want to detect!

Step 6: Simple Code for Analog Light Measurements:


This code doesn't do any calculations, it just prints out what it interprets as the amount of light in a qualitative manner. For most projects, this is pretty much all that;s needed!

/* Photocell simple testing sketch.

Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground

For more information see www.ladyada.net/learn/sensors/cds.html */

int photocellPin = 0; // the cell and 10K pulldown are connected to a0
int photocellReading; // the analog reading from the analog resistor divider

void setup(void) {
// We'll send debugging information via the Serial monitor
Serial.begin(9600);
}

void loop(void) {
photocellReading = analogRead(photocellPin);

Serial.print("Analog reading = ");
Serial.print(photocellReading); // the raw analog reading

// We'll have a few threshholds, qualitatively determined
if (photocellReading < 10) {
Serial.println(" - Dark");
} else if (photocellReading < 200) {
Serial.println(" - Dim");
} else if (photocellReading < 500) {
Serial.println(" - Light");
} else if (photocellReading < 800) {
Serial.println(" - Bright");
} else {
Serial.println(" - Very bright");
}
delay(1000);
}

To test it, I started in a sunlit (but shaded) room and covered the sensor with my hand, then covered it with a piece of blackout fabric.

Step 7: BONUS! Reading Photocells Without Analog Pins


Because photocells are basically resistors, its possible to use them even if you don't have any analog pins on your microcontroller (or if say you want to connect more than you have analog input pins). The way we do this is by taking advantage of a basic electronic property of resistors and capacitors. It turns out that if you take a capacitor that is initially storing no voltage, and then connect it to power (like 5V) through a resistor, it will charge up to the power voltage slowly. The bigger the resistor, the slower it is.

This capture from an oscilloscope shows whats happening on the digital pin (yellow). The blue line indicates when the sketch starts counting and when the counting is complete, about 1.2ms later.

This is because the capacitor acts like a bucket and the resistor is like a thin pipe. To fill a bucket up with a very thin pipe takes enough time that you can figure out how wide the pipe is by timing how long it takes to fill the bucket up halfway.

In this case, our 'bucket' is a 0.1uF ceramic capacitor. You can change the capacitor nearly any way you want but the timing values will also change. 0.1uF seems to be an OK place to start for these photocells. If you want to measure brighter ranges, use a 1uF capacitor. If you want to measure darker ranges, go down to 0.01uF.

/* Photocell simple testing sketch.
Connect one end of photocell to power, the other end to pin 2.
Then connect one end of a 0.1uF capacitor from pin 2 to ground
For more information see www.ladyada.net/learn/sensors/cds.html */

int photocellPin = 2; // the LDR and cap are connected to pin2
int photocellReading; // the digital reading
int ledPin = 13; // you can just use the 'built in' LED

void setup(void) {
// We'll send debugging information via the Serial monitor
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // have an LED for output
}

void loop(void) {
// read the resistor using the RCtime technique
photocellReading = RCtime(photocellPin);

if (photocellReading == 30000) {
// if we got 30000 that means we 'timed out'
Serial.println("Nothing connected!");
} else {
Serial.print("RCtime reading = ");
Serial.println(photocellReading); // the raw analog reading

// The brighter it is, the faster it blinks!
digitalWrite(ledPin, HIGH);
delay(photocellReading);
digitalWrite(ledPin, LOW);
delay(photocellReading);
}
delay(100);
}

// Uses a digital pin to measure a resistor (like an FSR or photocell!)
// We do this by having the resistor feed current into a capacitor and
// counting how long it takes to get to Vcc/2 (for most arduinos, thats 2.5V)
int RCtime(int RCpin) {
int reading = 0; // start with 0

// set the pin to an output and pull to LOW (ground)
pinMode(RCpin, OUTPUT);
digitalWrite(RCpin, LOW);

// Now set the pin to an input and...
pinMode(RCpin, INPUT);
while (digitalRead(RCpin) == LOW) { // count how long it takes to rise up to HIGH
reading++; // increment to keep track of time

if (reading == 30000) {
// if we got this far, the resistance is so high
// its likely that nothing is connected!
break; // leave the loop
}
}
// OK either we maxed out at 30000 or hopefully got a reading, return the count

return reading;
}

Comments

author
mistergjk made it!(author)2016-11-11

This is pretty fun, yet kinda annoying.

IMG_0634.JPG
author
VishwarathT made it!(author)2016-07-01

What is the appropriate sensor to measure intensity of blue light

author
AnantO made it!(author)2016-05-16

i want to use multiple LDRs and collect data at the same time of resistance , how can i colllect it from multiple LDR system.

author
ZeeshanZulfiqar made it!(author)2016-02-24

photos taken from this pdf... https://learn.adafruit.com/downloads/pdf/photocells.pdf

author
ZeeshanZulfiqar made it!(author)2016-02-18

hi pls help me i want to ask that can photocell respond to red laser light?

author
AndreaB3 made it!(author)2015-11-10

Silly Q: is it possible to break a photocell by supllying it too much light (for example using a phone's led?)

author
sjones124 made it!(author)2015-09-29

I'm a bit confused with a project I'm working on. I'm trying to add a LDR to a 6V DC battery powered strobe light. I assumed that I could just put it in line either between + and on/off switch, on/off and petentiometer, or between - and circuit board connection. None of these connections have worked. Do I need to build an additional circuit for the LDR to work?

author
vlad.fara.1 made it!(author)2015-03-20

Great tutorial :D May you tell me the app where you read the graph and in which format? I would really need it for an important contest.. Thanks in advance :)

author
Porda made it!(author)2015-03-17

Thanks for the great ible. This has answered a lot of questions I had about photocells and using them with Arduino.

author
BookLover715 made it!(author)2013-05-12

Is it possible to get photo sensors that are sensitive to other colors, like blue/UV or IR?

author
Artificial+Intelligence made it!(author)2009-06-17

Really nice tutorial. There is another photoresistor setup, that's worth mentioning. Instead of having a variable resistor (in this case a photoresistor) connected to the positive and a fixed resistor connected to ground, you could use two photoresistors (schematic shown below). this is called a differential light sensor. This setup can be used to measure the difference between the two sensors with one analog input. If the two sensors are exposed to the same amount of light, the readout on the ADC pin should be around 512, if the microcontroller has a 10 bit resolution. If the photoresistor connected to ground is exposed to more light than the other one, the analog voltage would drop, and if the photoresistor connected to positive is exposed to more light, the voltage would rise.

author
Artificial+Intelligence made it!(author)2009-06-17

Sorry. The schematic, I uploaded somehow couldn't be added to the comment.

author
Chowmix12 made it!(author)2011-01-27

If both light sensors were receives bright light (low resistance) wouldn't there be a short circuit?

author
diy_bloke made it!(author)2012-01-06

I don't think they wld go all the way to 0, but you cld include 2 equal resistors in series with each LDR

author
ReCreate made it!(author)2009-06-17

that is why they call it photoresistors...I always thought that they either went ON or OFF...

author
drock267 made it!(author)2009-06-11

Great 'ible. I just finished my senior project using photoresistors to make an interactive LED table. It also involved some PLC programming for the I/O behaviors. I am entered in a competition tomorrow against my fellow graduating classmates. Here's hoping I win some $$ and get an interview or ten. I learned a great deal about photo cells from personal research and this 'ible explains it pretty clear.

author
alessiof76 made it!(author)2009-06-11

good tutorial!
Did you know that the LED can be used as a photocell?
25 mV with 60 W of lighting small green led
i test it: http://www.youtube.com/watch?v=L3-0aCJOedo (only in italian sorry)

author
balam made it!(author)2009-06-11

Thank you for this tutorial very informative

About This Instructable

245,032views

153favorites

License:

Bio: All-original DIY electronics kits - Adafruit Industries is a New York City based company that sells kits and parts for original, open source hardware electronics projects ... More »
More by adafruit:Adaruit Resistor HelperAdafruit Photo TutorialLogger Shield: Datalogging for Arduino
Add instructable to: