TCS34725 color sensor

The TCS34725 color sensor on I2C at 0x29, with a white LED to light what it looks at. Aliases: Adafruit TCS34725, RGB color sensor, TCS3472.

It is the sensor in candy sorters, bead sorters and color-matching lamps. It has four photodiodes under red, green, blue and clear filters and counts the light on each, so a sketch can tell a red candy from an orange one by the share of each count.

Pins

Pin What it does
VIN Supply, 3.3 V or 5 V. The board regulates it down for the chip.
GND Ground.
SCL I2C clock. The board carries the pull-ups.
SDA I2C data.
INT The chip's interrupt, open drain, low when it fires. Leave it free if unused.
LED The white LED. The board pulls it high, so it is lit; pull it low to turn it off.

Properties

color is what is in front of the sensor, as #rrggbb. The row of cards on the part changes it while the circuit runs: red, orange, yellow, green, blue, purple, and none for an empty chute.

How it talks

Every access starts with a command byte with bit 7 set. Bits 6:5 are the type (00 for one register, 01 to step through them, 11 for a special function) and bits 4:0 the register. The TCS3472 datasheet's registers:

  • 0x00 ENABLE: power on (PON), the color cycles (AEN), the wait (WEN) and the interrupt (AIEN). Power on is sleep.
  • 0x01 ATIME: the integration, 256 minus a number of 2.4 ms cycles. 0xEB is 21 cycles, 50.4 ms.
  • 0x0F CONTROL: the gain, 1x, 4x, 16x or 60x.
  • 0x12 ID reads 0x44. 0x13 STATUS has AVALID, a finished integration, and AINT.
  • 0x14 to 0x1B: the clear, red, green and blue counts, two bytes each, low first.
  • 0x04 to 0x07 and 0x0C: the clear channel's interrupt thresholds and how many cycles out of range fire it. Command 0xE6 clears the interrupt.

After PON the oscillator takes 2.4 ms, and AEN then runs one integration after another. A count saturates at 1024 per cycle, or 65535.

The library

Adafruit_TCS34725.h works as its tutorial uses it:

#include <Wire.h>
#include "Adafruit_TCS34725.h"

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1);
  }
}

void loop() {
  uint16_t r, g, b, c;
  tcs.getRawData(&r, &g, &b, &c);
  uint16_t colorTemp = tcs.calculateColorTemperature_dn40(r, g, b, c);
  uint16_t lux = tcs.calculateLux(r, g, b);
  Serial.print("Color Temp: "); Serial.print(colorTemp); Serial.print(" K - ");
  Serial.print("Lux: "); Serial.print(lux); Serial.print(" - ");
  Serial.print("R: "); Serial.print(r); Serial.print(" G: "); Serial.print(g);
  Serial.print(" B: "); Serial.print(b); Serial.print(" C: "); Serial.println(c);
}

getRawData() waits one integration after each reading, as upstream's does. getRGB(), calculateColorTemperature(), setInterrupt(), clearInterrupt(), setIntLimits(), setGain() and setIntegrationTime() are there too. The color temperature and lux are integer sums here, within a few kelvin of the float answer.

What the model gets right

The command byte and its three types, sleep at power on, the 2.4 ms oscillator start, the integration time and gain, AVALID, saturation at 1024 counts a cycle, the clear channel interrupt with its thresholds and persistence, the special function that clears it, and the INT and LED pins, all from the TCS3472 datasheet.

What it does not model

How many counts a card gives is an assumption, since the datasheet gives the filters' curves and not a lit card at a few millimeters: a white card reads 30 counts a cycle at 1x on each color, each channel picks up a little of its neighbors, and with the LED off the card reads a tenth as much. Noise, infrared and the room's own light are not modeled.

Common mistakes

Reading before the first integration is done. Until AVALID is set the counts are zero.

Comparing raw counts between colors. A dark candy gives smaller counts than a light one of the same hue; compare each channel's share of the total instead.

See it in action

Color sorter reads each candy and swings a servo chute to its bin. Open it at /templates.