Photoresistor color sensing with the Arduino

Photoresistor color sensing with the Arduino

This project involves using an RGB LED in combination with a photoresistor to determine the color of an object. An actual color sensor goes for about $90, but you can make this one for pennies if you have an Arduino.

How this works is the RGB LED lights each color in rapid succession while recording the value of the photoresistor for each color. A color, say for instance red, will reflect a red light better than it will reflect any other color.

The photoresistor, after an amount of time, will change its resistance based on the amount of light it receives. We then use this inside of a voltage divider by putting another resistor to ground and connecting the junction of the photoresistor and 10k resistor. This way, any changes in light amplitude will result in voltage changes at this junction.

Connecting this to one of Arduino’s analog pins will allow us to sample this voltage and record it. The schematic for the sensor is shown below. It is all wrapped in heat shrink tubing for aesthetics.


It doesn’t work as well as a color sensor would, but the results are surprising. I’ve included the Arduino code if you want to play with it, steal it, whatever.

// Color Match
// January 28, 2012
// by George Gardner

int pwmrgb[] = {11, 9, 10}; //sets the r,g,b cathode pins for the pwm led (must be pwm pins)
int rgbbias[] = {100, 15, 0}; //sets the bias for the illuminated RGB LED: higher number = less intense (max 255)

int rgbds[] = {255, 255, 255};
int maxwhite[] = {773, 624, 542};
int minblack[] = {309, 134, 104};

int sensorValue = 0;

int speed = 5;

void setup(){
pinMode(2, OUTPUT); //sensor red cathode
pinMode(3, OUTPUT); //sensor green cathode
pinMode(4, OUTPUT); //sensor blue cathode
for(int i = 2; i < 5; i++){ digitalWrite(i, HIGH); analogWrite(pwmrgb[i-2], rgbds[i-2]); } } void loop(){ int switchstate = analogRead(A5); if(switchstate > 1000){
for(int i = 2; i < 5; i++){
digitalWrite(i, HIGH);
analogWrite(pwmrgb[i-2], 255);
switchstate = analogRead(A5);
while(switchstate < 1000){
switchstate = analogRead(A5);

for(int i = 0; i < 3; i++){
digitalWrite(i + 2, LOW);
sensorValue = analogRead(A0);
rgbds[i] = constrain(sensorValue, minblack[i], maxwhite[i]);
rgbds[i] = map(rgbds[i], minblack[i], maxwhite[i], 0, 255);
rgbds[i] = (255 + rgbbias[i]) – rgbds[i];
rgbds[i] = constrain(rgbds[i], 0, 255);
digitalWrite(i + 2, HIGH);

for(int i = 0; i < 3; i++){
analogWrite(pwmrgb[i], rgbds[i]);

void printresults(int i){
if(i == 0) Serial.print(“RED: “);
if(i == 1) Serial.print(“GREEN: “);
if(i == 2) Serial.print(“BLUE: “);

The maxwhite and minblack arrays are used to calibrate the sensor. Normally, you would set the sensor next to a black object, and record the values received from the photoresistor in the minblack array in the order R,G,B, respectively. Then put a white object on the sensor and record the maxwhite sensor reading in the same order.

I had better results with a photo card with CMY. We know by looking at a color wheel that cyan contains no red. So pointing the sensor to the cyan and reading the value on the serial monitor allowed me to set the first array on the minblack. Again, you could just use a white and black object, but I achieved much better results doing it this way.

For the maxwhite array, I would aim the sensor at magenta, get the reading for red, then aim it at yellow and record the reading for the red. I would then take the 2 values and average them to get the red value for maxwhite. Again, it’s all just to calibrate the device for better results.

The code contains the ability to light up an RGB led of the same color using Arduino’s PWM feature. The RBG LEDs I used were all common anode.

I’ve included a video to show the results.