RGB values received from TCS34725

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
Kadir
 
Posts: 9
Joined: Tue Apr 05, 2016 6:15 pm

Re: RGB values received from TCS34725

Post by Kadir »

I have a solution

The real colour is depend on clear value, I mean you can get correct (and more stable) colour value with the following calculation

tcs.getRawData(&r, &g, &b, &c);

multiplier = 255;

red = (r / c) * multiplier;
green = (g / c) * multiplier;
blue = (b / c) * multiplier;

I have implemented the formula below to get better solution

final_red = red / (red+green+blue)
final_green = green / (red+green+blue);
final_blue = blue / (red+green+blue)

Important note : Since the clear value is always bigger than raw colour, you may need to multiply by some value. In my case I multiplied every colour to 255 to get non zero value.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

Maybe useful for others using this sensor to sort and/or recognise also pastel and muddy colours:

1. Use a 5 - 15 mm high ultra-matt black shroud to eliminate all ingress of ambient light; a black v.e.l.v.e.t inner coating works wonders

2. Cut the shroud's top at an angle of 30° - 45° to eliminate specular LED reflections off of your sample to be measured

3. Hold the sample tight over the shroud or press the shroud down on the sample

4. Use an EMA to average as many readings as your time budget per measurement allows

5. Build an array with RGB triples {###, ###, ###} from all your colour samples ("train" or calibrate your code)

Then, you can enjoy reliable colour recognition over a far wider range of colours than most YouTube videos or Instructable tutorials suggest; this sensor is amazing value for money.

ps: Shiny or polished surfaces are difficult, even when angled 45° to avoid specular reflections from the LED back onto the sensor.

pps: Why is "v.e.l.v.e.t" a banned spam word?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: RGB values received from TCS34725

Post by adafruit_support_mike »

Systembolaget wrote:pps: Why is "v.e.l.v.e.t" a banned spam word?
Our spam filter keeps a running collection of words that have a high correlation to spam and a low correlation to normal posts. The specific words depend on who's trying to spam us at the moment.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

That's funny... so that type of fabric is a favourite spam word right now... who would have thought!

-

By the way, when taking measurements with the TCS34725 for 10 minutes, the raw red, green, blue and clear values drift upwards quite a lot, even when the sensor and sample are in a tight ultra-matt black box and controlled temperature; for example clear goes from 12037 after 30 seconds to 14921 after 10 minutes.

This can be troublesome when one leaves the system on and takes colour readings only every minute.

Could it be that the COB LED heats up, thus the current rises, and thus its brightness? The thermal runway effect of non-heat-sinked LEDs?

If so, how could that be controlled? Or is something else the reason for the value drift?

Just found the image below from a popular instructable, where, without being discussed, one can see the values drifting upwards. They have the sensor in a black enclosure.
FPCJI35I11YTW8T.jpg
FPCJI35I11YTW8T.jpg (84.4 KiB) Viewed 760 times

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB values received from TCS34725

Post by adafruit_support_bill »

As you suggest, it is likely due to heating of the LED. There will be some change in sensor responsivity with temperature also, but mostly in the near IR range.

A simple solution would be to turn off the LED between samples to allow it to cool.
Another approach is to calibrate against standard targets before each sample.
The ideal approach would be to use an external light source with a heat-sink and temperature sensors - plus periodic calibration to detect and correct for drift. On one medical instrumentation-grade spectrophotometer, we allowed the emitter temperature to stabilize for 15 minutes before initial calibration - and performed periodic full calibrations in addition to 1-point calibrations before each sample.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

Ok, thanks for your input... the LED, as I expected. See this half-hour test I ran over lunchtime; looks like the values would want to go higher still, if I would leave everything on for half a day or so.
Skärmbild.png
Skärmbild.png (298.7 KiB) Viewed 753 times
With a shroud and controlled ambient temperature, I was happy to see results with 12 colours after just a minute, comparing the numbers read to the ones stored; it looked like even more successful than the 5-colour-candy colour sorters one finds on the WWW. I am testing flat matt powder-coated sheet metal samples, some pastel, some murky, some bright. I thought I was done.

But then, doing the same exercise 20 minutes or over an hour later, none of my samples was matched within +/- 5 units, because of the value drift, strongest with the blue value.

I really want to use the sensor with LED as it is. I don't need medical grade accuracy. So now my idea is to sample each sheet metal sample for 30 minutes, find the average for red, green and blue, and then use the red, green and blue percentage/ratio from that average for comparison. If I don't leave the setup powered for over half an hour, I assume I can get a good match?

That brings me to a question.

As a not-quite beginner anymore, I know I can store each sample's red, green and blue ratio-triple {0.48, 0.35, 0.17} in an array. Is there a more clever way to measure a sample and then have the serial monitor output "1021" (RAL colour number) instead of coding a long tail of manually fine-tuned if/else statements? Meaning how can I search with the sensor's output (converted to ratios) in the array? Or is a long tail of if/else statements like

Code: Select all

 if ((r > 1.4) && (g < 0.9) && (b < 0.9)) {
 // Do some stuff
 }
the best way?

Maybe also the RAL number can be added to each sample's array entry to become a quadruple {0.48, 0.35, 0.17, 1021}?

Thanks in advance!

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB values received from TCS34725

Post by adafruit_support_bill »

I'm not familiar with the RAL system. It seems to be closer to the HSV model than to RGB. There are algorithms for converting RGB to HSV: https://gist.github.com/fairlight1337/4 ... bcc1ba5c72

I see that there are plenty of RGB->RAL on-line converters. I suspect that somewhere there is a published algorithm for performing that conversion also.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

Luckily, I don't actually need to convert anything. The matching RAL number can be stored in the array, together with each sample's RGB ratio. The question is "only" how without an endless tail of if/else statements, I can do the following; it's really just one of those "colour sorters", but more accurate and with far more colours in the end. With the question from before, this is what I want to achieve:

A. Power up and wait an hour (LED settles, still open question)
B. Scan all colour samples -> obtain r, g, b, w (modified Adafruit tcs34725 sketch), i.e. {2774, 3288, 4329, 10595}
C. Values go into Excel (via CoolTerm) -> I get all r, g, b sums, i.e. {10391} -> I get all r, g, b ratios, i.e. {0.27, 0.32, 0.42}
D. Put all r, g, b ratio triples in an array
E. Put corresponding RAL number "1234" (int/float) into another array, or add to corresponding ratio triple
F. Put corresponding linear actuator distance "567" (int/float) into yet another array, or add to corresponding ratio quadruple
G. Result: one array with a quintuple {0.27, 0.32, 0.42, 1234, 567} for each colour

1. Power up and wait an hour (LED settles, still open question)
2. Put a sample on the sensor shroud -> obtain r, g, b, w (don't really need w for colour sorting application)
3. Compare value triple (or quadruple) with those in array -> The colour gets identified
4. Output "1234" on a large OLED display and move linear actuator
5. Go to 2. after 1-5 minutes and read another sample...

My main problem, as a sort of beginner, is "only" at 3. (coding issue) and at A./1. (physical issue) which is where I wonder how those simple colour sorter or even simpler colour servo indicator projects work, where users also must have LED thermal runway and uptime value drift issues, but those are never mentioned in any project I reviewed on the WWW.

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB values received from TCS34725

Post by adafruit_support_bill »

There is no need for endless if/else statements. If you build such an array, you can iterate though it in a loop to do the comparisions. Your comparison routine will probably need a 'tolerance factor', since the a 100% match is not likely.

Since RAL seems to bin colors primarily by hue, you might consider converting the RGB to HSV first to narrow your search.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

If you build such an array, you can iterate though it in a loop to do the comparisions. Your comparison routine will probably need a 'tolerance factor', since the a 100% match is not likely.
Thanks, but that is exactly the question, how I could loop through an array of triples or, rather, quintuples - and how to bring sufficient tolerance into play.

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB values received from TCS34725

Post by adafruit_support_bill »

Assuming you have a table of RGB tuples, you could start by looping down through the 'R" column until you find the first value that matches within the tolerance band.
If the G and B columns are also within the tolerance band, you have a match. If not, you move on to the next row with a matching R value.

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

Alright, looping through the "r", then "g", then "b"... sort of a cascade by the sound of it.

Do you happen to know some online resource where one can learn about such more complex constructions? My C book for Arduino is not going too deep into things like finding matching data in arrays.

Or maybe these constructions have a name in the professional community, something I could then search for.

User avatar
adafruit_support_bill
 
Posts: 88096
Joined: Sat Feb 07, 2009 10:11 am

Re: RGB values received from TCS34725

Post by adafruit_support_bill »

Assuming you have defined a structure called rgbSample and have defined a table full of them:

Code: Select all

int SearchTable(rgbSample sample)
{
	for (int i = 0; i < tableSize; i++)
	{
		if (abs(table[i].r - sample.r) <= tolerance)
		{
			if (abs(table[i].g - sample.g) <= tolerance)
			{
				if (abs(table[i].b - sample.b) <= tolerance)
				{
					return i;  // this is a match
				}
			}
		}
	}
	return -1; // failed to find a match
}

User avatar
Systembolaget
 
Posts: 336
Joined: Wed Mar 08, 2017 1:01 pm

Re: RGB values received from TCS34725

Post by Systembolaget »

Thanks, that's quite some cascade to get me started ; ) I'm reading array book chapters to understand your suggestion; I don't want to just copy and paste code without really understanding what is what.

This is the array with 12 colours to begin with:

Code: Select all

const float SAMPLES[][5] = { // See initial colour training approach
{0.47, 0.35, 0.18,  10},
{0.62, 0.24, 0.14,  20},
{0.64, 0.18, 0.18,  30},
{0.60, 0.17, 0.22,  40},
{0.42, 0.26, 0.32,  50},
{0.27, 0.32, 0.42,  60},
{0.29, 0.33, 0.38,  70},
{0.18, 0.37, 0.45,  80},
{0.26, 0.45, 0.30,  90},
{0.35, 0.43, 0.23, 100},
{0.42, 0.40, 0.18, 110},
{0.48, 0.35, 0.17, 120},
};
Where the values are:

Code: Select all

{red, green, blue, ralNumber, actuatorMovement}
Later, I will add more.

If I pre-sort (hard-code) the array for r in Excel, there are five "close calls" to cater to:

1 and 12 differ sufficiently (> 0.02) first in w
2 and 4 differ sufficiently (> 0.02) already in g
5 and 11 differ sufficiently (> 0.02) already in g
6 and 9 differ sufficiently (> 0.02) already in g
6 and 7 differ sufficiently (> 0.02) first in w

It looks that testing for b is maybe not necessary, but testing for w; so w needs to go in the array, too.

So, now I have to dig in!

User avatar
mirz11
 
Posts: 2
Joined: Fri Sep 21, 2018 2:52 am

Re: RGB values received from TCS34725

Post by mirz11 »

Systembolaget wrote:That's funny... so that type of fabric is a favourite spam word right now... who would have thought!

-

By the way, when taking measurements with the TCS34725 for 10 minutes, the raw red, green, blue and clear values drift upwards quite a lot, even when the sensor and sample are in a tight ultra-matt black box and controlled temperature; for example clear goes from 12037 after 30 seconds to 14921 after 10 minutes.

This can be troublesome when one leaves the system on and takes colour readings only every minute.

Could it be that the COB LED heats up, thus the current rises, and thus its brightness? The thermal runway effect of non-heat-sinked LEDs?

If so, how could that be controlled? Or is something else the reason for the value drift?

Just found the image below from a popular instructable, where, without being discussed, one can see the values drifting upwards. They have the sensor in a black enclosure.
FPCJI35I11YTW8T.jpg
Hi mate, what method do you use to convert the raw color values to 0-255?
Thank you!

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”