How to have a dynamic number of LEDs depending on config with FastLED?

I have a few different strings of LEDs that I use with a given script, and they each have a different number of LEDs and color order. I'm wondering if there's a way to change their configs dynamically in setup()?

I know NUM_LEDS wants a const int. Is there some way to redefine that?

Here's an example:



#include "FastLED.h"

//#define NUM_LEDS    750
const int NUM_LEDS = 750;

#define LED_TYPE    WS2811

//#define BRIGHTNESS 255  
const int BRIGHTNESS = 255;

#define COLOR_ORDER RGB //RGB
#define LED_PIN 23

CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(115200);  
  Serial.println("Starting up...");

  int config_num=1;

  if (config_num==1) {
    const int NUM_LEDS = 32;      
    CRGB leds[NUM_LEDS];

    const int BRIGHTNESS = 20;
    
    // how to change COLOR_ORDER to "GRB"?
    
    // how to change LED_TYPE?
  }

  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();

  Serial.print("Set the brightness to: ");
  Serial.println(BRIGHTNESS); // this prints 255

}

void loop() {

  fill_solid(leds, NUM_LEDS, CRGB::Red);
  FastLED.show();
  delay(200);

  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
  delay(200);
  
  fill_solid(leds, NUM_LEDS, CRGB::Blue);
  FastLED.show();
  delay(200);
  
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  FastLED.show();
  delay(1000);

}

Can anyone think of a way to adjust the NUM_LEDS based on a configuration?

Do you want to change the value of NUM_LEDS at compile time or at run time ?

Which Arduino board are you using ?

Good question. I'd like to change it at compile time, based on a variable I'm setting.

Ideally inside setup(), but I guess an ifdef could work.

Why not simply change the value of NUM_LEDS ?

Sorry I forgot to mention, using ESP32's.

And the reason I want to do it in setup is that I have a bunch of different ESP32's runniny my script, and I'm trying to set the number of LEDs and color order based on the particular ESP32's Mac address.

So if (macaddy == "this_one") NUM_LEDS=64;

And of course I can change the value of NUM_LEDs manually at the top of my file each time, but I'm trying to figure out a way to have the number of LEDs vary based on which esp32 this is running on (as determined by the Mac addy).

If there's an easy way to change the NUM_LEDS in setup(), I don't know it yet.

I have not tried this, but could you set NUM_LEDS to the maximum number of LEDs that you will use and use it in

CRGB leds[NUM_LEDS];

but use a smaller number in functions such as fill_solid() ?

Don't use a constant NUM_LEDS (either const or #define) when you add the leds. Use something like


const uint16_t NUM_LEDS = 750;
CRGB leds[NUM_LEDS];

uint16_t number_of_leds;
void setup()
{
  if(myMax == someMac)
    number_of_leds=33;
  else if(myMax == someOtherMac)
    number_of_leds=750;
  else
    number_of_leds =123;

  if(number_of_leds) > NUM_LEDS)
  {
    Serial.println(F("FAIL"));
    // hang forever
    for(;;);

  }


  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, number_of_leds).setCorrection( TypicalLEDStrip );
}

Yeah, if the code is otherwise the same between units, there will always be room for the maximum buffer size, you can just allocate the maximum and only use a portion of it. But if not, your idea of using preprocessor commands is definitely feasible. Take your pick.

Then that's run time, not compile time. The idea of underutilizing the largest needed array would work. But you could also create the correct-sized array dynamically:

#include "Arduino.h"
#include <FastLED.h>
#include <WiFi.h>
#define LED_TYPE    WS2811

using macAddress = uint8_t[6];
const size_t macSize = sizeof(macAddress);

struct MacNumLeds {
	const macAddress mac;
	const uint16_t numLeds;
};

MacNumLeds macLedPairs[] = {
		{ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, 50},
		{ {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}, 12},
		{ {0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11}, 25},
		{ {0x30, 0xAE, 0xA4, 0x1B, 0x58, 0x74}, 30}
};

CRGB *leds = nullptr;
uint16_t numLeds = 0;

void setup() {
	Serial.begin(115200);
	delay(1000);

	macAddress myMac;
	WiFi.macAddress(myMac);
	log_i("Station MAC Address: %s", WiFi.macAddress().c_str());

	for (auto &pair : macLedPairs) {
		if (memcmp(myMac, pair.mac, macSize) == 0) {
			numLeds = pair.numLeds;
			log_i("Mactched MAC Address, Led Count: %d", numLeds);
			leds = new (std::nothrow) CRGB[numLeds];
		}
	}

	if (numLeds == 0) {
		log_e("Could Not Match MAC Address. Aborting.");
		ESP.restart();
	}
	if (leds == nullptr) {
		log_e("Could Not Allocate Memeory for LED Array. Aborting.");
		ESP.restart();
	} else {
		log_i("LED Array Allocated");
	}

}

void loop() {
}

The Color Order is a little trickier. Since it's a template parameter, it must be specified at compile time:

#include "Arduino.h"
#include <FastLED.h>
#include <WiFi.h>
#define LED_TYPE WS2811
#define LED_PIN 23

using macAddress = uint8_t[6];
const size_t macSize = sizeof(macAddress);

struct MacNumLeds {
	const macAddress mac;
	const uint16_t numLeds;
	const EOrder colorOrder;
};

MacNumLeds macLedPairs[] = {
		{ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, 50, RGB},
		{ {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}, 12, BGR},
		{ {0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11}, 25, GRB},
		{ {0x30, 0xAE, 0xA4, 0x1B, 0x58, 0x74}, 30, GBR}
};

CRGB *leds = nullptr;
uint16_t numLeds = 0;

void setup() {
	Serial.begin(115200);
	delay(1000);

	macAddress myMac;
	WiFi.macAddress(myMac);
	EOrder order;
	log_i("Station MAC Address: %s", WiFi.macAddress().c_str());

	for (auto &pair : macLedPairs) {
		if (memcmp(myMac, pair.mac, macSize) == 0) {
			numLeds = pair.numLeds;
			order = pair.colorOrder;
			log_i("Mactched MAC Address, Led Count: %d", numLeds);
			leds = new (std::nothrow) CRGB[numLeds];
		}
	}

	if (numLeds == 0) {
		log_e("Could Not Match MAC Address. Aborting.");
		ESP.restart();
	}
	if (leds == nullptr) {
		log_e("Could Not Allocate Memeory for LED Array. Aborting.");
		ESP.restart();
	} else {
		log_i("LED Array Allocated");
	}

	switch (order) {
		case RGB:
			FastLED.addLeds<LED_TYPE, LED_PIN, RGB>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;
		case RBG:
			FastLED.addLeds<LED_TYPE, LED_PIN, RBG>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;
		case GRB:
			FastLED.addLeds<LED_TYPE, LED_PIN, GRB>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;
		case GBR:
			FastLED.addLeds<LED_TYPE, LED_PIN, GBR>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;
		case BRG:
			FastLED.addLeds<LED_TYPE, LED_PIN, BRG>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;
		case BGR:
			FastLED.addLeds<LED_TYPE, LED_PIN, BGR>(leds, numLeds).setCorrection(TypicalLEDStrip);
			break;

		default:
			log_e("Unknown Color Order. Aborting.");
			ESP.restart();
	}
}

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