FastLED syntax compatability on PB

I love the idea of PB but come from a FastLED world. I would LOVE to see a version of PB made that uses Fastled syntax. That would make a ton of FastLED code instantly usable on the PB. I doubt I am the first to ask this, but have not seen it in searches.

Hi @devoh,
This is a good idea, and something I’ve been considering.

There’s a number of tools that could be ported/supported, and some commonality with slightly different inputs/names.

Much of the fastLED AP is fixed in 8 bit or 16 bit math, and as such has name variants (like beat8 and beat16) and takes integer arguments and return integer values where they usually mean some ratio between 0.0 and 1.0.

I could add a strictly compatible API so that code could work as-is (with a few exceptions), which is what you are asking for, but I think this code has a different aesthetic that is directly tied to the implementation constraints, much of it linked to 8 bit micros. These days 32 bit CPUs and even single and double precision FPUs becoming more common so I’ve tried to make a design choices that don’t punt these to the animation author.

I’ve considered adding compatible concepts, such as beat and beasin use fractional values instead of 8 or 16 bit integer inputs.

For experienced microcontroller programmers there’s a bit of mental shift to go from “255 is 1.0” to “1.0 is 1.0” but I think it simplifies things in the long run, and is certainly simpler for new users.

In the meantime, I think some measure of compatibility could be done with an adapter layer in the pattern code, for example here are beat8 and beatsin8 adapters:

//       beat8( BPM ) returns an 8-bit value that cycles 'BPM' times
//                    per minute, rising from 0 to 255, resetting to zero,
//                    rising up again, etc..  The output of this function
//                    is suitable for feeding directly into sin8, and cos8,
//                    triwave8, quadwave8, and cubicwave8.
function beat8(bpm) {
  return 255 * time(0.91552734375/bpm)
}

//       beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that
//                    rises and falls in a sine wave, 'BPM' times per minute,
//                    between the values of 'low' and 'high'.
function beatsin8(bpm, low, high) {
  return wave(time(0.91552734375/bpm)) * (high - low) + low
}

Of course these won’t truncate to 8 bits like their C code equivalents in fastLED since they are all using fixed point values, but for most cases it should work. If necessary, a floor() here and there would do the trick.

The beat16 and beatsin16 won’t work without some porting work because PB variables have only 16 bits for the integer portion and use signed numbers, so they store up to 32,767, not 65,535 and would overflow.

Here is the slight adaptation that doesn’t scale to 255 or 65536, and uses fractional values. If I were to design fastLED around a real number type (like floats or 16.16 fixed point math) I would make an API like this:

//       beat( BPM ) returns an value that cycles 'BPM' times
//                    per minute, rising from 0.0 to 1.0, resetting to zero,
//                    rising up again, etc..  The output of this function
//                    is suitable for feeding directly into wave, triangle, etc
function beat(bpm) {
  return time(0.91552734375/bpm)
}

//       beatsin( BPM, low, high) returns an value that
//                    rises and falls in a sine wave, 'BPM' times per minute,
//                    between the values of 'low' and 'high'.
function beatsin(bpm, low, high) {
  return wave(time(0.91552734375/bpm)) * (high - low) + low
}

As you can see, these are very similar, but don’t assume 8 bit values, instead returning values between 0.0 and 1.0, which are compatible with the rest of the Pixelblaze API. Conceptually these are similar to fastLED APIs, and might help port patterns.

I would fully welcome and help with any efforts to create a JS language API compatibility layer that helps port fastLED patterns. Of course there are a ton of APIs, not just the math stuff, including color utilities and things like that to explore.

I hope that helps both give you a head start in porting, and also an idea of my thinking around the design of the animation APIs.

2 Likes

@wizard,
I think this is a workable idea and would give everyone the best of both worlds. Thank you for the examples. I am just starting with PD and javaScript so any help is appreciated. I do have a question. If we make a fastled API does that take away from the PB’s available memory/variables, etc…? It would bite if it ends up limiting the PB. I am VERY excited to hear that there is a esp32 variant in the works. More speed/ram/flash!

1 Like

Certainly PB’s resources are not unlimited, but I wouldn’t worry about it quite yet. There are global limits (128), stack limits (128), array limits (64), array element limits (2048), and program space isn’t restricted but there are memory limits (10-25k or so) that are unlikely to hit unless your pattern becomes quite massive - even the most complex patterns I’ve seen haven’t come close.

For example, the two functions above compile to 104 bytes of program memory and consume 2 globals (for the function identifiers), zero array resources, and only a handful of stack elements while running.

Running the code takes time, but again I wouldn’t worry about it unless you run in to frame rate issues. It won’t be as fast as fastLED, but should be plenty fast for most small/medium LED setups.