FastLED | Change LED number at run time

Hello,

I’m trying to change the number of LEDs at runtime (not if leds running, but without reset).

This is my code for now, but it doesn’t work:

oldLEDCount = led amount before change
ledcount = led amount after change
first = first time this code runs
all_leds = CRGB array

  if(oldLEDCount > 0 && ledcount == 0 && !first) {
    free(ALL_LEDS);
  } else

  if(oldLEDCount != ledcount && !first) {
    ALL_LEDS = (CRGB*)realloc(ALL_LEDS, sizeof(CRGB) * ledcount);
  } else

  if(first || (oldLEDCount == 0 && ledcount > 0)) {
    ALL_LEDS = (CRGB*)malloc(sizeof(CRGB) * ledcount);
  }

  if(ledcount == 0)
  {
    return;
  }
  
  memset(ALL_LEDS, 0, sizeof(CRGB) * ledcount);

  if(INIT) {
    FastLED.addLeds<LED_TYPE, LED_PIN, LED_ORDER>(ALL_LEDS, ledcount).setCorrection(LED_STRIPTYPE);
    INIT = false;
  }
  
  FastLED.clear();
  FastLED.show();

Any idea if it’s possible to do that OR what is wrong in my code?

Does it compile?

Post your entire sketch. Tell us what it is supposed to do. Tell what it is actually doing. A wiring diagram might help.

nflug:
Hello,

I'm trying to change the number of LEDs at runtime (not if leds running, but without reset).

Why bother? If you ever have room for the LEDs, you'll always have room. Just use a maximum number, then talk to as many as actually exist. Or talk to non-existent LEDs. Doesn't matter. As long as there is memory devoted to them.

I routinely hook up a few LEDs on a little test strip to check programs designed for many more. No problems.

I am missing something, tell me.

a7

aarg:
Does it compile?

Yes

ToddL1962:
Post your entire sketch. Tell us what it is supposed to do. Tell what it is actually doing. A wiring diagram might help.

It's to big & complicated to post. This is just the important part.

alto777:
Why bother? If you ever have room for the LEDs, you'll always have room. Just use a maximum number, then talk to as many as actually exist. Or talk to non-existent LEDs. Doesn't matter. As long as there is memory devoted to them.

I routinely hook up a few LEDs on a little test strip to check programs designed for many more. No problems.

I am missing something, tell me.

a7

I will try that. Thanks.

alto777:
Why bother? If you ever have room for the LEDs, you'll always have room. Just use a maximum number, then talk to as many as actually exist. Or talk to non-existent LEDs. Doesn't matter. As long as there is memory devoted to them.

I routinely hook up a few LEDs on a little test strip to check programs designed for many more. No problems.

I am missing something, tell me.

a7

Set the limit to 2000leds. I run an app where the user can define how much strips he has e.g (144, 60, 30 per strip).

Works perfectly with your solution. Thanks!!!

alto777:
Why bother? If you ever have room for the LEDs, you'll always have room. Just use a maximum number, then talk to as many as actually exist. Or talk to non-existent LEDs. Doesn't matter. As long as there is memory devoted to them.

I routinely hook up a few LEDs on a little test strip to check programs designed for many more. No problems.

I am missing something, tell me.

a7

Ok what I see now is that FastLED or my controller (ESP32) can't handle that amount. Animations are flickering and are like 20fps & slow, I tried it with 1000 leds, still not good. Any idea?

If it isn't fast enough with the maximum that you plan to use, you have a different, more fundamental problem. Try it with that maximum, not an arbitrary number like 1000.

aarg:
If it isn't fast enough with the maximum that you plan to use, you have a different, more fundamental problem. Try it with that maximum, not an arbitrary number like 1000.

Probleme here is that there is not "Maximum" because it is for some customers & they can define by themself how much led strips they have (for that the maximum is 2000leds). Do you know an alternative to ESP32 with more SRAM but at the same price level (I prefer AliExpress, ESP32 is there around for $3-5) .

Because the data is sequential, the time it takes to update a strip is linearly related to the number of LEDs. It isn't a code problem, it's how the LEDs work. The only real solution is to run separate strips from multiple pins. Those customers that ask for 2000 LEDs don't know that, so they will blame you.

You haven't provided sufficient information.

What type of LEDs? The timing requirements of the WS2812-type and similar are fixed. So, that makes the update time for the entire strip fixed and proportional to the number of LEDs. Nothing you can do about that.

You could try a faster, SPI-based type (i.e. APA102). I've successfully clocked those above 20 MHz.

Or, maybe your code needs to be more efficient. But, can't tell because you didn't post it.

Maybe you can use DMA and ping-pong buffers to update the animation at the same time the previous frame is being clocked out.

I don't know much about ESP32, but I understand some versions have dual cores. Maybe you can take advantage of that.

However, given that this appears to be a commercial project, if you need help with it, I think you should be paying someone for that help rather than trying to get it for free from a hobbyist forum.

