The world is colorful – part 2 of 3

In this post we will work on a project to show how to sense the color of a light source.

A. About TCS3414 Color Sensor

Similar to how we view this colorful world with our eyes, the TCS3414 digital color light sensor developed by TAOS (Texas Advanced Optoelectronic Solutions, now a part of AMS) provides a way to separate the input light into Red, Green and Blue (as well as Clear) channel information.  This sensor can measure both the chromaticity (color) and illuminance (intensity) of ambient light and provide a digital output with 16-bits of resolution.  The four channels of digital data can be read with a microprocessor such as Arduino through I2C bus.  The beauty of this sensor is that all the analog signal detection and process are finished inside the sensor, and the output is purely digital so the signal/noise ratio is high.

 

B. Project description

In this project, we will use the TCS3414 sensor to detect the output of a first RGB tri-color LED, use an Arduino Nano board to obtain this information, distinguish the color of the detected signal, and then drive a second RGB tri-color LED accordingly, to reflect the color of the first LED.

 

C. Material

1. Arduino Nano board x 1
2. Breadboard x 1
3. TCS3414 evaluation board x 1
4. RGB LED x 2
5. 150 Ohm resistor x 4
6. 10k Ohm resistor x 2 (optional)
7. Jumper wires
8. USB cable (A plug to mini-B plug) x 1

 

D. Key notes

TCS3414 comes with a small package, roughly 3mm x 2mm size.  It’s hard to handle directly in a prototype project.  Luckily, there are some evaluation board developed for it, with the TCS3414 sensor soldered on the evaluation board and the evaluation board can be directly plugged into a breadboard.

The supply voltage of the TCS3414 sensor is between 2.7V and 3.6V, so we can use the 3.3V output of the Arduino Nano board to drive the sensor.

In order for the I2C bus of TCS3414 and Arduino Nano to work well, we can connect two pull up resistors (about 1k Ohm to 10k Ohm) between the 3.3V supply voltage and the SCL and SDA pins. But in this project, we didn’t use the two pull up resistors and the system still works fine.

 

E. Diagram

rgbTcsDiagram

 

F. Arduino sketch

/*
RGB LED Color Detection

This sketch demonstrates how to use a TCS3414 color sensor
to detect the color of the first RGB LED, and use the second
LED to reproduce the detected color.

Open Source Photonics
osphotonics@gmail.com

8/28/2014
*/

#include <Wire.h>

// define pins to drive the LEDs
int led1 = 6;   // for first LED
int led2r = 11; // for the second LED red diode
int led2g = 10; // for the second LED green diode
int led2b = 9;  // for the second LED blue diode

// define parameters for TCS3414
unsigned int TCS3414values[4];  // [Clear,Red,Green,Blue]
int integrationTime = 100;      // ms
int delay1 = 14;                // ms, for TCS3414 to initiate

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2r, OUTPUT);
  pinMode(led2g, OUTPUT);
  pinMode(led2b, OUTPUT);
  digitalWrite(led1,HIGH);    // get the first LED ready
  Wire.begin();               // join I2C bus
  TCS3414Start(delay1,integrationTime);  // get TCS3414 ready
}

void loop() {
  int i;
  unsigned int r,g,b;

  //enable TCS3414 integration
  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0x80);             // write to Control register
  Wire.write(0x03);             // Enable ADC_EN
  Wire.endTransmission();   

  // allow integration
  delay(integrationTime+50);  // wait slightly longer

  // get back crgb values
  TCS3414All(TCS3414values);         

  //disable TCS3414 integration
  Wire.beginTransmission(0x39); //slave address: 0011 1001
  Wire.write(0x80);             //write to Control register
  Wire.write(0x01);             //Disable ADC_EN
  Wire.endTransmission();   

  r = TCS3414values[1];
  g = TCS3414values[2];
  b = TCS3414values[3];  

  if (r > g*2 && r > b*2) {
    indicateColor(led2r);
  }
  else if (g > r*2 && g > b*2) {
    indicateColor(led2g);
  }
  else if (b > r*2 && b > g*2) {
    indicateColor(led2b);
  }
}

void TCS3414Start(int delay1,int integrationtime){
  // initialize
  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0x80); // write to Control register
  Wire.write(0x01); // Turn the device on (does not enable ADC yet)
  Wire.endTransmission();

  delay(delay1); // for TCS3414 to initialize    

  Wire.beginTransmission(0x39); //slave address: 0011 1001
  Wire.write(0x81);  // Write to Timing (integration) register
  Wire.write(0x01);  // set free running INTEG_MODE and integration time to 100ms
  Wire.endTransmission();  

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0x87);             // write to Gain register
  Wire.write(0x10);             // set gain to x4
  Wire.endTransmission();
}

