I know there has been quite a gap of time since the last preview release for FastSPI_LED2, almost two months!  On the one hand, I would like to apologize for the gap in time, especially since there were a handful of bugs floating around there (looking at you WS2801 and Arduino analog pins!).  On the other hand, there have been a lot of changes and editions in the time since then so grab your preferred beverage, do the clicky on the link to go start the download of the release candidate, and settle in to read all about what’s new.

A what?

First, though, a quick definition.  What is meant by release candidate?  This is basically the code in a fairly close to what we’ll publish/release format, barring any last minute bug fixes.  Any features (new chipsets, new platforms, new techniques, new [REDACTED]) will just have to wait until the next release.  So what will happen between now and the release?  Mostly we’ll keep an eye out for (and focus on fixing) any catastrophic bugs that people run into, and we’ll work on documentation and examples to play with, and I will take some time to shift my primary focus over to a large led art installation going up in early july.

Fine, now spill!

As hinted above, there is a lot in this release candidate.  A whole lot new.  FastSPI_LED2 had a number of goals laid out for it.  The first was to continue to be a straightforward to use high performance multi-led chipset interface library, a no brainer, we even put it in the name.  How to expand on that?  Let’s add multi-platform support (starting with the arm-based teensy 3.0), done in a way that will make porting to even more platforms (due, chipkit, beagle, CoAction, etc…) easier, much much easier.  Also, let’s apply “fast”, not just to the library itself, but to how quickly someone can get up and running using it.  People following the google+ community have seen some hints of what we’re talking about here.  Also, we’re going to add “fast” to the speed with which we can add support for new chipsets.  Also, we’re going to add “fast” to more of your led related programming, and maybe even beyond that (i.e. not just fast, but more), but we’ll get to that eventually.

The new library has nearly 10 times the amount of code.  However, don’t worry!  It compiles down far smaller than the old library.  Sample applications have gone from nearly 13kb of precious program flash down to 2600 bytes.  How do we do this?  Well, those details we’ll spill more on in the future.  We’re planning a series of posts digging down, in further detail, the various ways we’ve made our library do the thing we’re doing.  As with fast, however, not only is the compiled code going to be smaller, but the amount of work that you would need to do is also going to be smaller.  How much smaller?  Check this out:

#include <FastSPI_LED2.h>
#define NUM_LEDS 150

void setup() { LEDS.addLeds<WS2801>(leds, NUM_LEDS); }
void loop() { LEDS.showColor(CRGB::Blue); }

How about that?  No more multiple sets of initialization methods.  Also, no longer limited to one item.  You could have multiple sets of leds, even with different controllers!  And your options for configuring and tweaking those controllers have also been greatly expanded, but again, more on that later.  You will also notice that you no longer need to define your own CRGB structure.  This isn’t just cosmetic.  You will note that not only does the CRGB structure provide a way to define your set of leds, but it also provides named colors to work with!  We have all the HTML colors included in there.

You keep saying we, what’s up with that?

Ah, attention has been paid.  Yes, there are now two of us working on FastSPI_LED2.  Mark Kriegsman has joined in with a wide swath of new toys to add to the LED programming world.  As much of an optimization fanatic as I am, if not more so, he also brings a passion for the art, and for the color.  Since we’re talking about him here and now, we’ll dig into some of large contributions that he’s making to FastSPI_LED2.

In the 2.5 years that the library has been out there people have done some amazing, incredible, beautiful things, using the library as a base, including the two of us.  It is clear to us that, for LED programming, there is more to life than simply pushing rgb values out to the strips.

For one there is navigating the color space.  A lot of work is doable just playing with RGB, both simple and advanced, and the addition of the named colors shown above makes it even easier for people to work and play with.  However, we found ourselves playing in the HSV color space a lot, mainly because this provides for some really really easy ways to navigate around colors.  It started out with me finding a library to convert HSV to RGB, and then as I tend to do, optimizing it to get better performance out of it.

