The TCS34725 measures red, green, blue and unfiltered light through an IR-blocking filter, with a white LED on the board to light what it looks at. It is the usual sensor for colour-sorting machines, fruit-ripeness checkers and colour-matching toys.
On the Uno the common module is easy: it has a regulator and level-shifted I2C, so it runs from 5V on SDA/SCL directly. One extra wire, LED to D4, lets the sketch switch the white light off when you don’t need it. The sketch prints the raw channels, a normalised hex colour, the colour temperature in kelvin and an approximate lux value.
Wiring
| Arduino Uno R3 | TCS34725 RGB colour sensor | Wire | Notes |
|---|---|---|---|
| 5V | VIN | red | Into the board’s 3.3 V regulator; the I2C lines are level-shifted on the module. |
| GND | GND | black | |
| SDA | SDA | blue | Same signal as A4. |
| SCL | SCL | yellow | Same signal as A5. |
| D4 | LED | white | Pulled LOW = white LED off; released = on. Never driven HIGH. |
3.3–5 V on VIN (on-board regulator) part, 5 V board. Modules with a VIN pin have a 3.3 V regulator and level shifting on SDA/SCL, so ESP32, Pico and Uno all work. The 3V3 pin is the regulator output — use VIN or 3V3, not both.
Board quirks
- Use VIN or 3V3, not both. On the Uno feed 5 V into VIN; the 3V3 pin is the regulator’s output and stays unconnected.
- The LED pin is pulled up on the module. The sketch only ever pulls it LOW (light off) or switches D4 to INPUT (light on), so the Uno never pushes 5 V into the module’s circuit.
- Each reading waits one integration time (154 ms here) — longer means more sensitive and slower. With
GAIN_4Xa white object 5–10 mm from the sensor reads well under the LED; in bright daylight drop toGAIN_1Xif the clear channel saturates near 65535. - The hex colour is each channel divided by the clear channel, so it shows hue rather than brightness. It won’t exactly match a screen colour — the sensor’s filters and the LED’s white aren’t sRGB — but it is consistent, which is what sorting and matching need.
- Cover the sensor and object with a small tube or box to block room light; a tube light’s flicker and changing daylight shift the readings.
Code
// TCS34725 RGB colour sensor on an Arduino Uno R3 — colour as hex, colour temperature and lux.
// VIN → 5V (board regulator + level shifting), GND → GND, SDA → SDA (A4), SCL → SCL (A5), LED → D4.
// D4 only ever pulls LED low (light off) or lets it go (light on) — it never drives 5 V into it.
#include <Wire.h>
#include <Adafruit_TCS34725.h>
const uint8_t LED_PIN = 4;
Adafruit_TCS34725 tcs(TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_4X);
void ledOn(bool on) {
if (on) pinMode(LED_PIN, INPUT); // released: the module's pull-up turns the white LED on
else {
digitalWrite(LED_PIN, LOW);
pinMode(LED_PIN, OUTPUT);
}
}
void setup() {
Serial.begin(9600);
if (!tcs.begin()) {
Serial.println(F("No TCS34725 at 0x29 - check SDA/SCL and VIN"));
while (true) delay(1000);
}
ledOn(true);
Serial.println(F("TCS34725 ready - hold an object 5-10 mm from the sensor"));
}
void loop() {
uint16_t r, g, b, c;
tcs.getRawData(&r, &g, &b, &c); // waits one integration time (154 ms)
if (c == 0) return;
// Normalise by the clear channel so brightness doesn't change the colour.
uint8_t rr = min(255UL, (uint32_t)r * 255 / c);
uint8_t gg = min(255UL, (uint32_t)g * 255 / c);
uint8_t bb = min(255UL, (uint32_t)b * 255 / c);
char hex[8];
snprintf(hex, sizeof hex, "#%02X%02X%02X", rr, gg, bb);
Serial.print(F("R "));
Serial.print(r);
Serial.print(F(" G "));
Serial.print(g);
Serial.print(F(" B "));
Serial.print(b);
Serial.print(F(" C "));
Serial.print(c);
Serial.print(F(" "));
Serial.print(hex);
Serial.print(F(" "));
Serial.print(tcs.calculateColorTemperature_dn40(r, g, b, c));
Serial.print(F(" K "));
Serial.print(tcs.calculateLux(r, g, b));
Serial.println(F(" lux"));
delay(500);
}// TCS34725 RGB colour sensor on an Arduino Uno R3 — colour as hex, colour temperature and lux.
// VIN → 5V (board regulator + level shifting), GND → GND, SDA → SDA (A4), SCL → SCL (A5), LED → D4.
// D4 only ever pulls LED low (light off) or lets it go (light on) — it never drives 5 V into it.
#include <Wire.h>
#include <Adafruit_TCS34725.h>
const uint8_t LED_PIN = 4;
Adafruit_TCS34725 tcs(TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_4X);
void ledOn(bool on) {
if (on) pinMode(LED_PIN, INPUT); // released: the module's pull-up turns the white LED on
else {
digitalWrite(LED_PIN, LOW);
pinMode(LED_PIN, OUTPUT);
}
}
void setup() {
Serial.begin(9600);
if (!tcs.begin()) {
Serial.println(F("No TCS34725 at 0x29 - check SDA/SCL and VIN"));
while (true) delay(1000);
}
ledOn(true);
Serial.println(F("TCS34725 ready - hold an object 5-10 mm from the sensor"));
}
void loop() {
uint16_t r, g, b, c;
tcs.getRawData(&r, &g, &b, &c); // waits one integration time (154 ms)
if (c == 0) return;
// Normalise by the clear channel so brightness doesn't change the colour.
uint8_t rr = min(255UL, (uint32_t)r * 255 / c);
uint8_t gg = min(255UL, (uint32_t)g * 255 / c);
uint8_t bb = min(255UL, (uint32_t)b * 255 / c);
char hex[8];
snprintf(hex, sizeof hex, "#%02X%02X%02X", rr, gg, bb);
Serial.print(F("R "));
Serial.print(r);
Serial.print(F(" G "));
Serial.print(g);
Serial.print(F(" B "));
Serial.print(b);
Serial.print(F(" C "));
Serial.print(c);
Serial.print(F(" "));
Serial.print(hex);
Serial.print(F(" "));
Serial.print(tcs.calculateColorTemperature_dn40(r, g, b, c));
Serial.print(F(" K "));
Serial.print(tcs.calculateLux(r, g, b));
Serial.println(F(" lux"));
delay(500);
}Library: Adafruit TCS34725 (Adafruit) — compiled with Adafruit TCS34725 1.4.4.
Expected serial output
TCS34725 ready - hold an object 5-10 mm from the sensor
R 1412 G 1022 B 688 C 3197 #70513A 3105 K 694 lux
R 3361 G 812 B 731 C 4710 #B62B27 2511 K 319 luxTCS34725 ready - hold an object 5-10 mm from the sensor R 1412 G 1022 B 688 C 3197 #70513A 3105 K 694 lux R 3361 G 812 B 731 C 4710 #B62B27 2511 K 319 lux
Common errors
“No TCS34725 at 0x29”
Check SDA/SCL, VIN and GND. A VL53L0X/VL53L1X on the same bus also uses 0x29 — they can’t share a bus without changing one address.
Values are all 0 or the LED never lights
D4 is holding LED low. Check the sketch calls ledOn(true), and that LED isn’t wired to GND.
C reads 65535 and colours look washed out
Saturated. Lower the gain or integration time, or move the object a little further away.