I tried searching for this and couldn't find anything, but I feel like I'm probably asking a question that has already been asked. How does the single uint_32 color value relate to the 3 individual RGB values? I'd like to write my code expressed in just one 32 bit value, but I'm not sure how that 32 bit value relates to the RGB 8 bit version.
-Gavin
Neopixel uint_32 color values -
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- SeiRruf
- Posts: 82
- Joined: Thu Sep 04, 2014 3:07 am
Re: Neopixel uint_32 color values -
Hello gavinm, and welcome to the Adafruit forms!
The uint32_t declaration reserves 32-bytes for the given variable. NeoPixel color strings are only 24 bytes long, but there isn't a declaration for that.
Using the NeoPixel library, it is very simple to convert 3 8-byte variables (r, g, b) into one "32-byte" color value using the line of code below:
uint32_t purple = string.Color ( 255, 0, 255 );
The mathematical way of doing the same thing:and bit-shifting way:
In all of those examples, variable 'purple' would now be set to "16711935", or "0xFF00FF" in hex (notice the color values a bit easier in hex? Where 255 == FF). But how do you split that into three RGB values once again? The simple answer, byte-shifting in the other direction.
Here is a quick function I coded to split the colors.
To use it, call:
uint8_t green = splitColor ( purple, 'g' ); //returns 0, because our variable purple doesn't contain green.
Bit shifting in this example explained briefly.
'x >> y' shifts the given var (x) over (y) bytes. Since we're dealing with a 24-byte color, in order red, green, blue. In this example, lets take r:255, g:0, b:255.
In code, it is represented as 11111111 00000000 11111111 (bit placement: 23-22-21-20-19-18-17-16, 15-14-13-12-11-10-9-8, 7-6-5-4-3-2-1-0)
we want to take the first 8-15 bytes and call them green, and so on. Declaring the return value as uint8_t ensures we receive 0-255 expected value.
In short,
255 is a uint8_t value. It can not go one over. RGB holds 3 of those. 8*3 = 24. The closest declaration we have without tossing ram is uint32_t, which would easily house our 24-bits. I hope that makes sense, and was able to help you familliarize yourself a bit more with what you're looking for!
The uint32_t declaration reserves 32-bytes for the given variable. NeoPixel color strings are only 24 bytes long, but there isn't a declaration for that.
Using the NeoPixel library, it is very simple to convert 3 8-byte variables (r, g, b) into one "32-byte" color value using the line of code below:
uint32_t purple = string.Color ( 255, 0, 255 );
The mathematical way of doing the same thing:
Code: Select all
uint32_t red = (255^2 * r) + 2(255*r) + r;
uint16_t green = (255*r) + g;
uint8_t blue = b;
uint32_t fullColor = red+green+blue;
Code: Select all
uint32_t red = (uint8_t)(r << 16);
uint16_t green = (uint8_t)(g << 8);
uint8_t blue = (uint8_t)(b << 0);
uint32_t fullColor = red+green+blue;
Here is a quick function I coded to split the colors.
Code: Select all
/**
* splitColor() - Receive a uint32_t value, and spread into bits.
*/
uint8_t splitColor ( uint32_t c, char value )
{
switch ( value ) {
case 'r': return (uint8_t)(c >> 16);
case 'g': return (uint8_t)(c >> 8);
case 'b': return (uint8_t)(c >> 0);
default: return 0;
}
}
uint8_t green = splitColor ( purple, 'g' ); //returns 0, because our variable purple doesn't contain green.
Bit shifting in this example explained briefly.
'x >> y' shifts the given var (x) over (y) bytes. Since we're dealing with a 24-byte color, in order red, green, blue. In this example, lets take r:255, g:0, b:255.
In code, it is represented as 11111111 00000000 11111111 (bit placement: 23-22-21-20-19-18-17-16, 15-14-13-12-11-10-9-8, 7-6-5-4-3-2-1-0)
we want to take the first 8-15 bytes and call them green, and so on. Declaring the return value as uint8_t ensures we receive 0-255 expected value.
In short,
255 is a uint8_t value. It can not go one over. RGB holds 3 of those. 8*3 = 24. The closest declaration we have without tossing ram is uint32_t, which would easily house our 24-bits. I hope that makes sense, and was able to help you familliarize yourself a bit more with what you're looking for!
- gavinm
- Posts: 2
- Joined: Sun Aug 31, 2014 12:56 pm
Re: Neopixel uint_32 color values -
SeiRruf this was over my head a little when I first read your response, but I've been slowly chipping away and I've finally climbed up to a level where this makes sense. Thanks so much. I kept coming back to your response and it's clear as day now.
- michaelmeissner
- Posts: 1822
- Joined: Wed Aug 29, 2012 12:40 am
Re: Neopixel uint_32 color values -
One note, the so-called mathematical way of doing the encoding cannot be used in C/C++, since the ^ operator is the binary XOR operation, and not raise a value to the power. To express it mathematically, I would write it:
Code: Select all
uint32_t red = (256 * 256 * r);
uint16_t green = (256 * g);
uint8_t blue = b;
uint32_t fullColor = red+green+blue;
- timcode
- Posts: 10
- Joined: Tue Jun 04, 2013 11:22 pm
Re: Neopixel uint_32 color values -
I've been trying to figure this out too -- great explanation!
Please be positive and constructive with your questions and comments.