Extracting RGB color value

Hello there,

I’m using one of the various versions of the Adafruit_WS2801 library, and it uses a uint32_t type to describe the colors of an RGB led.
I also found the following function someone created to help create variables of this type:

uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}

My question is - how do I extract the red, green and blue values out of such a uint32_t type ?

I tried the following, but I’m encountering issues with the blue or green:

int getRedValueFromColor(uint32_t c) {
    return ((uint32_t)c >> 16);
}

int getGreenValueFromColor(uint32_t c) {
    return ((uint16_t)c >> 8);
}

int getBlueValueFromColor(uint32_t c) {
    return (c);
}

When I tried using these function on the photon RGB led, the red worked fine, but the green gave me blue and the blue gave weird purple…

All the colors need to be 8 bits, not 16 or 32 like you’re returning for green and blue. For green, if you shift it 8 places to the right, you’re left with the red and green values with 16 bits of information, so if you cast that to a uint8_t (by having the return type be a uint8_t), you will only get the 8 least significant bits. For blue, just casting c to an uint8_t will do the same.

uint8_t getRedValueFromColor(uint32_t c) {
    return c >> 16;
}

uint8_t getGreenValueFromColor(uint32_t c) {
    return c >> 8;
}

uint8_t getBlueValueFromColor(uint32_t c) {
    return c;
}
2 Likes

I do like UNION for that

* Types required for RGB-LED control */
struct ARGB_COLOR {
	byte B;  // blue  channel
	byte G;  // green channel
	byte R;  // red   channel
	byte A;  // alpha channel to indicate RGB.control true (!= 0) / false (== 0)
};

union COLOR {
	ARGB_COLOR argb;
	unsigned int value;
} color;

  // usage
  color.value = value;
  RGB.control(color.argb.A);
  RGB.color(color.argb.R, color.argb.G, color.argb.B);
2 Likes

Thank you !
Ric’s solution worked wonderfully!

My response to your question was aimed at showing you how to correctly write those functions, but looking at the larger picture, you might want to consider using a union as @ScruffR suggested. A union with a struct as one of its members is a nice and organized way to access smaller pieces (bits, nibbles, bytes) of a larger entity like a 32 bit int. I can’t tell if this is appropriate for your current project, but it’s something to keep in mind.

2 Likes