Light Measurement With CDS Photocells


 Back To Index


Figure #1: CDS Photocell

Sometimes referred to as photoresistors or light-dependent resistors, CDS photocells are used to measure the intensity of light, and they're probably one of the easiest sensors you'll use for robotics applications. CDS photocells are made of Cadmium Sulfide, hence the name CDS photocell.

Operation is simple. Light striking the surface of the photocell causes a decrease in resistance, while darkness produces a higher resistance. Measuring light levels with the the CDS photocell is simple with the PicBasic Pro RCTIME command. Here's how it works.

RCTIME Pin, State, Var

The RCTIME command measures the time Pin stays in a particular logic State, and returns this time in Var.

Right_CDS VAR PORTA.0   ' Right side CDS photocell is connected to PortA.0
Right_Raw VAR WORD      ' Word sized variable to hold raw right side CDS reading
Right_Val VAR BYTE      ' Holds right CDS priority encoded bit after NCD operation

Check_CDS:
  HIGH Right_CDS               ' Make right CDS pin high to charge cap
 
PAUSE 3                      ' Let cap charge for 3 milliseconds
 
RCTIME Right_CDS,1,Right_Raw ' Make pin an input & record the discharge time

Here's what's happening. In the code example above, Right_CDS has been assigned to PortA.0. Right_Raw is declared as a word variable to hold the raw light measurement or time count returned by the RCTIME command. These port assignments and variables are in the HARDWARE.INC file, but shown here for clarity.

As shown below in Figure #2, one side of the CDS connects to ground. The other side connects to the 0.01uF capacitor. The 220Ω resistor connects to the node between the CDS and capacitor.  The first line in our code sets pin PortA.0 to logic 1 or high. The following PAUSE 3 allows time for the PortA.0 pin to charge the capacitor to +5V.

After PAUSE 3 the RCTIME command makes the PortA.0 pin an input. At the same time it starts recording the "time" the PortA.0 pin "Right_CDS" takes to change from logic 1 to logic 0 or ground. Making the pin an input takes the pin to a "High-impedance" state allowing the caps lower plate to discharge back to ground through the CDS resistor. Since the CDS resistance will vary with light levels, hence the discharge time returned in Right_Raw will also vary, and we can measure these changes or light levels with the value returned by the RCTIME command.

The resolution [increments of time] of the RCTIME command is dependent on the oscillator frequency. At 20MHz the time is returned in 2uS [two microsecond] increments.  At 4MHz time counts are returned in 10uS increments. At 20MHz a reading of 4000 returned in the Right_Raw word variable would indicate 4000 x 2uS or 8mS. From the time PortA.0 was made an input, it took 8mS for the pin to return to ground. If the pin never changes state, the value returned by RCTIME will be 0.


Photo #1: Parts Photo

Parts List:

bullet

2 x Photonic Detectors, Inc. 10K to 200K CDS Photocells

bullet

2 x 0.01uF 50V Ceramic Caps [marked 103]

bullet

2 x 220Ω 1/8W Resistors [RED, RED, BROWN]


Figure #2: CDS Photocell Experiment Schematic

CDS photocells are best when used indoors, but they do have applications in extreme environments like bright sunlight or total darkness. In direct sunlight the resistance is very low. In total darkness the resistance is very high.  Intense light will cause a very low resistance which makes the response time short. The lower resistance allows the cap to discharge almost instantly. In total darkness the discharge time may exceed the RCTIME maximum count of 65535 [the maximum size of a word variable] due to the increased resistance. At 20MHz the maximum number of counts would be 65535 x 2uS or 0.13107 seconds.

You may want to experiment with different capacitor values depending on your environment. We have supplied 0.01uF and 0.1uF ceramic capacitors for you to experiment with. Try changing values in very light or dark situations to see the effects.

In this example we'll use two CDS photocells. Build the circuits shown above in Figure #2. Place both photocells on the front of Micro-Bot with one on the left side, and one on the right side. Place them at approximately a 45° angle to each other similar to the drawing in Figure #3 below.


Figure #3: CDS Placement

The code example below will read each photocell, and cause Micro-Bot to turn right or left depending on which photocell detects the brightest light.  Since readings will fluctuate even with slight variances in light levels, we'll use the NCD operator to return the priority encoded bit number when comparing readings. This keeps Micro-Bot from jerking back & forth quickly due to slight variances in changing light, and the values returned with the RCTIME command.

