Color Holiday Twinkle Lights
After all the discussion yesterday, I put together a ‘twinkle lights’ sketch that can use any colors you wish. It’s preloaded with some holiday color schemes to get started:: red&white&green, blue&white, ‘snow’, rainbow, and an approximate color match for incandescent ‘fairy lights’.
Code is here: https://gist.github.com/kriegsman/5408ecd397744ba0393e
The theory of operation is similar to the ‘warm twinkles’ posted here yesterday: https://plus.google.com/112916219338292742137/posts/ScvWcDq1rC5 Each pixel is either black, or it’s brightening up, or it’s darkening down. A separate array called ‘directionFlags’ is used to track whether each pixel should be brightening or darkening.
For illustration purposes, two different implementations of directionFlags are provided in the code. One is simpler but uses up a full byte (8 bits) of memory for each pixel’s direction flag, even though only one bit is needed. This makes each pixel take up 32 bits (24 for the color itself, and 8 for the direction flag).
The second implementation of directionFlags is more complicated, but much more compact: it uses just one BIT of memory for each pixel’s direction flag. Every eight pixels’ flags are packed into one 8-bit byte of RAM. With this implementation, each pixel takes 25 bits total: 24 for the RGB color, and just 1 for the directionFlag.
Yesterday’s implementation ‘hid’ the direction flag in the low bits of the red color channel. This code doesn’t try anything quite that tricky; it gets more difficult if you want to allow any color. Having a separate array of flags simplifies things here.
It’s also worth noting how that brightening and darkening work. Darkening is relatively easy: the three color channels are each reduced by a fraction using nscale8. The brightening takes two steps: first it calculates a fraction of the existing color (again, using nscale8), and then adds that onto the existing color. So provided that the values already in the color are bright enough to have the right hue, this brightening technique works reasonably well. There are cases where it won’t work well, and the hue you wind up with isn’t exactly the hue you were shooting for, but given that it required zero additional RAM, it’s a good option to explore.
Finally, you can make your own sets of color palettes, or write a different mechanism entirely for choosing new colors. Because of the way the colors are chosen and then set for each pixel as it’s ‘lit’ up, there’s a nice cross-fade between the different palettes.
Earlier, Simon Hermansen posted some good code that did something similar. (http://paste.ofcode.org/4t6xQA7DDwbaHaGFtd934j) Visually, the effects are similar, and his code is clear and easy to read. The big difference is that that code requires 56 bits per pixel vs. this code’s 25; the practical upshot of that is that this code can drive more pixels from the same microcontroller before it runs out of RAM. I provided the two implementations of directionFlags to illustrate the trade-offs between code simplicity and memory compactness.
http://www.youtube.com/watch?v=MGHPEwH3eI0