// ============================================================
// Sensor read functions - retrieves the CRGB raw sensor values
// ============================================================

void TCS3414All(unsigned int allcolors[]){
  unsigned int white = TSC3414Clear();
  unsigned int red = TSC3414Red();
  unsigned int green = TSC3414Green();
  unsigned int blue = TSC3414Blue();

  allcolors[0] = white;
  allcolors[1] = red;
  allcolors[2] = green;
  allcolors[3] = blue;

  //returns all colors;
}

// Gets the clear sensor value and returns an unsigned int
unsigned int TSC3414Clear(){
  unsigned int clearLow = 0;
  unsigned int clearHigh = 0;

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0xB6);             // read Clear register
  Wire.endTransmission();

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.requestFrom(0x39,2); // Request information
  clearLow = Wire.read();
  clearHigh = Wire.read();
  Wire.endTransmission();   

  clearHigh = (clearHigh * 256) + clearLow;
  return clearHigh;
}

// Gets the red sensor value and returns an unsigned int
unsigned int TSC3414Red(){
  unsigned int redLow = 0;
  unsigned int redHigh = 0;

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0xB2);             // read Red register
  Wire.endTransmission();

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.requestFrom(0x39,2); // Request information
  redLow = Wire.read();
  redHigh = Wire.read();
  Wire.endTransmission();

  redHigh = (redHigh * 256) + redLow;
  return redHigh;
}

//Gets the green sensor value and returns an unsigned int
unsigned int TSC3414Green(){
  unsigned int greenLow = 0;
  unsigned int greenHigh = 0;

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0xB0);             // read Green register
  Wire.endTransmission();

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.requestFrom(0x39,2); // Request information
  greenLow = Wire.read();
  greenHigh = Wire.read();
  Wire.endTransmission();

  greenHigh = (greenHigh * 256) + greenLow;
  return greenHigh;
}

//Gets the blue sensor value and returns an unsigned int
unsigned int TSC3414Blue(){
  unsigned int blueLow = 0;
  unsigned int blueHigh = 0;

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.write(0xB4);             // read Blue register
  Wire.endTransmission();

  Wire.beginTransmission(0x39); // slave address: 0011 1001
  Wire.requestFrom(0x39,2); // Request information
  blueLow = Wire.read();
  blueHigh = Wire.read();
  Wire.endTransmission();  

  blueHigh = (blueHigh * 256) + blueLow;
  return blueHigh;
}

void indicateColor(int ledPin) {
  int i;

  for (i=0;i<256;i++) {
    analogWrite(ledPin,i);
    delay(1);
  }
  for (i=0;i<256;i++) {
    analogWrite(ledPin,255-i);
    delay(1);
  }
  for (i=0;i<256;i++) {
    analogWrite(ledPin,i);
    delay(1);
  }
  for (i=0;i<256;i++) {
    analogWrite(ledPin,255-i);
    delay(1);
  }

  analogWrite(ledPin,255);
  delay(150);
  analogWrite(ledPin,0);
  delay(150);
  analogWrite(ledPin,255);
  delay(150);
  analogWrite(ledPin,0);
  delay(150);
  analogWrite(ledPin,255);
  delay(150);
  analogWrite(ledPin,0);
  delay(150);
}

G. Result and discussion

After we connect the LEDs, the resistors and the TCS3414 sensor with the Arduino Nano board, we can get a breadboard system as shown below:

IMG_3411[1]

Then we can connect the Nano board with a PC through the USB cable, and load the Arduino sketch shown in section F into the Nano board.  The system will then start to work.  In order to let the TCS3414 sensor to sense the light from the first LED (the one close to it), we can put a piece of white paper on top of the LED to reflect its light back onto the TCS3414 sensor.  Once the sensor detects the color of the first LED, the second LED will start to flash with the same color of the first one.  The color of the first LED can be set by connecting pin 6 of the nano board to a selected pin of the first RGB LED through the jumper wire.

So that’s it.  When the first LED shines with a certain color (Red, Green or Blue), the second LED will flash with the same color.  Isn’t that simple to detect the color of an RGB LED?

All the materials needed for this project can be purchased from eBay.

In part 3 of “The world is colorful” series posts,  we will work on a project to measure the real color of a sample (like a piece of orange paper), and display the measured color with an RGB LED.  Stay tuned!

 

 

Thanks for reading.  Open Source Photonics Blogs are supported by 612 Photonics.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: