getPixelColor description unclear
In my application I would like to highlight just one pixel by having it blink between full brightness and half-brightness. My assumption was that if I used all even RGBW values for that pixel's color, I could: get the pixel color, >>1 to divide all colors by 2, then save the dimmer pixel color. However, even when using even color values I'm getting leakage into adjacent colors, ie a fully bright green pixel blinks to cyan, a fully red pixel blinks to yellow.
It appears the "getPixelColor()" does NOT return the "previously set pixel color" as indicated by the method description but instead scales it by brightness. This means simply fetching the color through getPixelColor() and then resetting it through setPixelColor() changes the pixel color depending on the brightness setting.
The work-around that I found worked was to set brightness to 127, fetch the color, reset brightness back to the original value, then set the pixel color to >>1 color value. strip.setBrightness(127); uint32_t dim_color=strip.getPixelColor(blinking_index)>>1; strip.setBrightness(original_brightness); if(millis()&0x100) strip.setPixelColor(blinking_index,dim_color);
You're correct, getPixelColor() returns the pixel's RGB values after the brightness setting has been applied. Retrieving the original color value is not possible.
Rather than doing your brightness cruft, can you just force the most-significant-bit of each RGB value to zero when you calculate dim_color?
uint32_t dim_color=(strip.getPixelColor(blinking_index)>>1) & 0x7F7F7F7F;
Ah, you encountered the NeoPixel library’s Achilles heel. Tried to cover this a bit in the docs but it’s been tough to explain…
Short answer: it’s OK to use setBrightness() or getPixelColor() in one’s sketch, but not both. It has to do with some microcontrollers not being fast enough to perform brightness scaling “on the fly” as the data’s being sent out the wire, so we sneak this in by doing the brightness scaling in setPixelColor()…result being, what’s stored in RAM isn’t really the color you passed in, and there’s no way to get the original value back (unless, like, we used double the RAM, which isn’t gonna fly).
If you leave setBrightness() out of your code then the values returned by getPixelColor() will match those that were set with setPixelColor(). So the approach then, if you don’t want maxi-brightness colors, is to not use 255 or thereabouts in your RGB levels, but instead scale these back in your own code.
Alternately, if using setBrightness(), then setPixelColor() and getPixelColor() won’t match. An approach you can use then is to treat the strip as a write-only resource…that is, your own program state should contain any/all information necessary to generate the strip contents each time. This is what I usually aim for in my own projects.
Been thinking about a solution that would allow both to be used at the same time, but it’s gonna be complicated and might not actually be possible, so this is what we’re stuck with for now.
In the meantime though, yes, I’ll try to make this limitation more clear in the documentation.