Introduction: TCS3472 RGB Light Color Sensor With Arduino
Use the TCS3472 light color sensor with your Arduino for color recognition projects
The TCS3472 is a color/light recognition IC that can be paired with an Arduino to recognize colors and also provide a measurement of light intensity. This has various applications e.g. sorting of different colored product, light color measurement, health or fitness products etc.
In this project, a TCS3472 is used to detect color swatches and light up a RGB LED with the same color.
Supplies
Here are the major components for this project
- Arduino Uno
- TCS3472 RGB Light Sensor
- Black Box
- Connectors and Resistors
Step 1: TCS3472 COLOR LIGHT-TO-DIGITAL CONVERTER
To quote the offical specification sheet from Texas Advanced Optoelectronic Solutions (TAOS):
“The TCS3472 device provides a digital return of red, green, blue (RGB), and clear light sensing values. An IR blocking filter, integrated on-chip and localized to the color sensing photodiodes, minimizes the IR spectral component of the incoming light and allows color measurements to be made accurately. The high sensitivity, wide dynamic range, and IR blocking filter make the TCS3472 an ideal color sensor solution for use under varying lighting conditions and through attenuating materials.”
Here is a link to a data sheet on the Adafruit website
https://cdn-shop.adafruit.com/datasheets/TCS34725.pdf
The block diagram from the datasheet included
The IR blocking filter gets rid of the infra red component of the incoming light to ensure that only the visible portion of the light gets measured. The measuring elements consist of four light sensitive photodiodes – red, blue, green and clear. Again, from the datasheet, the spectral response of the photodiodes is included
Visible light has a wavelength of between 380 nm and 700 nm
These photodiodes produce a signal proportional to the intensity of the specific wavelength of light impacting them, provided that this light is within their wavelength sensitivity range. For example, if incoming light is blue, the blue photodidode will produce a signal, whereas the red and green will not “see” this light and will produce no signal. White light (which contains all colors) will result in a signal from every photodiode. The clear diode reacts to all wavelengths across the visible spectrum.
The signals from the various diodes are then fed into a ADC and are added up cumulatively over a period of time (integrated is the term used in the datasheet). Once the time is complete, the result is made available in a register. This result is a 16 bit value representing a max raw reading between 0 and 65,535, depending on IC settings.
The TCS3472 uses an I2C interface to connect to an external microprocessor or controller. (Multiple articles exist that describe this interface) The default address of the TCS3472 is 0x29 and requires connection of two signals: SDA, SCL. In the Arduino UNO, these default to pins A4 (SDA) and A5 (SCL).
Once connected, a microcontroller can issue commands via I2C to the TCS3472 and read the results of the light sensing photodiodes.
The TCS3472 can generate an interrupt signal if light sensed by the module exceeds or drops below a programmed threshold value.
Attachments
Step 2: TCS 3472 Color Sensor
This project uses a module which incorporates the TCS3472 IC. It can be purcashed on multiple sites.
The specific capabilities of this module are summarized below:
- The module includes two onboard LED “lights” which are used to produce white light that can be reflected off samples to produce a reading which coincides with the color samples
- The pin out labeled “LED” can be pulled low and this deactivates the onboard LED’s (for applications where outside light needs to be sensed).
- This specific unit came with two different headers one of which has to be soldered onto the module
- The TCS3472 IC requires a3.3V power supply. This module includes a 3.3V regulator allowing Vin to be greater than 3.3V. SDA and SCL are similarly reduced to 3.3V. These voltage shifting capabilities allow the module to be directly connected to a Arduino 5V system.
- INT specifies the interrupt out pin
Step 3: Black Box
In this project the TCS3472 will be used to detect the color of a swatch and light up a LGB LED to the same color. The readings from the TCS3472 device must correspond to the swatch – this requires that extraneous light that could skew the readings must be excluded from the readings. To achieve, a black box is used. The steps used to construct a suitable black box as follows:
- Solder header to TCS3472
- Solder header to a suitable sized perfboard
- Attach wires to the perfboard and connect wire ends to the header. Use six different color wires
- Find a rigid backing plate. This project used a small piece of ¼ “ plywood
- The backing plate must be covered in black. A small piece of black foam covered this requirement
- Drill suitable holes through the backing plate, perfboard, and foam.
- Construct a five sided black box from black matte paper or board. Using bolts and nuts, assemble the final box. Ensure that the connection wires are routed out the side of the box.
- The main purpose of the box is to shield from outside light and absorb light emitted from the two LED’s on the TCS3472 board. As a result, only light reflected from a color swatch positioned over the open end of the box is measured by the TCS3472.
Clearly, there are other ways to make such a box. A small black jewelry box could be used.
Step 4: The Circuit
Schematic of the circuit included
The circuit is simple. Connect Vin and GND to Arduino UNO 5V and GND pins. A4 is connected to SDA and A5 to SCL. Then connect the the RGB LED to digital pins 9,10,11 of the Arduino UNO. This specific circuit uses a common cathode LED. Connections have to be reversed in the case of a common Anode LED.
The LED’s are connected in series with current limiting resistors. In the case of this project, the green LED was much brighter than the other two colors. To equal this out, the current limiting resistor is 1kOhm. This may not be the case for other LED’s – some experimentation required.
Step 5: Gamma Correction
The human eye has a non-linear response to color brightness. Lower intensity light is perceived to be brighter than actual, whereas brighter light is perceived to be not to be so bright. This adaptation allows us to see better in the dark and conversely, not to be overwhelmed by very bright sunlight.
Here is the Wikipedia article on the subject
https://en.wikipedia.org/wiki/Gamma_correction
Or another simpler article
https://www.cambridgeincolour.com/tutorials/gamma-correction.htm
The TCS3472 produces measurements that are linear functions of input light intensity. To verify this, conduct the following optional experiment:
Use the same circuit shown previously, position the RGB LED directly over the the TCS3472. This experiment must be conducted in a darkened room to prevent outside light from influencing the results
Input various values between 0 and 255 into the analogWrite(ledPin, brightValue); Arduino function. This will produce a light intensity proportional to the brightValue. Use only one color at a time.
The results plotted on a graph for each of the red, green and blue LED’s inside the RGB LED. The vertical axis is the raw reading obtained from the TCS3472 and the horizontal access is the value between 0 and 255 outputted to the LED.
To correct for this straight line response so that the eye perceives a linear ramp up of brightness, a gamma function is applied. In the case of this project, gamma function equation is used:
Values obtained from the TCS3472 for RGB intensity between 0 and 255 (straight line response) must be modified by this function (visual response) before been output to analogWrite(ledPin, brightValue);
So for example, a theoretical value of 150 must be output as 68, calculated as shown.
Armed with this equation, we can code up a compensated voltage output that gives a better LED brightness increase and decrease.
Step 6: TCS3472 Arduino Library
For this project, the Adafruit TCS34725 library is used. Ensure that the library is installed with the Arduino IDE been used. Full description of the library posted by Adafruit.
https://github.com/adafruit/Adafruit_TCS34725
The functions used in this project as follows:
Class constructor
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_600MS, TCS34725_GAIN_16X);
This constructor will initiate an object “tcs” with an integration time of 600 msecs and a gain of 16 times.
Integration time and gain can be understood in terms of an ideal Op Amp integrator circuit. Many explanations of this circuit are available – for example:
https://www.electronics-tutorials.ws/opamp/opamp_6.html
The larger the integration time and the higher the gain, the greater the sensitivity of the TCS3472. These values must be selected based on the specific application.
The library allows for the following integration times (all in milliseconds):
2.4, 24, 50, 60, 101, 120, 154, 180, 199, 240, 300, 360, 401, 420, 480, 499, 540, 600, 614
This value can be specified at the time of initiation or set via the function
tcs.setIntegrationTime(TCS_INTEGRATIONTIME_300MS)
The library also allows for four gain values:
1X, 4X, 16X, 60X
tcs.SetGain(TCS34725_GAIN_16X)
This project uses the following commands from the library:
tcs.begin();
Checks a TCS3472 IC is connected to SCL and SDA pins of the Arduino UNO and sets the required values in the TCS3472 registers.
tcs.getRawData(&r, &g, &b, &c);
Gets the 16 bit result of the integration cycle once a measurement cycle is initiated.
Step 7: Arduino Code
The main code that converts a swatch color to a LED RGB display is in the program “ColortoRGBLED.ino”
Some comments on the code:
- Include Adafruit_TCS34725 and Wire libraries (for I2C)
- By default SCL and SDA must be connected to pins A4 and A5 on the Arduino UNO. These pins may be different for other Arduino boards
- Calibration values must be entered before running the program. See the next section
- The sketch contains a map function which works in the same way as the Arduino map() function. It takes some inputs that lie in a certain range and converts them into a new range. This function was included because the native map() function uses long integer types; different variables types are required for this application. The mathematical formula is the same.
- The gamma correction is stored in a table which is computed in the setup loop. This makes the code execution faster during detection cycles in the main loop
- Black and White calibration values are stored in a C++ Struct variable
Attachments
Step 8: Calibration
The black box and TCS3472 need to be calibrated for their specific configuration. Here are the calibration steps
- Connect up the TCS3472 to the Arduino UNO according to the schematic
- Open the program “TestTCS3472.ino”. Upload the program “TestTCS3472.ino” to the Arduino
- Serial monitor set to 115200 baud
- Take a piece of black matte paper or swatch and cover up the open side of the black box
- Type any charater into the serial monitor and send to the Arduino. This will set off a read cycle
- The results will display in the Serial Monitor. Note down the r, g, b, c values (black values)
- Repeat above with a white matte paper or swatch. Note down the r, g, b, c values (white values)
- Open the program “ColortoRGBLED.ino” in the Arduino IDE
- Scroll down to lines 53 – 58. Edit the file to include your black and white values. redCal.blackvalue = r value recorded in step above with black swatch and so on.
- Program is now ready to run
Attachments
Step 9: Final Step
Upload the sketch “ColortoRGB.ino”, type in any value into the Serial Monitor and the RGB LED will light up to the color of the swatch detected by the TCS3472 at the open end of the black box.
Happy color detection!