Neopixel functions really slow?

I’m working with some very long strings of neopixels and beardedinventors’ Neopixel class.

It seems like the blob manipulation functions are really slow. Testing with a 240 pixel string (a 4m reel of 60 LED/pixel), clearFrame() takes about 500ms. Put another way, that means writePixel() takes about 2ms, which is just really slow for doing any sort of animation on long strings.

Any suggestion to speed this up? I’m thinking I might add some off-board hardware to translate from “real” SPI to the odd PWM that the WS2812s expect, and stop messing about with giant blobs entirely.

[Edit: Moved to correct category.]

I have to wonder whether the newer blob writestring functions would help here, ie changing

for (i = 0 ; i < 10; i++) frame.writen(bits[g*10 + i],'c'); for (i = 0 ; i < 10; i++) frame.writen(bits[r*10 + i],'c'); for (i = 0 ; i < 10; i++) frame.writen(bits[b*10 + i],'c');

…to…

frame.writestring(bits(bits.slice(g*10, g*10+9))); frame.writestring(bits(bits.slice(b*10, b*10+9))); frame.writestring(bits(bits.slice(r*10, r*10+9)));

…have not tried this myself, but looks worth a try.

Hi Hugo,
Just tried this but get, ERROR: attempt to call ‘string’

I think the actual code would be:
g *= 10; b *= 10; r *= 10; frame.writestring(bits.slice(g, g+10)); frame.writestring(bits.slice(b, b+10)); frame.writestring(bits.slice(r, r+10));
Peter

That’s a huge win. clearFrame() for 240 pixels went from 522ms to 112ms!

That is a pretty incredible change! We’ll get the code updated on GitHub.

It’s always a bit tricky with example code. On the one hand, it would go faster still if you inlined writePixel into clearFrame, and then hoisted the invariants out of the loop. On the other hand, that would uglify the code substantially and it’d be harder to learn from as an example.

If you’re trying to animate large chains of Neopixels as fast as possible, you’ll probably need to end up using the techniques on http://electricimp.com/docs/resources/efficientsquirrel/ which in this case would probably start off:
local fws = frame.writestring.bindenv(frame);
and then stashing the particular bits.slice() results you need in locals too.

Peter