Hi, I'm interested in using the FastSPI_LED2 library to control three WS2811 LED strips

Hi, I’m interested in using the FastSPI_LED2 library to control three WS2811 LED strips with an Arduino Uno. I’d like to control each one independently, giving each strip its own data pin and having them do completely unrelated things. Can anyone point me to some example code that controls multiple strips that are doing completely separate things? All the code I’ve found seems to treat multiple strips as though they’re part of a 2D array, so I’m having trouble understanding how to apply that to my situation. Thanks.

You can logically represent all three strips with a single array and then just treat each 1/3 of that array like they were individual entities. Unless you topology necessitates not having them daisy chained together

If you want them separated, though, you could always do:

CRGB leds1[16];
CRGB leds2[16];
CRGB leds3[16];

void setup() {
LEDS.addLeds<WS2811, 11>(leds1, 16);
LEDS.addLeds<WS2811, 12>(leds2, 16);
LEDS.addLeds<WS2811, 13>(leds3, 16);
}

void loop() {
// do stuff with leds1
// do stuff with leds2
// do stuff with leds3
LEDS.show();
}

Thanks Daniel, I think your strategy will make my code easier to read and conceptualize.

Also, once I get my next project done, and do some maintenance work on the library, I have some higher level libraries/code examples that I want to put up.

For my personal use I have pattern code that simple takes a representation of a set of LEDs and works on that, then I can have an arbitrary number of these pattern objects, running at different rates, and a scheduler that takes care of running them at the rates they want to run at and making sure the LEDs get drawn out at the frame rate that I want.

Liquid eye has a total of 27 individual instances of programs running (and at the moment, four or five specific programs that those instances may be using) - abstraction is a good thing :slight_smile:

Unless I’m completely misreading the Fast_SPI docs, you don’t gain much by using it with WS8211’s. They’re not SPI.

Take a look at the Adafruit Neo_Pixel library.

With that, you’d start out like this:

#include <Adafruit_NeoPixel.h>

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(33, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(33, 7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(33, 8, NEO_GRB + NEO_KHZ800);

void setup() {
strip1.begin();
strip1.show(); // Initialize all pixels to ‘off’

strip2.begin();
strip2.show(); // Initialize all pixels to ‘off’

strip3.begin();
strip3.show(); // Initialize all pixels to ‘off’
}

void loop()
{
//do stuff with strip1
// do stuff with strip2
// do stuff with strip3
}

And I see Daniel’s plan is very similar. We’d hoped to use the FastSPI libraries with a project, but since the WS8211 can’t use hardware SPI, we just stuck with the NeoPixel libraries.

You are completely misreading the docs - the library is named FastSPI_LED2 because it started out as a high speed SPI/PWM library for driving 595 shift register based rgb leds (and then HL1606) - it has since spread out to support nearly a dozen LED chipsets, many of which are not SPI based.

I’m working on figuring out the best timing for a name change (there’s a lot of pointers out there to the existing name) to indicate that it’s not SPI-exclusively based anymore (though it does include some high performance SPI code that can be used for generic reading - as well as Pin access code).

In fact, the WS2811 is primary led chipset these days - it’d be pretty bad for me if my own library didn’t support it :slight_smile:

Next up is going to come multi-plexing WS2811 output so that I can double or even triple write performance on some platforms :slight_smile:

Don’t mean to step on any toes. I’ve been digging into this lately and I think not on the misreading.

Neither library uses actual SPI for WS8211 for obvious reasons. Both use optimized inline assembler to handle the weird timing on that chipset. If the other chipsets are not needed, the NeoPixel library gets the job done. Didn’t say FastSPI wouldn’t work. Just that what seem to be the most advantageous features of FastSPI ( ie hardware SPI instead of bitbanging ) aren’t applicable.

Not sure which is faster. Haven’t tested that. If FastSPI_LED2 gets faster, we’ll take another look.

If you implement interleaving multiple string output in the same loop, that would be very interesting.

But I already have a code base for the NeoPixel library, which works well enough at present. I’d already whipped up my code snippet before I saw that you already had one there.

No toes stepped on here - but there’s more to the Fast part of the library than just the SPI, even beyond all the high level colorspace/rgb pixel management work that there is, or the higher performance interpolation code, or the fast and clamped arithemtic operations that let you add/subtract pixel values without having to check for/worry about wrapping/over/underflow - there’s two major places where the FastSPI_LED2 library is more efficient than NeoPixel.

The first is pixel setting. Setting RGB color values w/FastSPI_LED2 is simply 3 1 byte writes to memory. For NeoPixel, there’s a method call, a bitmask and’ing, a comparison, which means jumps, and then the 3 bytes get set, also it is unclear whether or not the pointer incrementing that the neopixel library does gets compiled down as efficiently to the avr’s offset memory index functions. NeoPixel does the RGB re-ordering (if your strip needs it) at the point where the pixel value is set, I do the RGB re-ordering interleaved in writing the data out to the chips - no cpu cost to the end code.

Similarly, the library does something similar with global brightness. E.g. if you call show(128) then all the led data gets pushed at half the brightness of what you set (it’s a 0-255 value scale). You can read a value off of a knob and be able to globally change the brightness of your leds without changing any other programming - again, interleaved in with the writing of data out to the led chips, so no extra performance cost there.

Also - switching code over on changing chipset is another thing that I wanted out of this library - since i switch chipsets based on what’s appropriate, it’s nice to be able to re-use code by just changing the chipset used, vs. swapping out the library.

When you only have 16Mhz, and an led chipset that requires an 800kbps data rate, your remaining clocks count when you’re dealing with more than a couple dozen leds :slight_smile: The Fast isn’t just for pushing bits out to the leds…

Very interesting. Glad I posted. We’re still pretty early in the project, and if a re-write was going to happen to change library, this is a good time.

I’ll grab a copy and give it a shot.

Thanks for the info !

(To be fair, the two of us who are working on FastSPI_LED2 do high performance optimization (memory, cpu usage, network usage, etc…) on all scales both as part of our day job and for fun, and across the board and count cycles like some kinds count m&ms :slight_smile:

No problem! (So much documentation to get written up for people to use! I can’t wait until people can start using the high performance pin/spi libraries for talking to things other than leds).

Also - feel free to ping if you’re interested in guinea pigging the ws2811 interleaving - I may end up needing to do that sooner rather than later for a project i’m working on for Priceless.

Daniel my infinity heart mirror has 799 WS2811/12 LEDs on it. I would love something to make if faster… let me know and I would be happy to guinea pig! Oink!

Ouch, that’s 24ms of write time per frame - this is the one downside to the ws2811/12’s, they’re pretty strictly locked at a paltry 800kbps data rate :frowning:

Wow. Got the FastSPI_LED2 library working with my hardware.

Noticeably faster than the NeoPixel library doing the same tasks.

Great work, guys. Many thanks.

I may have the hardware on hand to try the interleaved code in a week or two. I have Arduino Unos, NanoV3s, and access to a couple of Teensyv3’s. Also have a meter of LPD8806 LEDs on hand.

BTW - sorry for semi-hijacking your thread, Bonnie.

No way, this discussion has been awesomely informative for me. This is my first real arduino project and I’m very much learning as I go. Please hijack my threads anytime. :wink:

Glad to hear we haven’t wandered too far afield for what you’re working on.

Just ignore the NeoPixel library discussion. Bad call on my part. FastSPI_LED2 is the way to go.

Daniel, I’d love to play with the interleaving stuff. I have 7 strands in my current project and more in my next.