Let's Make Robots!

$2 Color Detection Sensor

Detects the color of an object
AttachmentSize
ColourSensor.pde2.78 KB

SENSOR

My original inspiration was "http://www.societyofrobots.com/sensors_color.shtml". I made this sensor one evening long ago and have been meaning to share it as a good project for beginners. Basically wire it up like in the schematic and make sure all the LEDs point in such a way that any reflecting light will hit the photo resistor (I didn't do this well enough and had to compensate in the code for it). Run the code and tweak the calibration numbers to get it to work right.

The sensor works decently well for how simple it is. It can work with a variety of materials (in the video I use cloth, plastic, paper ect.). However the range is limited about 1 inch and if the objected is too angled it may not work at all. For best results keep the sensor normal to your sample surface.

It works because an object will reflect the most color that is of the same color as an object. This is why that object appears that color to us. This means a red object will reflect more of the red light than of the green, blue or yellow LED and cause the greatest change in the photo resistor readings. We can use this to determine color.

Future improvements on the projects can include using PWM to determine the exact shade of an object. Also modulation may be possible but some other sensor other than a photo resistor must be used (photo resistors don't have the response time for it). Perhpas a TSL230 or similar.

Check that your LEDs work ;)

And here is what it looks like after battling polymorph for an hour.....

MATERIALS
1 - Photoresistor
4 - 560 ohm resistors
1 - 10k resistor
4 - LEDs (Red, Blue, Yellow, Green)

SCHEMATIC

Here is the schematic of the sensor I made.



CODE

The code bellow is the one that I was running when I made the video. It continually turns the LEDs on to sample an object and then flashes one LED once it has reached a decision. It also prints all the numbers to a serial monitor so that you can see what the sensor sees and adjust it (If your physical one is as faulty as mine was....). The .pde file is included bellow for all you Arduino lovers. Remember a small cool down time is required for the photo resistor between samples.

**Uploaded Code with the faster runtime now.

//Pins
int photoResistor = 0;

int b = 2;
int r = 3;
int g = 4;
int y = 5;

//Calibration
// AKA Terrible software solution to a hardware problem....
double bAdj = 1.0;
double rAdj = 1.02;
double gAdj = 1.0;
double yAdj = 1.17;
double ambientAdj = 1.0;

void setup()
{
  pinMode(g, OUTPUT);
  pinMode(y, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(r, OUTPUT);
  pinMode(photoResistor, OUTPUT);
  Serial.begin(9600);
}

void loop()
{  
    allOff();
    delay(100);
    asses(100,100);
}

void allOff()
{
    digitalWrite(g, LOW);
    digitalWrite(y, LOW);
    digitalWrite(r, LOW);
    digitalWrite(b, LOW);
}

void allOn()
{
    digitalWrite(g, HIGH);
    digitalWrite(y, HIGH);
    digitalWrite(r, HIGH);
    digitalWrite(b, HIGH);
}

void pulse(int colour)
{
   for(int i=0;i<3;i++)
   {
      digitalWrite(colour, HIGH);
      delay(100);
      digitalWrite(colour, LOW);
      delay(100);
   }
}
 

void asses(int colldownTime, int saturationTime)
{
 
    delay(500);
    double ambient = analogRead(photoResistor);
    Serial.print("Ambient: ");
    Serial.println(ambient*ambientAdj);
    
    digitalWrite(g, HIGH);
    delay(saturationTime);
    double green = analogRead(photoResistor);
    Serial.print("Green: ");
    Serial.println(green*gAdj);
    digitalWrite(g, LOW);
    delay(colldownTime);
    
    digitalWrite(r, HIGH);
    delay(saturationTime);
    double red = analogRead(photoResistor);
    Serial.print("Red: ");
    Serial.println(red*rAdj);
    digitalWrite(r, LOW);
    delay(colldownTime);
    
    digitalWrite(b, HIGH);
    delay(saturationTime);
    double blue = analogRead(photoResistor);
    Serial.print("Blue: ");
    Serial.println(blue*bAdj);
    digitalWrite(b, LOW);
    delay(colldownTime);
    
    digitalWrite(y, HIGH);
    delay(saturationTime);
    double yellow = analogRead(photoResistor);
    Serial.print("Yellow: ");
    Serial.println(yellow*yAdj);
    digitalWrite(y, LOW);
    delay(colldownTime);
    
    double rawData[] = {(green*gAdj), (red*rAdj), (blue*bAdj), (yellow*yAdj)};
    double maximum = ambient*ambientAdj;
    int decision;
    
    for (int i=0; i<4; i++)  
    {
       if (maximum<rawData[i])
      {
          maximum = rawData[i];
          decision = i+1;
      }
    }
         
    Serial.println("");
    
    if(decision == 0)
    {
       Serial.println("No object detected.");
       allOn();
       delay(1000);
       allOff();
    }
    else if(decision == 1)
    {
       Serial.println("I think its green.");
       pulse(g);
    }
    else if(decision == 2)
    {
       Serial.println("Looks red to me.");
       pulse(r);
    }
    else if(decision == 3)
    {
       Serial.println("Blue for sure!");
       pulse(b);
    }
    else if(decision == 4)
    {
       Serial.println("Booring old yellow.");
       pulse(y);
    }
    Serial.println("");

}


/* All my work is distributed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License or any subsiquent version of that license. Details here "http://creativecommons.org/licenses/by-nc-sa/3.0/". You don't need to give me any credit but any derivative works must remain free and open source to the community. All code, diagrams and details are provided on an "as is" basis with no expressed or implied waranties for suitability to any purpose - don't blame me if something breaks. */

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Why is that you have the photoresistor set as an output. Isn't it being used as an input, sensing the amount of light recieved?

Thanks

Thanks Gonzik! 

 I'm working on a basketball hoop that keeps track of score based on the color of the ball. Your simple concept is great! thanks for the help.

I could make code for picaxe

Then do it! I don't use Picaxe but someone else might find it very useful :)

I'll do it when i get mc's and cable

Hoi Gonzik !

You never know how things will connect !
My daughter got inspired to make a colored marble sorter for here elementary science fair.

I'll update with video and more info when I get it.

Thanks for sharing Gonzik !

 

Glad to hear that Grog! Hope she wins =)

Can I do it with phototransistor to get bigger speed?

You should be able to, just make sure that the saturation region of the photo transistor works with the wavelengths of the LED's you plan to use, and add a fudge factor to make your program equally sensitive to the different colors.

Hello Gonzik!

Great, great job on the color sensor. I was actually thinking about purchasing one on the web, and then I stumble across this post which saved me about $65.

Anyway, I was wondering if you could design a schematic and code for hooking it up to a Picaxe 28x1 instead of an Arduino. I understand if you do not have the time, but any help would be of extreme value to me.

Thanks in advance,

Student robot maker