TCS3472 Colour sensor to Fastled

Hi all.
I have been playing with the I2C TCS3472 colour sensor tonight (connected to an UNO).

I was hoping to get the detector to match the detected colour to output on an RGB strip using Fastled.

I have the sensor in a small white enclosure for testing, with an RGB led inside the enclosure that reflects off the top of the box (not pointing directly at the TCS3472.
I have also disabled the onboard white led on the TCS3472, as I don't appear to need it.

I have had REAL trouble finding a library that actually compiles without errors. None of them appear to output what I need.

My hastily assembled to efforts are below, but they don't track the colour very well. Yellow is definitely a colour it has problems with. Individual colours (red, green and blue) are fine.

Anyone achieved this?

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

#define DATA_PIN    3                    // Data to the addressable WS2812 leds
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS    1
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          255
#define FRAMES_PER_SECOND  120

float red, green, blue;

// our RGB -> eye-recognized gamma color
byte gammatable[256];


Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  Serial.println("RGB Colour detection system");

  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }


  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);    // Setup the addressable leds
  delay(500);
  FastLED.setBrightness(255);
}

void loop() {

  tcs.getRGB(&red, &green, &blue);

  Serial.print("R:\t"); Serial.print(int(red));
  Serial.print("\tG:\t"); Serial.print(int(green));
  Serial.print("\tB:\t"); Serial.println(int(blue));
  Serial.println("");

  for ( int i = 0; i < NUM_LEDS; i++) {
    //leds[i].setRGB( gammatable[(int)red], gammatable[(int)green], gammatable[(int)blue]);
    leds[i].setRGB((int)red, (int)green, (int)blue);
    //leds[i].setRGB(0, 255, 0);
    FastLED.show();                                                                                   // send the 'leds' array out to the actual LED strip
  }

  delay(300);

}

Several attempts at the Fastled output there. What does the 'gammatable' bit do?

I also tried:

include "TCS34725.h"
#include <FastLED.h>

TCS34725 tcs;

#define DATA_PIN    3                    // Data to the addressable WS2812 leds
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS    1
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          255
#define FRAMES_PER_SECOND  120

void setup(void)
{
  Serial.begin(115200);

  Wire.begin();
  if (!tcs.attach(Wire))
    Serial.println("ERROR: TCS34725 NOT FOUND !!!");

  tcs.integrationTime(33); // ms
  tcs.gain(TCS34725::Gain::X01);

  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);    // Setup the addressable leds
  delay(500);
  FastLED.setBrightness(255);
}

void loop(void)
{
  if (tcs.available())
  {
    static uint32_t prev_ms = millis();

    TCS34725::Color color = tcs.color();
    Serial.print("Interval   : "); Serial.println(millis() - prev_ms);
    Serial.print("Color Temp : "); Serial.println(tcs.colorTemperature());
    Serial.print("Lux        : "); Serial.println(tcs.lux());
    Serial.print("R          : "); Serial.println(color.r);
    Serial.print("G          : "); Serial.println(color.g);
    Serial.print("B          : "); Serial.println(color.b);


    TCS34725::RawData raw = tcs.raw();
    Serial.print("Raw R      : "); Serial.println(raw.r);
    Serial.print("Raw G      : "); Serial.println(raw.g);
    Serial.print("Raw B      : "); Serial.println(raw.b);
    Serial.print("Raw C      : "); Serial.println(raw.c);

    prev_ms = millis();

    for ( int i = 0; i < NUM_LEDS; i++) {
      //leds[i].setRGB( gammatable[(int)red], gammatable[(int)green], gammatable[(int)blue]);
      //leds[i].setRGB((int)red, (int)green, (int)blue);
      leds[i].setRGB(color.r, color.g, color.b);
      FastLED.show();                                                                                   // send the 'leds' array out to the actual LED strip
    }
  }

  delay(300);
}

Just wondered if anyone has any suggestions or pointers to better code?

Nothing. If the array were initialized and used properly, it might solve your color conversion problem.

Did you notice the comment in the code, regarding gammatable?

I didn't understand the comment to be honest. I spent something like 2 hours trying to find a library that would compile at all!

Can't even remember which examples I lifted these from. I will have to go and look back through all the libraries I downloaded for the original.

I try to remember things from a university course regarding the way the human brain handles and decodes the signals from the different senses like eyes, ears, gravity, heat, pain.....
There was a part about coloured light. There's a mathematical description of light by wavelengths and then the "human way". Chromatic versus ???. Is the light source You use really good for the project, identifying colours when they are a mix mad by 3 mixed specific wavelengths?
Suppose You would use an all wavelength source illuminating a well defined coloured surface. What would the outcome be?

The gammatable is supposed to translate arbitrary R, G, B values into mixtures of colors that the eye recognizes.

"Yellow" is some combination of R and G, but whoever wrote that code didn't bother to put meaningful values into the array. The exact values, incidentally, depend on the particular RGB LED that you happen to have.

Blindly cutting and pasting code doesn't often get you very far, and some extracurricular reading should help a lot, e.g. Color vision - Wikipedia

Thanks. I will investigate further

