Use of Cadmium Sulphide Resistor for Light Detection

A cadmium sulphide resistor is simply a light sensitive resistor, that is, the resistance changes as a function of the light intensity. A common application is switching on street lamps at dusk. Small cadmium sulphide resistors are readily available from Jameco and numerous others for less than $1.00.

Figure #1 illustrates how the resistance varies with light intensity for a typical cadmium sulphide resistor. Note that at one foot-candle (quite dark) the resistance is close to 30 KOHMS and at 50 foot-candles, which is typical of an electrical engineering laboratory, it is slightly over 1K. Note that the general form of the equation for resistance is;

R = k_1 * I ^ (-k_2)

where I is the light intensity.

In fact, vendors do not normally provide such a plot. Rather, such vendors as Jameco simply provide values of R_dark and R_light. I am uncertain as to the light intensities for "dark" and "light" or if there is a standard. (I would welcome any information on this).

A typical light detector is illustrated in Figure #2. Assume the Cd S resistor has the characteristics shown in the plot in Figure #1. When the light intensity is less than 10 foot candles, the value of R_det is greater than 4.7 K. Thus, the voltage at node A is greater than that at node B, and the output of the comparator is at a logic one. Thus, for light intensities less than nominally 10 foot-candles, the comparator output is at a logic one and it is at logic zero for light intensities above the 10 foot-candle threshold. Of course, the logic may be reversed by simply interchanging the inputs to the comparator.

In designing your own detector, there is no need for you to use a foot-candle meter! Rather, measure the resistance at the high light threshold above which you want the detector to be in one state and then measure at the low light level below which you definitely want the detector to be in the other state, and then pick a value of R3 between these two values. For example, we measured 1.0K at the high light level and 10.0K at the low light level and settled on R3=4.7K as a threshold. Resistors R1 and R2 are equal and should be selected such that they are in the same ballpark as R3 such that the voltage at the output of the voltage divider has a maximum swing as the cadmium sulphide R_det varies. For example, values of R1 = R2 = 10 Ohms would be ridiculous as the output of the divider would be close to 5.0 Volts for all realistic values of the cadmium sulphide resistor.

Program LIGHT_1.C is a simple routine to detect light by continually monitoring the output of the comparator. This concept is used in the discussion of a Selectable Melody Player elsewhere in the manual where the detection of a light change causes a melody to be randomly selected and played.

** Program LIGHT_1.C
** Detects whether output of CDs threshold circuit is reporting
** a "light" or "dark" condition.  Uses parallel input BUSY.
** Peter H. Anderson, MSU, August 25, '96

#include <stdio.h>
#include <dos.h>

#define DATA 0x03bc
#define STATUS DATA+1
#define CONTROL DATA+2

void main(void)
   while (1)
      if (((inportb(STATUS)^0x80)>>7) == 1)


Consider an application where a certain darkness causes a lamp to turn on. If a single threshold detector as discussed above is used, the added light from the lamp may well then cause the lamp to turn off, and the process will then repeat. A simple remedy is to incorporate hysterisis in the design.

A typical circuit which incorporates two thresholds is illustrated in Figure #3. Note that the lamp is switched on when the light intensity falls below nominally 10 foot-candles (R_det = 4.7K). The lamp then stays on until the light intensity is above nominally 20 foot-candles (R_det = 2.2K).

In program LIGHT_2.C, the BSY and /ACK leads which are bits 7 and 6 on the Status Port are continually scanned (line 13). If the lamp is on, but the light intensity is above 10 foot-candles, these leads are at 0, 0 and no action is taken. If, the light intensity is above 20 foot-candles, these leads are at 1, 0, and the light is turned off (line 18). If, below 10 foot-candles, the leads are at 0, 1 and the lamp is turned on. Note that if the circuit is operating properly, the leads should never assume a 1, 1 state. Most probably, the circuit is not connected to the parallel port.

** Program LIGHT_2.C
** Light detector with hysterisis.  If light intensity less than
** 10 foot-candles, lamp is turned on.  Lamp is turned off when
** light intensity goes above 20 foot-candles.
** Peter H. Anderson, MSU, August 25, '96

#include <stdio.h>                                            /* 1 */
#include <dos.h>                                              /* 2 */
                                                              /* 3 */
#define DATA 0x03bc                                           /* 4 */
#define STATUS DATA+1                                         /* 5 */
#define CONTROL DATA+2                                        /* 6 */
                                                              /* 7 */
void main(void)                                               /* 8 */
{                                                             /* 9 */
   int det;                                                   /* 10 */
   while (1)                                                  /* 11 */
   {                                                          /* 12 */
      det = (inportb(STATUS)^0x80)>>6;                        /* 13 */
      switch (det)                                            /* 14 */
      {                                                       /* 15 */
         case 0:  break;  /* no action */                     /* 16 */
                                                              /* 17 */
         case 2:  outportb(DATA, 0x00);                       /* 18 */
                 /* turn off lamp */                          /* 19 */
                  break;                                      /* 20 */
         case 1:  outportb(DATA, 0x01);                       /* 21 */
                  /* turn lamp on */                          /* 22 */
                  break;                                      /* 23 */
         case 3:                                              /* 24 */
             printf("Be sure the circuit is connected.\n");   /* 25 */
             break;                                           /* 26 */
      }                                                       /* 27 */
   }                                                          /* 28 */
}                                                             /* 29 */