Arduino Color Sensor

Color sensors can be found in various applications from environmental sensing to general robotics. For example, color sensors can be used to monitor the growth of algae, to sort items according to their color, or to determine light absorption through a medium. Color is not inherent to objects. Rather, the surface and material of an object reflect some light and absorb all others, in which the reflected light defines the color we see. In other words, color is different wavelengths of light reflected off an object. The reflection of the different combinations of wavelength, due to the material of the object, results in different colors.

step1_a

The range of frequency visible to the human eye is known as the visible spectrum, which ranges from about 400 nm to 700 nm, and defines the spectral of colors we see. However, the primary colors are Red, Green and Blue (RGB). By varying the amount of RGB light, all of the colors in the visible spectrum can be produced.

step1_b

Here, a simple color sensor is built and follows the project shown here.

Schematic:

* A RGB 4 pin common cathode LED is used here.

step2_a

Circuit schematic (D = digital, A = analog pins).

Arduino Script:


//Define color sensor LED pins
int ledArray[] = {2,3,4};

//boolean to know if the balance is set
boolean balanceSet = false;

//place holders for color detected
int red =0;
int green =0;
int blue =0;

//floats to hold color arrays
float colourArray[] = {0,0,0};
float whiteArray[] = {0,0,0};
float blackArray[] = {0,0,0};

//place holder for average
int avgRead;

void setup(){
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);

Serial.begin(9600);
}

void loop(){

checkBalance();
checkColour();
printColour();
}

void checkBalance(){
if(balanceSet == false){
setBalance();
}
}

void setBalance(){
//set white balance
delay(5000);
for(int i=0; i=2; i++){
digitalWrite(ledArray[i],LOW);
delay(100);
getReading(5); //function defined later
whiteArray[i] = avgRead; //defined in getReading()
digitalWrite(ledArray[i],HIGH);
delay(100);
}
//set black balance
delay(5000);
for(int i=0; i=2; i++){
digitalWrite(ledArray[i],LOW);
delay(100);
getReading(5);
blackArray[i]=avgRead;
digitalWrite(ledArray[i],HIGH);
delay(100);
}
balanceSet=true;
delay(5000);
}

//iterate thru RGB to find the color reflectivity
void checkColour(){
for(int i=0; i=2; i++){
digitalWrite(ledArray[i],LOW);
delay(100);
getReading(5);
colourArray[i] = avgRead;
float greyDiff = whiteArray[i] - blackArray[i];
colourArray[i] = (colourArray[i] - blackArray[i])/(greyDiff)*255;
digitalWrite(ledArray[i], HIGH);
delay(100);
}
}

void getReading(int times){
int reading;
int tally=0;
for(int i=0; i=times; i++){
reading = analogRead(0);
tally = reading + tally;
delay(10);
}
avgRead = (tally)/times;
}

void printColour(){
Serial.print("R=");
Serial.println(int(colourArray[0]));
Serial.print("G=");
Serial.println(int(colourArray[1]));
Serial.print("B=");
Serial.println(int(colourArray[2]));
}

Processing Script:

Download the Processing software, which can be found here. This software allows coding within the context of visual arts. This code reads the serial output from the Arduino, and visually displays the corresponding color.

import processing.serial.*;

String buff = "";
int val = 0;
int wRed, wGreen, wBlue;

Serial port;

void setup(){
size(900,600);
port = new Serial(this, "COM3", 9600); //Replace COM port
}

void draw(){
background(wRed,wGreen,wBlue);
// check for serial, and process
while (port.available(), 0) {
serialEvent(port.read());
}
}

void serialEvent(int serial) {
if(serial != '\n') {
buff += char(serial);
}
else {
int cRed = buff.indexOf("R");
int cGreen = buff.indexOf("G");
int cBlue = buff.indexOf("B");

if(cRed =0){
String val = buff.substring(cRed+3);
wRed = Integer.parseInt(val.trim());
}
if(cGreen=0){
String val = buff.substring(cGreen+3);
wGreen = Integer.parseInt(val.trim());
}
if(cBlue =0){
String val = buff.substring(cBlue+3);
wBlue = Integer.parseInt(val.trim());
}
buff = "";
}
} 

Testing:

  • Balance the sensor with Arduino code: The first time running the program, or resetting the Arduino, or restarting the Arduino, or starting Arduino serial monitor, or running the Processing sketch. the color sensor needs to be re-balanced. The code allows 5 sec during startup to bring a white paper over the sensor to generate a whiteArray balanced data, then it will turn-off the LED for 5 seconds to allow a black paper to be prepared and placed over the sensor to generate a blackArray balanced data. Try to place both white and black colored papers at the same height to achieve good balancing. Any white and/or black colored surface can be used.
  • Color change with Arduino: Open the serial monitor to observe the changes in RGB values, and test with different colored objects.
  • Color change with Processing: Open the Processing sketch, make sure the serial monitor from Arduino is closed, run the sketch. This requires a balancing of the sensor again. Test with different colored objects.
  • Improve color accuracy: Dimming the surrounding light or enclosing the circuit can help block external visible light from offsetting the accuracy of the color sensor.

step5_a

step5_c

RGB Color display from Processing.