Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

TCS34725 colour sensor with Arduino Uno — hex colour, CCT and lux

Wire a TCS34725 RGB sensor to an Arduino Uno R3 at 5 V, switch its white LED safely from D4, and print colour as hex plus colour temperature and lux.

Arduino C++Verified — core avr 1.8.8, Adafruit TCS34725 1.4.4, 3 Nov 2026Compile-only

Community draft — report a mistake

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 R3Only the pins used are shown · 5 V logicTCS34725 RGB colour sensor5VGNDD4SDA · 18SCL · 19LEDINT (not connected)SDASCL3V3 (not connected)GNDVIN
Every connection
Arduino Uno R3TCS34725 RGB colour sensorWireNotes
5VVINredInto the board’s 3.3 V regulator; the I2C lines are level-shifted on the module.
GNDGNDblack
SDASDAblueSame signal as A4.
SCLSCLyellowSame signal as A5.
D4LEDwhitePulled 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_4X a white object 5–10 mm from the sensor reads well under the LED; in bright daylight drop to GAIN_1X if 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-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// 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

Serial Monitor · 9600Output
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 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.

↑↓ to move · Enter to open