# RGB sensor HOWTO use?

I've got an RGB sensor (this one with the three LED thingies) and wonder how to access it using NXC.

I know I can SetSensorColorFull(IN_1); and then access it using ReadSensorColorEx or, for simplicity, ReadSensorColorRaw, but I'm a bit stumped wrt. the return values.

I know normal 24-bit (3x8bit) RGB colour codes. I know normal NXC return values (0/1, 0‥100, 0‥255). But I don't know how the values here work.

I've toyed around with i = ReadSensorColorRaw(IN_1, r); where unsigned int r[4];, and got values: i was always 1 (even if the cable was unplugged), and the r[INPUT_RED] aka r[0] values were somewhat usable, and about 0‥60 were black in general, and I got up to 1023 (when holding the sensor towards light), but if I hold the RGB sensor towards anything yellow, green or blue, the values are somewhat off. Also, I found no docs whatsoever as to what r[INPUT_BLANK] is supposed to be.

When unplugging the sensor, I got r = { x, 0, x, 0 } (where x was roughly 120) in my test program just using NumOut to debug the sensors, so I assume that the sensor return values are biased somewhat?

Would using ReadSensorColorEx give somewhat better usable values, or anything else I can use? Do I need to calibrate them first, and if yes, how? To clarify, I don't want the functions that just give back “it's red”, “it's green”, etc. but I want somewhat usable R/G/B colour tuples (and would take Intensity as bonus, although I'm using light sensors for them normally, or SetSensorColorRed if must be).

I'm using NXT Firmware 1.29, and exclusively Open Source tools. If there's anything else needed, information wise, just comment.

-

To understand how to use the data, it help to understand how the color sensor works. Let's take a step back for a minute and have a look. The sensitive electrical component here is just a photodiode or phototransistor that lets us measure light intensity.

If we turn all of the LEDs off we are just measuring ambient light. If we turn on just one of the LEDs and hold the sensor close to a surface, we are measuring mostly the reflected light from that one LED (and some ambient light).

When we switch to color mode, it looks like all 3 LEDs are on at the same time, but what is actually happening is that they are being switched in sequence very rapidly. off-red-green-blue-off-red-green-blue-... and so on.

This means the mysterious 4th value, INPUT_BLANK, is the off part of the cycle - it is just measuring ambient light.

You said that you would take intensity as a bonus, but actually that is all you are getting. If you hold the sensor close to a white surface, you should get high values for all 3 colors. If you move the sensor even closer (but not too close), the values will increase. This is because the reflected intensity is getting strong, not because the surface is getting whiter.

This means the RGB values are not like the ones on your computer screen. If you do a web search for robotic vision systems, you will find that RGB just doesn't work. The common practice is to convert the values to HSV (hue-saturation-value). The HSV values can more easily deal with changes in ambient light allowing you to more accurately determine colors.

I am not sure how the normalized and scaled values are calculated in ReadSensorColorEx, but you can play around with them and see if they give you better results for whatever it is that you are trying to do.

-
Thanks for this enlightening explanation. Do you have any references for this, so we can read deeper if needed? Also, do you know of any example program using the RGB sensor in full mode? –  mirabilos Sep 14 '14 at 11:20
Sure. I learned most of this by reading the source code for the EV3. The timing happens in the d_analog device driver. I haven't got to the part where it actually computes the colors though. It's in there somewhere. –  David Lechner Sep 14 '14 at 17:22
For an example, have a look at the Mindcuber source code. It does it's own figuring of colors by converting them to HSV and then sorting them. –  David Lechner Sep 14 '14 at 17:25
Thanks. I will accept this as answer (feel free to move those comments into the answer body), even though the Mindcuber source is not Open Source it’s enough to read it to write a documentation for the sensor. –  mirabilos Sep 17 '14 at 12:31