Mark started working with me on this, and he started out by tuning the HSV to RGB conversion to be even smaller and faster.  Then it turned into a game, with each of us making tweaks to squeeze a few more clock cycles and bytes out of the thing (he won – at just about 1µs to convert HSV to RGB on the teensy 3).  However, that wasn’t enough for him.  Mark dug into the theory behind the HSV color space, as well as the theory and biology behind the human eye’s perception of color and brightness.  He tweaked and massaged the library further, keeping it fast but tweaking it around so that the colors looked smoother, and more natural, and better fit to our eyes.

In fact, it looks so good, and so smooth, our default color conversion uses this more natural, more balanced, system.  Of course, since we believe in choices, and speed, if you want, for your project, to use the raw, uncorrected conversion as fast as you can get it, we’ll give you that too.

Did Mark stop there, though?  No!  Of course not.

Lib8tion, or “pour yourself another”

One thing I discovered in doing LED projects with a variety of chipsets from a variety of suppliers, I discovered that every supplier has a different opinion on what the proper order of “RGB” is.  Some think it should be BGR, some think it should be GRB, one even thought it should be  ЯᗺG (thankfully, no one thought it should be B0RG, or it’d all be futile!).  Previously, this was dealt with by people changing the order of R, G, and B in their struct.  However, as mentioned above, we have these lovely hsv(ish) to RGB converters.  Those work a lot better if they know what the RGB type is and the proper ordering.

To handle this, and also make it easier for people to pair up strips with different orderings on different pins, we moved specification of a strip’s RGB ordering to the point where you add a controller, and made a standardized CRGB class.  Of course, since we’re playing in C++, we can put methods on the class, and oh did we.  The full documentation is coming up, but you can do things like add rgb colors, multiply them to shift scale, and more!  Of course, as with all things, we want this to be fast, and did Mark ever deliver.  Since RGB values are 8 bit, he pulled together optimized 8 bit versions of a number of operations (multiply, divide, scaling, saturating add (e.g. add two numbers and the value is 255 if the sum would be > 255, useful when dealing with RGB values!)), and added those to the class and world.

Of course, we immediately looked for other places to put this.  One is, his scaling function is fast enough that the FastSPI_LED2 show functions now all take an optional brightness argument and will scale the brightness as it writes to the led strip with no increased overhead (except for one limited case, which we’ll document, but won’t affect most of you).  Let me say that again.  Global brightness FOR FREE.  Order  now, and we’ll throw global dimming for free too!

There’s more (you didn’t think we were done, did you?).  A whole library of interpolation, easing, random number generators, optimized memory operations, sin/cos.  You don’t need us to explicitly apply “fast” to all of those, do you?

You said fast, what about the leds?

You will be able to be fast with getting the colors that you want all of your leds to be.  Of course, what kind of leds are you thinking of?  We’ve got WS2801, LPD8806, WS2811/2, TM1809/4s, TM1803, UCS1903, SM16716, DMX controlled.  You want to preserve your hardware SPI port for your SD card reader?  Put your WS2801 on a different set of pins and the library will automatically fall back to high performance bit-banged output (2.5Mbps on 16Mhz arduino, over 5Mbps on a 48Mhz teensy 3.0).  Put multiple strips on your controller.  Of different types, even!  Also, you didn’t think we’d forget about the fast or the spi, did you?  On the teensy 3 you can push those LPD8806s at nearly 22Mbps.  If you don’t feel like playing with math at home, that’s 150 leds at over 6000 fps.  Let that sink in for a moment.  Sure, you want to do something other than push LED data, so let’s call it 3000 fps and you can spend the rest of the time thinking about what you want to show on the strip for 0.0003 seconds.

But wait, there’s more!

Alas, not in this release, there isn’t.  We do have a long list of things that will trickle out in updates over the next few months (after we take a bit of a break).  I have at least four more chipsets sitting on my desk at home, we’re investigating 16bit representations of rgb/hsv color data for insanely smooth color transitions, we’re going to push as much of the led writing to DMA on the platforms where we can (oh, hey, look, back to 6000 fps, and you get ALL of your cpu time back!), we’re going to add platforms (we’re looking at you due!), we’ve got some ideas for even more efficient support of multiple strips of certain types of leds, we’re going to add more code to support making things bright, pretty, flashy, and we’re going to keep the code as fast as we can to stay as much out of your way as possible.

And we haven’t even started talking about [REDACTED]!

As Mark said tonight, “Let a thousand pixels bloom”