Color Match Lamp
A colour-copying mood lamp built on the TCS34725 RGB sensor: twice a second the sketch pulls raw red/green/blue/clear counts over I2C, normalizes them against the clear channel, classifies the dominant colour (RED, CYAN, MAGENTA...), computes colour temperature and lux with the real Adafruit formulas, and paints the whole 16-pixel NeoPixel ring in the matched colour while the OLED shows the name, RGB values, kelvin and lux. In the Lab, click the TCS34725 to reveal three R/G/B sliders and feed it any colour yourself - or leave it in auto mode and watch it sweep a full rainbow every 12 seconds. The button on GPIO 14 freezes (holds) the ring colour so you can capture a shade you like.
// Color Match Lamp - point the TCS34725 at any colour and the NeoPixel ring copies it.
// Click the TCS34725 on the bench and drag the R/G/B sliders while the sketch runs -
// the ring, OLED and serial monitor all follow. The button freezes (holds) the colour.
#include <Wire.h>
#include <Adafruit_TCS34725.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
#define RING_PIN 5
#define NUM_PIXELS 16
#define BTN_PIN 14
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
Adafruit_NeoPixel ring(NUM_PIXELS, RING_PIN, NEO_GRB + NEO_KHZ800);
bool hold = false;
int lastBtn = HIGH;
int heldR = 0;
int heldG = 0;
int heldB = 0;
void setup() {
Serial.begin(115200);
pinMode(BTN_PIN, INPUT_PULLUP);
if (!tcs.begin()) {
Serial.println("TCS34725 not found");
while (1) delay(10);
}
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
ring.begin();
ring.setBrightness(120);
ring.show();
Serial.println("Color Match Lamp ready");
}
void loop() {
int btn = digitalRead(BTN_PIN);
if (btn == LOW && lastBtn == HIGH) {
hold = !hold;
if (hold) {
Serial.println("HOLD");
} else {
Serial.println("LIVE");
}
}
lastBtn = btn;
uint16_t r;
uint16_t g;
uint16_t b;
uint16_t c;
tcs.getRawData(&r, &g, &b, &c);
if (c == 0) c = 1;
int r8 = (int)(255.0 * r / c);
int g8 = (int)(255.0 * g / c);
int b8 = (int)(255.0 * b / c);
if (r8 > 255) r8 = 255;
if (g8 > 255) g8 = 255;
if (b8 > 255) b8 = 255;
uint16_t kelvin = tcs.calculateColorTemperature(r, g, b);
uint16_t lux = tcs.calculateLux(r, g, b);
// classify the dominant colour (0 RED 1 GREEN 2 BLUE 3 YELLOW 4 CYAN 5 MAGENTA 6 WHITE 7 DARK)
int nameId = 7;
int hi = r8;
if (g8 > hi) hi = g8;
if (b8 > hi) hi = b8;
if (hi < 25) {
nameId = 7;
} else if (r8 > 60 && g8 > 60 && b8 > 60) {
nameId = 6;
} else if (hi == r8) {
if (g8 * 10 > r8 * 6) nameId = 3;
else if (b8 * 10 > r8 * 6) nameId = 5;
else nameId = 0;
} else if (hi == g8) {
if (b8 * 10 > g8 * 6) nameId = 4;
else if (r8 * 10 > g8 * 6) nameId = 3;
else nameId = 1;
} else {
if (r8 * 10 > b8 * 6) nameId = 5;
else if (g8 * 10 > b8 * 6) nameId = 4;
else nameId = 2;
}
if (!hold) {
heldR = r8;
heldG = g8;
heldB = b8;
}
ring.fill(ring.Color(heldR, heldG, heldB), 0, NUM_PIXELS);
ring.show();
Serial.print("R=");
Serial.print(r8);
Serial.print(" G=");
Serial.print(g8);
Serial.print(" B=");
Serial.print(b8);
Serial.print(" ");
if (nameId == 0) Serial.print("RED");
else if (nameId == 1) Serial.print("GREEN");
else if (nameId == 2) Serial.print("BLUE");
else if (nameId == 3) Serial.print("YELLOW");
else if (nameId == 4) Serial.print("CYAN");
else if (nameId == 5) Serial.print("MAGENTA");
else if (nameId == 6) Serial.print("WHITE");
else Serial.print("DARK");
Serial.print(" ");
Serial.print(kelvin);
Serial.print("K lux=");
Serial.println(lux);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("COLOR MATCH LAMP");
display.setTextSize(2);
display.setCursor(0, 14);
if (nameId == 0) display.print("RED");
else if (nameId == 1) display.print("GREEN");
else if (nameId == 2) display.print("BLUE");
else if (nameId == 3) display.print("YELLOW");
else if (nameId == 4) display.print("CYAN");
else if (nameId == 5) display.print("MAGENTA");
else if (nameId == 6) display.print("WHITE");
else display.print("DARK");
display.setTextSize(1);
display.setCursor(0, 36);
display.print("R ");
display.print(r8);
display.print(" G ");
display.print(g8);
display.print(" B ");
display.print(b8);
display.setCursor(0, 50);
display.print(kelvin);
display.print(" K ");
display.print(lux);
display.print(" lux");
if (hold) {
display.setCursor(104, 0);
display.print("HOLD");
}
display.display();
delay(500);
}
Built with FluxBench.AI — the AI workbench for embedded projects.