One day my 'oh that should not be too difficult' project will actually be that

So I have had a play, including using the gammatable values, but it stil ldoesn't represent the colours correctly.
Basic reds, blue and green seem fine, but any mix just fails.

Not sure what you would set the brightness of the strip to? I theory I suppose it doesn't matter?

Any ideas what I can try to dial this in?
My only other thought was to literally note the individual values of each colour I want to reproduce and then hash the outputted values to vaguely match.... seems a bit bodge however.

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

#define DATA_PIN    3                                       // Data to the addressable WS2812 leds
#define LED_TYPE    WS2812
#define COLOR_ORDER RGB
#define NUM_LEDS    30
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          255
#define FRAMES_PER_SECOND  120

float red, green, blue;
byte gammatable[256];                                                                                  // our RGB -> eye-recognized gamma color
#define commonAnode false


Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  Serial.println("RGB Colour detection system");

  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }


  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);    // Setup the addressable leds
  delay(500);
  FastLED.setBrightness(255);

  for (int i = 0; i < 256; i++) {                                                                     // Convert RGB colors to what humans see
    //Serial.println(gammatable[i]);
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;

    if (commonAnode) {
      gammatable[i] = 255 - x;
    } else {
      gammatable[i] = x;
    }
    
  }

  Serial.println("SENSOR ONLINE");
}

void loop() {

  tcs.getRGB(&red, &green, &blue);

  Serial.print("R:\t"); Serial.print(int(red));
  Serial.print("\tG:\t"); Serial.print(int(green));
  Serial.print("\tB:\t"); Serial.println(int(blue));
  Serial.println("");

  for ( int i = 0; i < NUM_LEDS; i++) {
    leds[i].setRGB( gammatable[(int)red], gammatable[(int)green], gammatable[(int)blue]);
    //leds[i].setRGB((int)red, (int)green, (int)blue);
    //leds[i].setRGB(0, 255, 0);
    FastLED.show();                                                                                   // send the 'leds' array out to the actual LED strip
  }

  delay(10);
}

The color correction is specific to your RGB LED. That gamma table initialization does not do what you want.

So how do you find the gamma table for your RGB led? No idea where I got these RGB led strips from.

This code I found online works better.... but still no correct yellow (which according to the Adafruit forum , is a known issue with this sensor)

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

#define DATA_PIN    3                                       // Data to the addressable WS2812 leds
#define LED_TYPE    WS2812
#define COLOR_ORDER RGB
#define NUM_LEDS    30
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          255
#define FRAMES_PER_SECOND  120

byte gammatable[256];                                                                                  // our RGB -> eye-recognized gamma color
#define commonAnode false


Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  Serial.println("RGB Colour detection system");

  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }


  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);    // Setup the addressable leds
  delay(500);
  FastLED.setBrightness(255);

  for (int i = 0; i < 256; i++) {                                                                     // Convert RGB colors to what humans see
    //Serial.println(gammatable[i]);
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;

    if (commonAnode) {
      gammatable[i] = 255 - x;
    } else {
      gammatable[i] = x;
    }

  }

  Serial.println("SENSOR ONLINE");
}

void loop() {

  uint16_t clear, red, green, blue;
  delay(60);  // takes 50ms to read 
  tcs.getRawData(&red, &green, &blue, &clear);
  //tcs.getRGB(&red, &green, &blue);

   Serial.print("C:\t"); Serial.print(clear);
  Serial.print("\tR:\t"); Serial.print(red);
  Serial.print("\tG:\t"); Serial.print(green);
  Serial.print("\tB:\t"); Serial.print(blue);

    // Figure out some basic hex code for visualization
  uint32_t sum = clear;
  float r, g, b;
  r = red; r /= sum;
  g = green; g /= sum;
  b = blue; b /= sum;
  r *= 256; g *= 256; b *= 256;
  //Serial.print("\t");
  //Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.print((int)b, HEX);
  //Serial.println();

  Serial.print("\tR:\t"); Serial.print(gammatable[(int)r]);
  Serial.print("\tG:\t"); Serial.print(gammatable[(int)g]);
  Serial.print("\tB:\t"); Serial.print(gammatable[(int)b]);

  Serial.println();

  for ( int i = 0; i < NUM_LEDS; i++) {
    leds[i].setRGB( gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]);
    //leds[i].setRGB((int)red, (int)green, (int)blue);
    //leds[i].setRGB(0, 255, 0);
    FastLED.show();                                                                                   // send the 'leds' array out to the actual LED strip
  }

  delay(10);
}

Make your own color correction table. If "yellow" doesn't look yellow to you, adjust the RGB values until it does look yellow.

I think I will make a sensor enclosure anyway, and pipe the RGB led I am trying to copy into the top.
I will then make a routine to store values when I press a button.

I can then cycle through the colours (of the RGB I am trying to copy) and store the values.
Maybe I can work out some kind of array of colour values.

For the record, I am trying to add extra RGB leds to the interior of my car, but you cannot break into the RGB leds that are already built into the doors (not easily anyway).
Luckily, there is also a single, diffused RGB led in the centre console which I was planning to use as my colour reference.

See how it goes...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.