$2 Color Detection Sensor

ColourSensor.pde (2851Bytes)

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.

SDC10939.jpg

Check that your LEDs work ;)

SDC10943.jpg

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.

ColorSensor.jpg



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(ambientambientAdj);
    
    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(redrAdj);
    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(yellowyAdj);
    digitalWrite(y, LOW);
    delay(colldownTime);
    
    double rawData[] = {(green
gAdj), (redrAdj), (bluebAdj), (yellowyAdj)};
    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®;
    }
    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. */

 

https://www.youtube.com/watch?v=8yPo3nV3duQ

Well done Gonzik !

Very nicely done project.  The running commentary  complements the project well.

Great work!

I like your project very much. I’ve tried to do something like this a big while ago but I wasn’t very successful…

But, can’t you make it a bit faster?

Nice !

Great idea :slight_smile:

Sure

Ya you can, faster video uploaded. You can’t make it faster than 1 second though b/c the ptotoresistor needs to cool down before and after a reading of .1 seconds (response time on them things is slow). For anything faster you will need somekind of electromagnetic frequency sensors to detect the color.

Thanks

Thanks first video upload to youtube and lmr :stuck_out_tongue:

How about Tri-color LED?

Do you think it’s possible to try one of those tri-color RGB LED and have multicolor looping in the code to get more precise scale of color tone?

Yes but not with my setup

I think it is possible but it’s hard to do it practically with a photoresistor. When I tested it objects reflect all colors even those that are not in their own spectrum. So a yellow object will reflect Red and Green as it should, but the Blue LED will also cause a change in the photoresistor. So when you mix those colors in proportion to how much of a change they caused in the photoresistor you won’t get yellow back. To try and filter out this “noise” is very hard and seems to be dependant on the surface of the object. The problem is that even in this simple setup the difference between how much of a change a red LED and a blue LED reflected off red was very miniscule. The arduino gives back a raw value between 0 and 1024 and the difference between colors was offten only maybe 15. I fear that with PWMing errors could accumulate to the point of making the sensor usless. But in theory it is possible !!!

         

Nice!

I was asking because I think it would be cool to use it in robots while moving to analyze the floor, but with that speed it would be a bit difficult. 

Thank you for answering and even showing that in a new video :smiley:

It is possible but you need

It is possible but you need a TSL230 or similar. Here is a guy that did just that: http://www.youtube.com/watch?v=SgAooELer_Y

Floor Finder ?

@ XicoMBD: I thought you already did this with a webcam and Processing?

That’s true! But I don’t

That’s true! 

But I don’t like to be always dependent on a computer :wink:

Yeah I thought of that too

Yeah I thought of that too but then you need to space them out so that they don’t affect each other and you might end up not sampling the same surface. I suppose its possible to have them angled differentley (One normal to surface and the other two 45 degrees off of that but I really think the light to frequency IC TSL230 is the best way to approach such a problem they are cheap from sparkfun). O and by the way Anton I’m a fan of your MTR and the servo encoders you made - hope to be at that level one day :wink:

Something like this maybe with a photoresistor next to each LED?


1 - Red LED, photoresistor for Green LED
2 - Blue LED, photoresistor for Blue LED
3 - Green LED, photoresistor for Red LED
1     2     3
--------------------
&nbsp;      l      /   
  &nbsp;    l     /
    \   l   /
  sample

You might also have a look

You might also have a look at this http://www.rev-ed.co.uk/docs/AXE045.pdf
I have done some work with the TCS230 sensor and it’s a pain to work with without a lens assembly.
https://www.robotshop.com/letsmakerobots/node/18124
The lens also have a IR filter.

Picaxe?

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

Can I do it with

Can I do it with phototransistor to get bigger speed?

Tri-Color LED Marble Sorter

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 !

final.jpg

 

Sorry for the late response.

Sorry for the late response. I have never worked with a Picaxe so you will have to write the code yourself. As for the schematic it would be the same. Both systems use 5V logic so just hook up the photo resistor to an analogue pin using a voltage divider and hook up the LED’s to digital pins.

You should be able to, just

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.

Glad to hear that Grog! Hope

Glad to hear that Grog! Hope she wins =)