Example:

After taking a reading from each photocell, the results returned are;

Right_Raw returns 1500 [0000 0101 1101 1100 binary]
Right_Val = NCD Right_Raw Bit 11 is the highest bit set. NCD result = 11
Left_Raw returns 995 [0000 0011 1110 0011 binary]
Left_Val = NCD Left_Raw Bit 10 is the highest bit set. NCD result = 10

The larger reading indicates the darker side. If we use the approach IF Right_Raw > Left_Raw THEN turn left, Micro-Bot will turn back & forth wildly even with slight variations in light levels.

This would be pretty useless since these values will change really quickly, so we'll use NCD to return only the highest bit set. As shown above in bold, Bit 11 is the highest bit set in Right_Raw. Using the NCD operator returns only the highest bit set in Right_Val & Left_Val like this;

Right_Val = NCD Right_Raw
Left_Val =  NCD Left_Raw

Notice how we only need byte-sized variables [Left_Val & Right_Val] since the returned values can only be from 1 to 16 with the NCD operator. Also notice that if one value is a only 1 single bit higher than the other value that it will be twice as large.

Example:

If only bit 11 is set in a word sized variable, the actual binary value is 0000 0100 0000 0000 or 1024 decimal. If only bit 10 is set in the second word variable, the binary value is 0000 0010 0000 0000 or 512 decimal. While this may seem like a huge difference when comparing the results of measurements, it's really very little considering the non-linear nature of the CDS photocell response to light changes, and how quickly it will change.

We want to subtract one value from the other to find the difference, but we can't subtract until we know which number is the greater of the two. So we use -

IF Right_Val > Left_Val THEN

IF Left_Val > Right_Val THEN

This is a simple example that will cause Micro-Bot to turn in the direction of the brightest light source. Kind of like a light compass. Try pointing a flashlight at one of the CDS photocells and watch Micro-Bot turn towards the light.

'***********************************************
'*  Name    : CDS1.BAS                         *
'*  Author  : Bruce Reynolds                   *
'*  Notes   : Micro-Bot CDS Light Measurements *
'***********************************************

' Declare a few local variables '
Right_Val VAR BYTE     ' Right CDS reading for comparison
Left_Val  VAR BYTE     ' Left CDS reading for comparison

INCLUDE "HARDWARE.INC" ' Hardware setup & variables
 
Begin:
  GOSUB Check_CDS
  IF Right_Val > Left_Val THEN
   IF
(Right_Val-Left_Val) >= 1 THEN  ' Is right CDS >= 2 x darker than the left?
    FOR
X = 0 TO 2                    ' If yes then turn left
     PULSOUT Left_Servo,ReverseLeft   ' Reverse left servo
    
PULSOUT Right_Servo,ForwardRight ' Forward right servo
    
PAUSE 20
    NEXT
    GOTO
Begin
   ENDIF
  ENDIF
 
  IF
Left_Val > Right_Val THEN
   IF
(Left_Val-Right_Val) >= 1 THEN  ' Is left CDS >= 2 x darker the right?
    FOR
X = 0 TO 2                    ' If yes then turn right
     PULSOUT Left_Servo,ForwardLeft   ' Forward left servo
    
PULSOUT Right_Servo,ReverseRight ' Reverse right servo
    
PAUSE 20
    NEXT
   ENDIF
  ENDIF
  GOTO
Begin      'Return
   
Check_CDS:
  HIGH Right_CDS               ' Make right CDS pin high
 
PAUSE 3                      ' Let cap charge
 
RCTIME Right_CDS,1,Right_Raw ' Time & record discharge time
 
HIGH Left_CDS                ' Make left CDS pin high
 
PAUSE 3                      ' Let cap charge
 
RCTIME Left_CDS,1,Left_Raw   ' Time & record discharge time
 
Right_Val = NCD Right_Raw
  Left_Val =  NCD Left_Raw  
  RETURN
   
  END

See the Navigation With CDS Photocells & Infrared project for a more advanced example of using both infrared & CDS photocells for navigation.


 Back To Index

Copyright © 2007 Reynolds Electronics
http://www.rentron.com