This years Vex competition uses blue and red donuts. Several of my students have been asking me for a simple color sensor. After trying several approaches (using an RGB LED in reverse and passive filters over light sensors) I arrived at the following simple design. This is an active sensor that uses a high intensity RGB LED to illuminate the object and then measures the reflected light with a CdS cell.
One of the advantages of the active sensor is that it can work in most lighting conditions. You can also tell when the sensor is running since the RGB led is flashing.
A CdS sensor changes its resistance proportional to the amount of light falling on it. When the cell is highly illuminated, the resistance is low. The CdS cell is connected as one leg of a voltage divider. When the resistance of the cell is high (say 100K) most of the current flows through the 5V leg and the voltage at pin7 is close to 5V. When the resistance of the cell is low, pin 7 is closer to ground and the pin is closer to 0V. In practice the setup pictures goes between about 0.3 and 4V.
When the sensor is in operation, one of the color channels (say Red and pin12) is pulled low for 50 ms. This causes the LED to light since the common anode of the RBG led is connected to 5V through a current limiting 220 ohm resistor. The voltage on pin 7 connected to the CdS cell is read using the ADC with the value inversely proportional to the strength of that color. (Low values mean strong color response.) This process is repeated for each of the three color channels and a comma delimited RGB triplet is output to the serial port. In addition, the values are compared and the lowest value sets the state of outputs 8 and 9 which are each connected to a LED. If red is lowest (strongest response) then the LED connected to 9 lights. If blue is lowest the the LED connected to 8 lights. If green is lowest then both LEDs light. If the total value from all the sensors is less then a threshold then none of the LEDs light since there is no object to reflect light.
In the images above you can see that the blue test object reflects blue much more strongly then it reflect red. In sensor terms, the Blue sensor might return 2V while the Red sensor returns 3.5 Volts and the green sensor returns 2.8V. These values of course change with ambient lighting, but the relationship between the values is relatively consistent.
Good luck with your color sensors!
The code for the sensor is shown below.
'color Sensor'LEDs RGB on channels 1 2 3. Pull low to turn on.'Read the CdS cell on channel 4'Set all outputs highhigh 0high 1high 2high 3low 4high 5pause 1000main:w3 =0 'This is accumulate the sum of all channels'Set the red channel low turns it on.low 1high 2high 3pause 50 'Give time for the LED to turn on.readadc 0,b0serout 0,T2400_4, (#b0)high 1 'Repeat for Green Channellow 2high 3pause 50readadc 0,b1b1 = b1 + 20serout 0,T2400_4, (",",#b1)high 1 'Repeat for Blue Channelhigh 2low 3pause 50readadc 0,b2serout 0,T2400_4, (",",#b2,13,10)w3 = b0 + b1 + b2if w3 > 450 then nocolor 'Cut on total intensityif w3 < 150 then nocolor 'Cut on total intensityif b0<b1 and b0<b2 then redif b1<b0 and b1<b2 then greenif b2<b0 and b2<b1 then bluegoto mainnocolor:'sertxd ("nocolor",13,10)high 4high 5goto mainred:low 4high 5goto mainblue:high 4low 5goto maingreen:low 4low 5goto main