Loading... Please wait...

Electronic Design Blog - BM017

Sensing Color With The Arduino and the TCS34725

Posted by


Sensing color with the Arduino and the TCS34725 is a pretty straight forward exercise. The TCS34725 is an IC manufactured by AMS (previously Taos). It packages color sensing analog-to-digital converters for clear, red, green, and blue color sensing into a tiny 6 pin package. The TCS34725 implements an I2C interface to configure settings and reading the color values.

In the photo above you can see a prototype of our BM017 color sensor module. We’ve included a white LED on the module that allows you to illuminate the object whose color you are sensing.

Here’s an image of the senor measuring a blue sheet of paper.



Our first application with this sensor simply configures the TCS34725 and reads each color value one time per second. Following that there’s a simple comparison of the red, green, and blue values to see which value is larger. The largest value is assumed to be the color present. Here are some points of interest from the work I did that might help you during implementation.

1. Red is the color most easily measured. Green and blue are closer in value and can be indistinguishable if the color sample is too far from the sensor.
2. Since the sensor may be close to the object it is sampling we added a white LED to our module to allow illumination of the sample.
3. The TCS34725 operates at 2.7V-3.6V. The Arduino at 5V. So our module also has a voltage level converter on the I2C pins allowing both devices to see the voltage they operate at.
4. The Arduino code uses the wire library with the SDA and SCL pins associated with A4 and A5 respectively.
5. The ATime setting in the TCS34725 determines the resolution of the color measurement. I have mine set for 16-bit values, and I think the integration (measurement) time is about 600mS.

This module will be available for resale in about 6 weeks. I’ll place the schematic on our web site at some point in the next few weeks. In the mean time here’s a screen capture.


The Arduino code will set the TCS34725 up for operation and check that it is connected to the I2C lines on power up. Then it will read the color registers and try to determine which color is dominant. If you enable the Serial Monitor it will display the color it sees as red, green, or blue. If you want to see the raw measurements you can comment in that portion of the code and it will send the data to the Serial Monitor.

Here is the code I used for simple color comparisons.

/*
BM017_Arduino_color_sensing:  This program interfaces to the AMS TCS34725 color light
to digital converter IC.  It uses the Arduino I2C interface.  

Schematics associated with the BM017 module may be used for hardware wiring information.
See the user datasheet at <a href="http://www.solutions-cubed.com">www.solutions-cubed.com</a> for additional information.

*/

#include <Wire.h>
#include <Math.h>

byte i2cWriteBuffer[10];
byte i2cReadBuffer[10];

#define SensorAddressWrite 0x29 //
#define SensorAddressRead 0x29 // 
#define EnableAddress 0xa0 // register address + command bits
#define ATimeAddress 0xa1 // register address + command bits
#define WTimeAddress 0xa3 // register address + command bits
#define ConfigAddress 0xad // register address + command bits
#define ControlAddress 0xaf // register address + command bits
#define IDAddress 0xb2 // register address + command bits
#define ColorAddress 0xb4 // register address + command bits

/*  
Send register address and the byte value you want to write the magnetometer and 
loads the destination register with the value you send
*/
void Writei2cRegisters(byte numberbytes, byte command)
{
    byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Send address with Write bit set
    Wire.write(command);                          // Send command, normally the register address 
    for (i=0;i<numberbytes;i++)                       // Send data 
      Wire.write(i2cWriteBuffer[i]);
    Wire.endTransmission();

    delayMicroseconds(100);      // allow some time for bus to settle      
}

/*  
Send register address to this function and it returns byte value
for the magnetometer register's contents 
*/
byte Readi2cRegisters(int numberbytes, byte command)
{
   byte i = 0;

    Wire.beginTransmission(SensorAddressWrite);   // Write address of read to sensor
    Wire.write(command);
    Wire.endTransmission();

    delayMicroseconds(100);      // allow some time for bus to settle      

    Wire.requestFrom(SensorAddressRead,numberbytes);   // read data
    for(i=0;i<numberbytes;i++)
      i2cReadBuffer[i] = Wire.read();
    Wire.endTransmission();   

    delayMicroseconds(100);      // allow some time for bus to settle      
}  

void init_TCS34725(void)
{
  i2cWriteBuffer[0] = 0x10;
  Writei2cRegisters(1,ATimeAddress);    // RGBC timing is 256 - contents x 2.4mS =  
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ConfigAddress);   // Can be used to change the wait time
  i2cWriteBuffer[0] = 0x00;
  Writei2cRegisters(1,ControlAddress);  // RGBC gain control
  i2cWriteBuffer[0] = 0x03;
  Writei2cRegisters(1,EnableAddress);    // enable ADs and oscillator for sensor  
}

void get_TCS34725ID(void)
{
  Readi2cRegisters(1,IDAddress);
  if (i2cReadBuffer[0] = 0x44)
    Serial.println("TCS34725 is present");    
  else
    Serial.println("TCS34725 not responding");    
}

/*
Reads the register values for clear, red, green, and blue.
*/
void get_Colors(void)
{
  unsigned int clear_color = 0;
  unsigned int red_color = 0;
  unsigned int green_color = 0;
  unsigned int blue_color = 0;

  Readi2cRegisters(8,ColorAddress);
  clear_color = (unsigned int)(i2cReadBuffer[1]<<8) + (unsigned int)i2cReadBuffer[0];
  red_color = (unsigned int)(i2cReadBuffer[3]<<8) + (unsigned int)i2cReadBuffer[2];
  green_color = (unsigned int)(i2cReadBuffer[5]<<8) + (unsigned int)i2cReadBuffer[4];
  blue_color = (unsigned int)(i2cReadBuffer[7]<<8) + (unsigned int)i2cReadBuffer[6];

  // send register values to the serial monitor 
/*
  Serial.print("clear color=");
  Serial.print(clear_color, DEC);    
  Serial.print(" red color=");
  Serial.print(red_color, DEC);    
  Serial.print(" green color=");
  Serial.print(green_color, DEC);    
  Serial.print(" blue color=");
  Serial.println(blue_color, DEC);
*/

 // Basic RGB color differentiation can be accomplished by comparing the values and the largest reading will be 
 // the prominent color

  if((red_color>blue_color) && (red_color>green_color))
    Serial.println("detecting red");
  else if((green_color>blue_color) && (green_color>red_color))
    Serial.println("detecting green");
  else if((blue_color>red_color) && (blue_color>green_color))
    Serial.println("detecting blue");
  else
    Serial.println("color not detectable");

}  

void setup() {
  Wire.begin();
  Serial.begin(9600);  // start serial for output
  init_TCS34725();
  get_TCS34725ID();     // get the device ID, this is just a test to see if we're connected
}

void loop() {
    get_Colors();
    delay(1000);
}

View Comments


Color Sensor to RGB LED Driver with an Arduino

I’m in the process of adding the BM017 Color Sensor to our web site. This breakout module is based on the TCS34725 by AMS (formerly Taos). You can use it to detect red, green, blue, and clear color values from object in front of the sensor. I covered basic use of the sensor [...]

Read More »





Recent Updates

Connect with us: Facebook Twitter