Fast efficient way to move memory

So I have a FastLED sketch on Pro Micro (ATmega32U4) controlling a WS812B strip and I'm doing chases back and forth. Currently I'm using a for loop to move the values like this:

CRGB tempColor = leds[NUM_LEDS-1];
    for (byte p = NUM_LEDS - 1; p > 0; p--)
    {
      leds[p] = leds[p-1];
    }
    leds[0] = tempColor;

and was wondering if there might be a more efficient way of doing it, perhaps using DMA or memmove function?
Another article "fastest way to move a block of RAM" sort of implies that memmove is not much better.

You will need a different processor for that.

The logical way to improve the performance of your code is remove it. Replace it with a byte variable that indicates where to start access, increment that variable when appropriate, and wrap the value when the end of the array is reached.

For bonus points correctly use a pointer during access. And avoid modulus.

How many leds are there ?
Which leds are they ? WS2812B ?

Memmove is fast, sometimes the compiler does not call the memmove() function but includes the code itself to move memory. However, that will not help.
The FastLED library uses time for the protocol to the ledstrip.

If you want a fast changing of the leds, then there are NeoPixel DMA libraries for certain boards.

There probably is, but the processing time to generate the new frame is negligible compared to time to transmit the bytes to the strip.

for ESP's mainly, to be fair, if the processing and transmission time really becomes an issue, so will memory space, and you will anyway need a different board.

To answer the question. The best would be to get FastLED read the data from a ring buffer when transmitting, but this will require a modification of the library.

If you just want the pattern to move faster you can make it skip steps, the changes are anyway faster than the eye can see. I always just re-create the pattern that i want to see, depending on the time that has passed, and not worry about skipping steps. As long as the refresh rate is higher than about 40Hz, (60Hz is better of course) you will see something that is smooth.

2 Likes

And Teensy.

C move memory

Looks like you could get a fairly fast update using a Teensy with an OctoWS2811 adapter - the OctoWS2811 LED Library claims simultaneous update of up to eight LED strips using DMA, that would update the same number of LEDs in 1/8 the time it takes for a single strip.

A ring buffer is undoubtedly the best way to do this. I would be somewhat appalled if the library doesn't support this by means of a base pointer. The same trick can be used to quickly switch buffers.

Simpler to use the Teensy WS2812 LED Library. It blasts the LED data over a hardware UART via DMA. Works as fast as the LED protocol allows. It also integrates with FastLED. So, none of the code has to change.

But, yes, there are a lot smarter way of doing what OP originally posted.

1 Like

Pretty sure it doesn't. FastLED creates an object where you pass a reference to an Array. You would have to modify the call to show() to make it start reading somewhere else, and roll over back to the beginning. Not hugely complicated in itself, but it will take some searching for the proper spot in the code to do this

@DrWizard I agree with @Deva_Rishi here. I think it may be possible to speed up the code you posted somewhat, but it will probably make very little difference overall because other parts of your sketch will be far slower, in particular the .show() which takes a fixed time for a given length of strip. The only way to speed up the animation may be to skip frames, in essence, by calling .show() a fixed number of times per second, resulting in some of the frames your code is drawing never actually being sent to the strip.

You could switch to a SPI-controlled LED strip type such as APA102 (aka Adafruit DotStar). I've clocked those at ~20MHz.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.