Step 4: Step 3: Write Code

Here is my Arduino code. You will need to calibrate the const values based on how much light is in the room - comment out the indicated portion of the loop() method and note the RGB values it displays for different colored cards. Store those RGB values in the ICOLOR const int[]'s at the beginning of the script. If you did a good job of light-proofing the box, the same RGB values should work with various levels of background light.

/**Runs a color sensor on the Arduino
* Start the program while showing it the white card. When the RGB LED turns off,
* switch (quickly) to the black card. After the RGB LED flashes white, it is ready.
//pin identifiers
int blue = A2;
int green = A1;
int red = A0;
int redOut = 9;
int greenOut = 10;
int blueOut = 11;
//counts the number of loops - used to time events
int count = 0;
//stores the current RGB input
int out[3];
//ICOLOR = RGB input from transistor that is that color.
//COLOR = RGB output to make RGB LED show that color
int IWHITE[3] = {175,48,455}; int WHITE[3] = {224,226,243};
int IBLACK[3] = {42,5,20}; int OFF[3] = {0,0,0};
int IRED[3] = {145,15,38}; int RED[3] = {200,0,0};
int IYELLOW[3] = {175,40,60}; int YELLOW[3] = {255,150,0};
int IMAGENTA[3] = {150,16,83}; int MAGENTA[3] = {200,0,200};
int IBLUE[3] = {57,7,160}; int BLUE[3] = {0,0,200};
int IGREEN[3] = {41,6,50}; int GREEN[3] = {0,200,0};
int NONE[3];
//[0] of these is the min, [1] is the max.
int redConvert[2];
int greenConvert[2];
int blueConvert[2];

//reads in the current color
int* readColor(){
  int ret[3];
  ret[0] = analogRead(red);
  ret[1] = analogRead(green);
  ret[2] = analogRead(blue);
  return ret;

//checks that each element in color1 is within dev of
//the corresponding element in refColor
boolean inRange(int color1[], int refColor[], int dev){
  return (abs(color1[0] - refColor[0]) <= dev) &&
  abs(color1[1] - refColor[1]) <= dev &&
  abs(color1[2] - refColor[2]) <= dev;

//sets the RGB LED color
void setColor(int color[]){
  analogWrite(redOut, color[0]);
  analogWrite(greenOut, color[1]);
  analogWrite(blueOut, color[2]);

//determines values for black and white
void calibrate(){
  int redSum = 0;
  int greenSum = 0;
  int blueSum = 0;
  for(int i = 1; i <= 5; i++){
    redSum += analogRead(red);
    greenSum += analogRead(green);
    blueSum += analogRead(blue);
  int whiteCal[3] = {redSum/5,greenSum/5,blueSum/5};
  redSum = blueSum = greenSum = 0;
  Serial.print("white Cal (RGB): ");
  Serial.print(" ");
  Serial.print(" ");
  Serial.println("insert black card");
    Serial.print("red green blue: ");
    Serial.print(" ");
    Serial.print(" ");
  Serial.println("new card detected - I hope it's black");
  for(int i = 1; i <= 5; i++){
    redSum += analogRead(red);
    greenSum += analogRead(green);
    blueSum += analogRead(blue);
  int blackCal[3] = {redSum/5,greenSum/5,blueSum/5};
  Serial.print("black Cal (RGB): ");
  Serial.print(" ");
  Serial.print(" ");
  //calculate conversion functions
  redConvert[0] = blackCal[0];
  redConvert[1] = whiteCal[0];
  greenConvert[0] = blackCal[1];
  greenConvert[1] = whiteCal[1];
  blueConvert[0] = blackCal[2];
  blueConvert[1] = whiteCal[2];

//runs calibration routine and turns the light white before
//starting loop
void setup(){

void loop(){
  //reads in new values
  out[0] = analogRead(red);//0-1024
  out[1] = analogRead(green);
  out[2] = analogRead(blue);

//update RGB LED and print output less frequently
  if(count % 5000 == 0){
    Serial.print("red green blue: ");
    Serial.print(" ");
    Serial.print(" ");

//comment out the rest of this loop to just display values and not use the RGB LED
    else if(inRange(out,IRED,10)){
    else if(inRange(out,IBLUE,10)){
    else if(inRange(out,IYELLOW,10)){
    else if(inRange(out,IMAGENTA,10)){
    else if(inRange(out,IGREEN,10)){
    else setColor(OFF);
<p>your circuit diagram is not at all clear , and also i m using 2n5777 phototransistors which are 3terminal transistors , i connected the base with ground as usual , i m facing a problem while calibrating the whole device , every time it shows either 655,655,655 or 0,0,0 .</p><p>and i tried altering the codes a bit but that didn't helped me either , so i am hoping that if you could help me resolve this problem .</p><p>can you please get in touch (anshmanu@icloud.com) , i want to discuss more things on Arduino .</p><p>the overall project was quite nice actually :) </p>
Love this project! Working on it right now. This is my very first Arduino project and I am a bit clueless to say the least. Do you have an image of the bottom of the board so I can see the connections more clearly? Thanks!
<p>while for different color values...we are getting almost same values on the serial monitor...what could be the problm apart from the insulation</p>
<p>Thanks for sharing !</p><p>I made an SMD version of this project.</p><p><a href="http://www.instructables.com/id/Your-Own-Color-Sensor-using-LEDs/" rel="nofollow">http://www.instructables.com/id/Your-Own-Color-Sen...</a></p>
I Have just one question. <br>Of what use is comparing colors to some one who is color blind like I am, <br>if you don't tell me what colors i am looking at ???
Hi anoniemouse,<br> <br> I had not considered that use case. If you add the following code to the setColor function, it should print the name of the color in addition to changing the color of the RGB LED. I haven't tested this code (I don't currently have access to the Arduino), but it compiles. Does this help? Thanks for your interest!<br> <br> if (color == WHITE) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;WHITE&quot;);<br> &nbsp; } else if (color == RED) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;RED&quot;);<br> &nbsp; } else if (color == YELLOW) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;YELLOW&quot;);<br> &nbsp; } else if (color == MAGENTA) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;MAGENTA&quot;);<br> &nbsp; } else if (color == BLUE) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;BLUE&quot;);<br> &nbsp; } else if (color == GREEN) {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;GREEN&quot;);<br> &nbsp; } else {<br> &nbsp;&nbsp;&nbsp; Serial.print(&quot;BLACK OR OFF OR UNREADABLE&quot;);<br> &nbsp; }
Could you upload your video again, please? <br> <br>When I turn on the program and show the white card, the RGB flashes a couple of colours but it does not turn off for me to switch to the black card. Any ideas? Also-to clarify, is the last section of the code required only if we want to adjust the RGB values? If we want to use the same values you wrote, then we should just keep that part of the code commented out, correct?
Hi arnabc, <br> <br>I re-uploaded the video. Did you get it working? Let me know if you have any more questions. Good luck!
Sorry about the video - I deleted my Google Plus account a few weeks after I uploaded that video, and I didn't realize that would also delete my Youtube videos. I don't have the video with me now, but I should be able to re-upload it later this week. <br> <br>This part is explained in the missing video. Sorry for the inconvenience.: <br>To do exactly what I did with the code as-is, you should have the white card showing when you start the program. The RGB LED should flash red, then green, then blue, then white for a longer time than the colors. After no more than about 2 seconds, the light should turn off. After it detects that the white card is no longer there, it should wait for 5 seconds (while you switch to the black card) and then do calculations based on the black card. After that finishes, the LED should turn white. When the LED turns white after being off, it is ready to read cards. <br> <br>Did you set OFF to {0,0,0}? Can you post any serial output from when you tried to run it? <br> <br>The last section of the code (from &quot;//comment out the rest of this loop to just display values and not use the RGB LED&quot; to the end of the if/else block) is the part that makes the RGB LED respond to the card changing. If you comment it out, it will dump RGB values to the serial output, and the LED will stay white. Is this the block of code you are referring to? None of it is commented out in the code I posted. <br> <br>To generate the numbers I used, I ran the program with that code commented out and looked at the serial output when I showed it different cards. I noted the RGB values and the variation for each color card, and hard coded the average RGB values as the values in the ICOLOR arrays. So, to calibrate it for your cards/your background lighting, you should do the same. If you want to use the same values I wrote, you should not comment anything out. Does that answer your question?

About This Instructable


78 favorites

More by ekc32011: Arduino Color Sensor
Add instructable to: