I finally got a chance to play with v2 of the library.  First go

I finally got a chance to play with v2 of the library. First go at it and the WS2801 string I’m testing just went berserk … much like when I forgot to set a data rate on the v1 library. I did the obvious and inserted a .setDataRate() line only to have it barf at me. A bit of digging revealed that no longer exists, but instead the fourth parameter in the construct is now the speed. Tried my usual data rate of ‘2’ and that didn’t work. Turns out I had to bump it all the way to 16 to get the example sketch to even run on a 32 pixel string. Anything less than that and only part of the string would light up.

So I wonder … what does the speed relate to. I know Daniel said the speed parameter goes from 0 to 255, but what does that relate to, and how does it related to the old library? With my SD Card Readers, which are SPI devices, I’m able to set the speed with SPI_FULL, SPI_HALF, SPI_QUARTER, etc., etc. That makes sense to me. But to have a range from 0 to 255 …?

Thanks for sharing. Yeah, they need some documentation patches to help clarify the new code structure. I am having a similar problem, but hadn’t tried a speed above 7, so I will try that also.

Documentation and examples will come when the library is finished (part of why these are still preview releases).

The value is basically the delay/timing for each bit that gets sent out. The higher the value, the more time taken for each bit.

In the first version of the library, the value from 0-7 mapped to the arduino’s set of cpu clock dividers for spi clock speeds. The teensy 3, however, has more timing options, and with the software spi, I can basically run at any rate desired, so straight power of two dividers don’t make sense.

Oh I wasn’t too worried about the documentation, as you said, this is still preview code. I was just wondering about the 0-255 range for speed. At a value of 16, it works great on my test string of 32 pixels. Not sure yet how it will behave once I put a full 500 pixels on or if I have to make it slower.

Another question. When defining which controller, you’re setting a clock, data, and latch pin (and speed value). For something like the WS2801 which doesn’t use a latch pin, does it matter whether that value is set or not? Or will that mess with the SPI somehow if it’s set to say, 0 (I presume 0 would indicate the first pin, which in Arduino world is many times tied to one of the serial buses.)

The underlying spi code now makes the select pin optional, but I haven’t had a chance to expose that to the higher level classes yet.

While the ws2801 doesn’t make use of it directly, I want to provide support for it so that people can do things like hang multiple strips off of the hardware spi port and use the select lines to write to specific ones (yes, this would require extra circuity to do that, however). In fact I want to write up support for working with mux’s, so that you could switch between up to 16 lines using only four select pins.

In your comments about speed you note on why someone would want to do that. I can push data at over 20Mbit to lpd8806s at up to about 120-150 LEDs. If I want more LEDs, I can either slow down the data rate as the strand gets longer, or I can distribute my LEDs over multiple strands and use a mux to select between them and run at full speed. I have some hardware to test this exact setup (though, in my case I want to use it to build a multi-led-strip test harness).

As for the speed values, another way to think about them is as clock dividers - eg a speed of 2 is half, a speed of 4 is quarter, etc…

There are defines for the default set of avr clock dividers (2,4,8,16,32,64,128) but I’m not local to the code at the moment so I can’t easily look them up.

Ah - here we go SPEED_DIV_2/4/8/16/32/64/128 are the defines. On the arduino (and, at the moment, for hardware SPI on the teensy) any other value is rounded to one of those values, because that’s just how the hardware setup is done. For software/bitbang’d spi, that value is used to set up how much delay is going on between each bit that gets written out, roughly. (It’s not an exact mapping, however).

That raises my curiosity even more then. How is it, in v1, I can run with a datarate value set to 2 (which would mean half), whereas with v2 I need to raise that value to 16? Anything lower and the strings won’t work.

Also - another thing to try, to see if you can up the data rate (this is something that I’ve found to work on some strips) - see about grounding clock/data/ground lines on the far end of the strip.

Actually, in v1 - 0 is half, 1 is 1/4 and 2 is 1/8, etc…

Also - even with the hardware SPI, the v2 library is much faster than the v1 library - that might also be juggling things on you at times.

(and because of a quirk in the mapping and how the avr SPI does setting its dividers, 3 and 4 are 1/16 and 1/32 respectively, but 5 and 6 are both 1/64 and 7 is 1/128)

That makes more sense if with v1, 2 is 1/8 and with v2 I have to set it to 16. With v2 being faster, it stands to reason that I would have to change the divider.