If your animations are amenable, another possibility is to run parallel strips.

If your patterns are only 50 LEDs long, e.g., you feed the same signal to 10 strips (500 LEDs). The strips are lined up end-to-end physically but not wiring one to the next.

Many chasing patterns repeat this way. Obvsly if every pixel needs its own color, like a raster showing a picture, you are running up against hard limits around what you can do with limited resources.

a7

Yes I’m using the WS2812B strips. Right now 2 strips a 144leds.
But the max. should be 2000leds.

I used the example FastLED code to test. With 144leds it’s running smooth. But if I go over 300leds it starts getting really slow. Tried it with 2000, than it is just flickering.

#include <FastLED.h>

#define NUM_LEDS 2000
#define NUM_LEDS_REAL 288

CRGB leds[NUM_LEDS];

void setup() { 
	Serial.begin(57600);
	FastLED.addLeds<WS2812B,4,GRB>(leds,NUM_LEDS);
	FastLED.setBrightness(75);
}

void fadeall() { 
  for(int i = 0; i < NUM_LEDS_REAL; i++) { 
    leds[i].nscale8(250); 
  } 
}

void loop() { 
	static uint8_t hue = 0;
	for(int i = 0; i < NUM_LEDS_REAL; i++) {
		leds[i] = CHSV(hue++, 255, 255);
		FastLED.show(); 
		leds[i] = CRGB::Black;
		fadeall();
		FastLED.delay(10);
	}

	for(int i = (NUM_LEDS_REAL)-1; i >= 0; i--) {
		leds[i] = CHSV(hue++, 255, 255);
		FastLED.show();
		leds[i] = CRGB::Black;
		fadeall();
		FastLED.delay(10);
	}
}

All of the 3 posts before your reply, explain in different words why it's not fast enough. Perhaps it would be a good idea to go over all of them and find one that clicks with you.

aarg:
All of the 3 posts before your reply, explain in different words why it's not fast enough. Perhaps it would be a good idea to go over all of them and find one that clicks with you.

They are not different.

I have an ESP32 and want to light 2000 leds (WS2812B)

But it should be user configurable. That means the user can say how much strips he want to add.
The max. for that should be 2000leds, regardless of what strip (eg. 144, 60, 30)

For testing I used the code above. First with 288 leds (2 strips a 144 leds). Everything runs fine.
Then I increased the value of the array (not the strips) to 500. It starts getting slow. Increased it again to 2000. Animations is not running smooth anymore.

nflug:
They are not different.

I have an ESP32 and want to light 2000 leds (WS2812B)

But it should be user configurable. That means the user can say how much strips he want to add.
The max. for that should be 2000leds, regardless of what strip (eg. 144, 60, 30)

For testing I used the code above. First with 288 leds (2 strips a 144 leds). Everything runs fine.
Then I increased the value of the array (not the strips) to 500. It starts getting slow. Increased it again to 2000. Animations is not running smooth anymore.

Yes, because (again), the strip itself slows down in proportion to the number of LEDs.

aarg:
Yes, because (again), the strip itself slows down in proportion to the number of LEDs.

I have a friend who uses the esp32 with over 5000 LEDs and he doesn't have this behavior. I asked him already about my code. He said I should use a loop with a yield instead of the standard loop. I also tried that but it didn't work. So it is possible to do that without loss of speed.

According to some Adafruit Neopixel documentation:

NeoPixels receive data from a fixed-frequency 800 KHz datastream (except for “V1” Flora pixels, which use 400 KHz). Each bit of data therefore requires 1/800,000 sec — 1.25 microseconds. One pixel requires 24 bits (8 bits each for red, green blue) — 30 microseconds. After the last pixel’s worth of data is issued, the stream must stop for at least 50 microseconds for the new colors to “latch.”

For a strip of 100 pixels, that’s (100 * 30) + 50, or 3,050 microseconds. 1,000,000 / 3,050 = 328 updates per second, approximately.

So 3.05 mS * 2000/100 = 61mS. Refresh rate will then be 1/61ms = 16.4 Hz

aarg:
According to some Adafruit Neopixel documentation:

So 3.05 mS * 2000/100 = 61mS. Refresh rate will then be 1/61ms = 16.4 Hz

I understand that. But what I don't get is why it is not working with just 288leds and a CRGB array of 2000. It must be an issue with the code / performance. I even tried it with the dual core. Somehow this array size slows down. What I also tried now was to split the array into 4 pieces but nothing changed.

(Only the array size is 2000, the animations are running for 288 leds)

nflug:
I understand that. But what I don't get is why it is not working with just 288leds and a CRGB array of 2000. It must be an issue with the code / performance. I even tried it with the dual core. Somehow this array size slows down. What I also tried now was to split the array into 4 pieces but nothing changed.

When you specify an array size, that information can not be communicated to the strip. Also the strip can not communicate the actual number of LEDs to the processor. All the data is shifted out regardless of what is actually connected to it.