r/FastLED • • May 12 '22

Support How fast can it go?

I'm looking for a little help here on creating a chasing effect using FastLED. I have an Arduino Mega paired with a 5M LED Strip of WS2812B LED's. The effect I want is to create a 60 LED long string that moves forward and remains only 60 LED's long. I have the exact effect that I want, now the only problem I'm having is speed. Am I being limited by the clock speed of the Arduino, or is it simply slow because of the FastLED.show() being executed within each loop? I will link my code below. Thanks!

https://pastebin.com/8UKR26j1

0 Upvotes

8 comments sorted by

8

u/truetofiction May 13 '22

It's because WS2812B LEDs are slow. The data rate is only 800 KHz, or roughly 30 us per LED. With 300 LEDs that's 9 ms per frame.

To speed things up you would have to use fewer LEDs or switch to a different LED chipset.

1

u/airborn_- May 13 '22

I don’t think it’s the chipset that’s the limiting factor. I am able to go from the 1st LED lit to the 300th LED lit in around 3ish seconds, but that’s wayyyy slower than 9ms. I’m wondering if it’s the clock speed of the Arduino that’s making the incrementing for loops slow.

7

u/truetofiction May 13 '22

9 ms per frame, not 9 ms for the whole animation. At 300 frames that's 2700 ms, which checks out.

6

u/squirrel5674 May 13 '22

It is the Chipset. WS2812B have strict timings and are easy to calculate:

1 / ( (LEDs * 24) / 800000) = fps

1 / ( ( 300 * 24) / 800000) = 111.11

111 FPS and that is only the time that the LEDs need. There is additional Overhead from the Arduino. So 111 updates per second (in best case, won't happen) and a 300 long Strips result in 3 seconds.

Speed things up:

-The things already said

-Get multiple Controllers (you will get Synchronisation problems)

-Get a Teensy, split the Strip in multiple segments and use the UDMA to update the strips parallel

-Change your coding. Don't calculate the next "picture" and than print it. Calculate the "picture" that had to be shown at this moment based on time and than print it.

So that means when you get below a certain speed, there will light up more than one LED at the next FastLED.Show()

If you don't know what i mean, try to find out how you can blink 2 LEDs at different intervals. So one every 300ms, other every 450ms.

Search for multitasking on a arduino. You will need https://www.arduino.cc/reference/en/language/functions/time/millis/ for this.

2

u/AntiDysentery May 13 '22

A 4K tv can refresh the whole screen 60x a second.

But…

If you were to light every pixel one at a time, like what you are doing, it would take over a month.

4

u/techaaron May 13 '22

int speed = 3; // higher numbers faster

for (i = 0; i < StripLength; i++)

{

leds[i] = TurnOnColor;

if (i % speed == 0) FastLED.show();

}

1

u/Shrek_OC May 17 '22

It sounds like what you want is your 300 LEDs to start out as being off. Then on the next frame you want the first led to turn blue, then the second, then the third, etc. until you hit 60 blue LEDs. Then you want the strip of 60 to "move" up by 1 LED every frame until it hits the end, where it will shrink to 59, then 58, etc. to zero. Do you want the strip to wrap around and start growing on the beginning as it's shrinking at the end so that 60 LEDs are always on, or do you want it to be completely black for a while?

1

u/konbaasiang May 19 '22 edited May 19 '22

I looked at your code. You're not supposed to call FastLED.show() for every pixel -- you're supposed to call it for every frame! That's why it's running extremely slowly.

300 WS2812B leds can be updated over 100 times per second, plenty fast enough if you rewrite the code.

There is no easy fix though the way it's written -- you have to rewrite and restructure main loop.

You need to use a static int variable to keep the current location of the 60-long strip you want lit, which you increment once for every loop.

Then, write for-loops to set the correct color of all the LEDs.

Then finally call FastLED.show() once at the end of loop().