Integers are great and all, but…
Earlier this year I made a “mobile party light” called L.O.L.A and gave it to a friend who throws a lot of impromptu get-togethers and likes to have funky mood lighting “on tap.” It’s 10 meters of TM1809, encased in 3/4" white split loom ducting (cable organizer tubing), run from an Arduino Uno with a SparkFun Danger Shield on top. I wanted the ‘end users’ to be able to adjust the lights and patterns just by moving sliders, not by re-programming, and the Danger Shield was a quick and easy way to do that. Software-wise, there are four or five major animation patterns, ranging from mellow to rave-y; all are adjustable for color, brightness, and speed from the Danger Shield sliders. (Picture of control box = Imgur: The magic of the Internet )
Last night, L.O.L.A was deployed at an after-Thanksgiving cocktail hour, in a very mellow “slow party lights” mode, with the colors mostly in the warm reds, oranges, and yellows, and I took a few seconds of video. In this mode it’s definitely not exciting; it’s designed to just be interesting background ambient lighting.
What, you may ask, does any of this have to do with integers? Not much – and that’s on purpose! Watch the video. You may be able to see that moving light bands on the strip don’t have crisply defined integer-pixel “ends” to them; they’re anti-aliased at the each end.
Although the strip is 300 pixels long, the position of each band of light is represented as a 16-bit value. But instead of a sixteen-bit integer (0…65535), I treat it like a fixed point Q12.4 value – meaning a 12 bit integer part, and a 4-bit fractional part, ranging from 0.0 … 4095.9375, in steps of 0.0625. When rendering a band of light onto the strip, the ‘head’ pixel and ‘tail’ pixel are displayed at a fractional brightness proportional to the fractional part of the coordinates. Er, hrm. That sounds complicated, but it isn’t so bad.
Basically, if a band of light starts at “10.25” and runs to 20.125", then the first pixel, #10, is only lit at 75% brightness (value=192). Pixels #11-20 are lit at 100%, and pixel #21 is lit at 12.5% brightness (value=32).
This all means that the bands of light can sort-of move by 1/16th of a pixel, instead of by whole integer pixels. All the math is done in fixed-point (because floating point is painfully slow, especially on a 300 pixel frame), which is fast, so the frame rate stays pretty high, and the motion appears very smooth – much smoother can you can get with just ‘integer pixels.’
The bands of light also fade in and out over each other using more fixed point fractions; the code uses “leds[i] += newcolor;” (note the plus sign in there), instead of just “leds[i] = newcolor”, so the colors add together.
The specific code for L.O.L.A. v1 is a bit too ugly to share, but if folks are interested, I could put together a simple ‘fractional pixel’ animation example.
Any other folks out there have ‘fractional pixel’ advice, notes, or code to share?
Update: Simple(r) example and sample code can be found here: https://plus.google.com/112916219338292742137/posts/2VYNQgD38Pw
