This project uses a TCS230 color sensor I ordered from Amazon. It uses both "passive" and "active" color recognition: Passive recognition goes straight to an RGB LED. Active recognition is processed by the Arduino to output a specific color.
According to a similar product's datasheet,
In the TCS3200, the light-to-frequency converter reads an 8 × 8 array of photodiodes. Sixteen photodiodes have blue filters, 16 photodiodes have green filters, 16 photodiodes have red filters, and 16 photodiodes are clear with no filters. The four types (colors) of photodiodes are interdigitated to minimize the effect of non-uniformity of incident irradiance. All photodiodes of the same color are connected in parallel. Pins S2 and S3 are used to select which group of photodiodes (red, green, blue, clear) are active.
Materials needed:
- Arduino board: https://amzn.to/2DLjxR2
- Breadboard: https://amzn.to/2RYqiSK
- Jumper wires: https://amzn.to/2Q7kiKc
- Male-female wires: https://amzn.to/2CSrhPx
- Color sensor: https://amzn.to/2SfaFXr
- RGB LED (common anode): https://amzn.to/2RaP7hE
As an Amazon Associate I earn from qualifying purchases.
Step 1: CircuitConstruct a circuit as shown above:
- Sensor S0 to D2
- Sensor S1 to D3
- Sensor S2 to D4
- Sensor S3 to D5
- Sensor out to D6
- Red LED to D7
- Green LED to D8
- Blue LED to D9
Upload the following code in the IDE:
//Arduino pins:
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6
#define redLED 7
#define greenLED 8
#define blueLED 9
//Output from the sensor:
int redFrequency = 0;
int greenFrequency = 0;
int blueFrequency = 0;
//Formatted color values:
int redColor = 0;
int greenColor = 0;
int blueColor = 0;
//Values used for calibration
int redMin;
int redMax;
int greenMin;
int greenMax;
int blueMin;
int blueMax;
int color = 0;
void setup() {
//Declarations:
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
pinMode(13, OUTPUT);
pinMode(sensorOut, INPUT);
// Set frequency scaling to 20%:
digitalWrite(S0, HIGH);
digitalWrite(S1, LOW);
Serial.begin(9600);//begin serial communication
calibrate();//calibrate sensor (look at serial monitor)
}
void loop() {
readColor();//read sensor
decideColor();//format color values
printColor();//print values
}
void decideColor() {//format color values
//Limit possible values:
redColor = constrain(redColor, 0, 255);
greenColor = constrain(greenColor, 0, 255);
blueColor = constrain(blueColor, 0, 255);
//find brightest color:
int maxVal = max(redColor, blueColor);
maxVal = max(maxVal, greenColor);
//map new values
redColor = map(redColor, 0, maxVal, 0, 255);
greenColor = map(greenColor, 0, maxVal, 0, 255);
blueColor = map(blueColor, 0, maxVal, 0, 255);
redColor = constrain(redColor, 0, 255);
greenColor = constrain(greenColor, 0, 255);
blueColor = constrain(blueColor, 0, 255);
//light led
analogWrite(redLED, redColor);
analogWrite(greenLED, greenColor);
analogWrite(blueLED, blueColor);
//decide which color is present (you may need to change some values here):
if (redColor > 250 && greenColor > 250 && blueColor > 250) {
color = 1;//white
}
else if (redColor < 25 && greenColor < 25 && blueColor < 25) {
color = 2;//black
}
else if (redColor > 200 && greenColor > 200 && blueColor < 100) {
color = 4;//yellow
}
else if (redColor > 200 && greenColor > 25 /*&& blueColor < 100*/) {
color = 3;//orange
}
else if (redColor > 200 && greenColor < 100 && blueColor > 200) {
color = 5;//purple
}
else if (redColor > 250 && greenColor < 200 && blueColor < 200) {
color = 6;//red
}
else if (redColor < 200 && greenColor > 250 && blueColor < 200) {
color = 7;//green
}
else if (redColor < 200 /*&& greenColor < 200*/ && blueColor > 250) {
color = 8;//blue
}
else {
color = 0;//unknown
}
}
void calibrate() {
Serial.println("Calibrating...");
Serial.println("White");//aim sensor at something white
//set calibration values:
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
redMin = pulseIn(sensorOut, LOW);
delay(100);
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
greenMin = pulseIn(sensorOut, LOW);
delay(100);
digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
blueMin = pulseIn(sensorOut, LOW);
delay(100);
Serial.println("next...");//aim sensor at something black
digitalWrite(13, LOW);
delay(2000);
Serial.println("Black");
//set calibration values:
digitalWrite(13, HIGH);
delay(2000);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
redMax = pulseIn(sensorOut, LOW);
delay(100);
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
greenMax = pulseIn(sensorOut, LOW);
delay(100);
digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
blueMax = pulseIn(sensorOut, LOW);
delay(100);
Serial.println("Done calibrating.");
digitalWrite(13, LOW);
}
void printColor() {//print data
Serial.print("R = ");
Serial.print(redColor);
Serial.print(" G = ");
Serial.print(greenColor);
Serial.print(" B = ");
Serial.print(blueColor);
Serial.print(" Color: ");
switch (color) {
case 1: Serial.println("WHITE"); break;
case 2: Serial.println("BLACK"); break;
case 3: Serial.println("ORANGE"); break;
case 4: Serial.println("YELLOW"); break;
case 5: Serial.println("PURPLE"); break;
case 6: Serial.println("RED"); break;
case 7: Serial.println("GREEN"); break;
case 8: Serial.println("BLUE"); break;
default: Serial.println("unknown"); break;
}
}
void readColor() {//get data from sensor
//red:
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
redFrequency = pulseIn(sensorOut, LOW);
redColor = map(redFrequency, redMin, redMax, 255, 0);
delay(100);
//green:
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
greenFrequency = pulseIn(sensorOut, LOW);
greenColor = map(greenFrequency, greenMin, greenMax, 255, 0);
delay(100);
//blue:
digitalWrite(S2, LOW);
digitalWrite(S3, HIGH);
blueFrequency = pulseIn(sensorOut, LOW);
blueColor = map(blueFrequency, blueMin, blueMax, 255, 0);
delay(100);
}
Step 3: Calibrationin the function void decideColor()
, you may need to edit the values in this section:
if (redColor > 250 && greenColor > 250 && blueColor > 250) {
color = 1;//white
}
else if (...) {
For example, you may need to change redColor > 250
to redColor > 230
and so on. However, this part of the code is only used for "active" color detection (as opposed to passive), so you may comment it out entirely if you want to.
Once you are ready to use the sensor, you need to go through the initial calibration:
- Connect your board and open the serial monitor
- Aim the sensor at something white about 1" away
- Wait for the serial monitor to say "next"
- Aim the sensor at something black at the same distance
- Wait for the serial monitor to say "done calibrating"
Now the sensor should be calibrated and you are ready to use it:
- Passive detection: Simply point it at something and the LED should change to match the detected color
- Active detection: open the serial monitor and watch for the sensor values to come in. To the right of these is a section that says
____ detected
. If these colors seem inaccurate, remember to adjust the values discussed step 3
Comments