Mind you, this all started because I couldn’t get my strings to work at 5V AT ALL after not having touched anything for the past four months. They worked fine at 3V3, but 5V would go berserk. After a glass of wine (or was it a bottle, I forgot), that’s when I realized I had set the .setDataRate(2) AFTER the .init() and .start(). After I sorted that out and verified that it worked just fine at 5V, I switched to the v2 library only to watch it all come crumbling down again … because I used the same value as speed: 2. Once I raised that to 16, everything worked again. At a speed of 4, 1/4 of the string would light up very erratic, at 8 about half would light up, again, very erratic. At 16 is when it finally worked. It seems the higher the voltage, the slower the data rate must be.

I will try adding VCC/GND at the end of the strip, and add pulldowns on the DATA/CLK lines, see what happens. Then mess with the speed variable again.

Question: if I have the library control two LED strings, one on the SPI bus using pins 13, 11, and 10, and a second one on three other pins, can I address each one separately?

I did a quick test, and defined LED1 and LED2 and I wrote code that’s simply turning on leds[0].r to 255 randomly. But that affects both strings. So how can I address them separately, if at all possible?

You can use two separate RGB led arrays. I have a test app that runs five different types of strips (ws2811, ws2801, tm1809, lpd8806, tm1803) in cycling patterns - nice to be able to test combinations without rebuilding/re-pushing :slight_smile:

Two ways to do this - let’s say you have 25 leds on each string:

CRGB string1Leds[25];
CRGB string2Leds[25];

WS2801<11, 13> LED1;
WS2801<8, 9> LED2;

// do stuff with string1Leds, do stuff with String2Leds

LED1.show(string1Leds, 25);
LED2.show(string2Leds, 25);

You could also do a multi level array

CRGB leds[2][25];

LED1.show(leds[0], 25);
LED2.show(leds[1], 25);

Or if you feel like doing the math yourself

CRGB allLeds[50];

LED1.show(leds, 25);
LED2.show(leds + 25, 25);

(hmm, I should make it so that show can take an offset, so that second line would be LED2.show(leds, 25, 25); )

One of the pieces I will be writing up before the final library ships will be a master controller, where you will be able to say something like:

CRGB ledsAll[25];

LedController.add(new WS2811<11,13>, ledsAll, 25, 0);
LedController.add(new WS2811<8, 9>, ledsAll, 25, 25);

then after you do your array juggling and stuff, simply call


Still thinking about that top level interface, sa I want it to be something that is quickly/easily accessible to very very green newbies, but also be powerful/flexible enough for people doing more complex/dynamic things.

Ah, goodie. Creating two separate arrays works great. The next thing to test is how much overhead it adds and whether there’s any kind of slowdown …

So - there’s two things that you’re going to notice. One is that since you’re pushing data to two strips, you will spend twice as much time pushing data vs. 1 strip. The other is that equivalent speed values right now don’t turn into equivalent timings between hardware and software SPI - i’m working on fixing that.

Once I get DMA on the teensy 3 working, the right way to do this would be to instead have multiple LED controllers on the same strip, but with different select pins selected. Then you can use hardware SPI in the background (freeing up CPU time for you to prepare your next frame) for both strips :slight_smile: I’m still working out the specifics of that, and the final library will ship with example code for that.

Something else I’m noticing: if I put the second string on pins 8(SCK) and 7(DATA), it woks fine. If I put it on pin 9(SCK) and 7(DATA), it works fine. However, if I put it on pin 9(SCK) and 8(DATA), it won’t work. The code being tested is randomly turning on the first LED red and pushing it down the entire string (think about a line of morse code that you’re reading.) But if I use pins 8 and 9, I get some of the pixels lighting up blue or magenta (as well as red) …

Teensy 3 or arduino/avr? If it’s an AVR, it might be a bug in an optimization that I have in place for when the pair of pins are on the same output port - i’ll investigate.

And yes, it must be a “same port” issue. I just tried pins 4 and 7 (or PD4 and PD7) and got the same erratic result.

For the non-hardware SPI setup - what’re you running the data rate at? Can you try making sure it’s at least 4? Let me know if that helps or not (it will help me narrow down the problem)

Huh, another bug? Tried setting a string using pins 3 (PD3) for SCK and A5 (PC5) for DATA however that didn’t work. On a whim I physically started moving the wire for DATA to a different pin. I reached A3 (PC3) and lo and behold, the string started working. So even though the code specifies A5, it’s A3 that’s sending data.

Data rate across all of them is set at 16.