Go Down

Topic: How do you dynamically change the number of active LEDs for Fast LED ? (Read 312 times) previous topic - next topic

thedubdude

My application requires that I re-define the number of LEDs after I've compiled and uploaded the code to the Arduino Uno. At present, the Fast LED library seems to require you to define the number of LEDs with a "define" statement:

(example) #define NUM_LEDS 484

However, because the WS2811 LEDs operate in series, the frame rate is set by the number of LEDs. I need to be able to change the frame rate on the fly by effectively decreasing the number of LEDs in the #define statement ... but I don't see anyway to do this while the Arduino is running. Does anyone know how to do this?

Thanks in advance for your help.

PaulRB

I need to be able to change the frame rate on the fly by effectively decreasing the number of LEDs in the #define statement ...
Sounds like entirely the wrong approach! Can you please explain what you are really trying to do? Are you really connecting strips of different numbers of LEDs on the fly? Or is the strip fixed but you want to change the site speed of animation?

thedubdude

Thanks for replying. The strips are fixed and I want to change the site speed of the animation. BTW, I can observe the greatly improve frame rate when I reduce the number of LEDs in the #define NUM_LEDS statement.

PaulRB

"site speed" was a typo. Meant to say "frame speed", sorry.

Are you setting NUM_LEDS to more than the actual number of LEDs in your strip? If not, the result of setting NUM_LEDS to less than the actual number of LEDs is that you won't get the pattern you actually wanted!

Post your code (using code tags as suggested in the forum guidelines in the sticky post) and tell us how many leds are in your strip and we will suggest what is possible.

lesept

Indeed, it woud be easier to help if you explain your application.

Supposing you have 1 strip with 100 leds and you want to light 50 leds only in one case and 75 in another case and 100 in the last case, you just need to play with the addresses  of the leds you want to light up in each case.

The speed is always too high for you to see any difference between 50 or 100 lit leds. So I don't see why you would need to change that speed, nor to change the max number of leds.

Just define the maximum number of leds (100 in my example) and light up only the leds you want lit.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Grumpy_Mike

Quote
I need to be able to change the frame rate on the fly by effectively decreasing the number of LEDs in the #define statement .
In the C language you can't change the size of an array at run time. What you could do is to define an array that would be the largest you would ever need. Then hack the library code so you can change the number that the show method uses.

thedubdude

I am looking at high speed animations with a moving strip. At times I want more LEDs with a slower FRAME rate and at others I need a super fast frame rate with fewer LEDs. My strip is 484 LEDs long and at times I just want 22 active and at others I want 242 active...but I want the frame rate to increase with fewer LEDs .... which it does if I define NUM_LED=22 . Just turning off the non-active LEDs does not increase the FRAME rate...reducing the number of LEDs does... the RESET to the panel occurs much sooner with less LEDs. I need to be able to control the FRAME rate/# of active LEDs on the fly. Thanks for your help.

Grumpy_Mike

If you use the Adafruit libiary then there is a note in the Adafruit_NeoPixel.cpp file which says:-
Code: [Select]
// via Michael Vogt/neophob: empty constructor is used when strand length
// isn't known at compile-time; situations where program config might be
// read from internal flash memory or an SD card, or arrive via serial
// command.  If using this constructor, MUST follow up with updateType(),
// updateLength(), etc. to establish the strand type, length and pin number!
Adafruit_NeoPixel::Adafruit_NeoPixel() :

PaulRB

I am looking at high speed animations with a moving strip.
Sounds like you are trying to make some kind of pov display? The problem with that will not only be the frame rate, the PWM frequency will also be a problem, it is only a few hundred Hz. For pov you need KHz.

What frame rate do you want to achieve with 22 LEDs and 242 LEDs? Do you realise you will be limited to using the first 22 or 242 LEDs in the strip, and that the other LEDs will not be black/off? The other LEDs will show previous frames.

In theory you should be able to achieve 30+ frames per second with 484 LEDs.

lesept

If the 22 LEDs are always the same ones, you can simply declare 2 strips, the first with those 22 adn the second one with the remaining 242.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

thedubdude

Please keep in mind I effectively only have one LED strand and one DATA_PIN.  The first 22 LEDs are the same LEDs I want access to when I wish to display either 22 LEDs or 242 LEDs.


I tried a number of things to no avail... I tried

void setup() {
   FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, 242);
   FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, 22);
}

 // I then tried lighting all 242 LEDs with:
FastLED[0].showLeds();

//  only 22 LEDs light

//////////////////////////////////////////////////////////////////////////////////////////////////////////


Next I tried defining two controllers:

#define NUM_LEDS 242
#define NUM_STRIPS 2
CRGB leds[NUM_LEDS];
CLEDController *controllers[NUM_STRIPS];

void setup()
{
        controllers[0] = &FastLED.addLeds<WS2811, DATA_PIN>(leds, 242);
   controllers[1] = &FastLED.addLeds<WS2811, DATA_PIN>(leds, 22);
}

// I then tried lighting all 242 LEDs with:
controllers[0]->showLeds(128);

// Only 22 LEDs light but controller 0 has 242 LEDs...likely because both controllers have the same
// data pin and controller[1] was setup last. In fact if I tried swapping controllers 0 and 1,
// such that controller 1 had 242  LEDs and then:
// controllers[1]->showLeds(128);  does in fact light the 242 LEDs.

// As an experiment I tried assigning each controller a separate data pin and this does in fact work in that I
// can  light the number of LEDs (with the FRAME rate that corresponds to that number of LEDs) based on the
// controller I choose.....The only problem is that I have but one string of LEDs with only 1 data pin. So to
// take implement this scheme I would need to add hardware to switch my one
// panel data input pin between two Arduino data pins to allow me to
// change from driving 22 LEDs to 242 LEDs.



/////////////////////////////////////////////////////////////////////////////////////////////////////


The idea of defining multiple STRIPs of different lengths won't work as the FastLED.show(); shows all STRIPs defined. There is no command to light just STRIP 1 or 0 independently. Once again both strips have the same DATA PIN and are in fact the same STRIP. 


thedubdude

So I was able to achieve my goal by creating a second DATA pin for the LED string and tying it to the original DATA pin. At any given time only one of the DATA pins is an active output while the other is an input. One of the data pins is defined to for a controller with 242 LEDs and the other has 22:

   controllers[0] = &FastLED.addLeds<WS2811, DATA_PIN1>(leds, 242);
   controllers[1] = &FastLED.addLeds<WS2811, DATA_PIN2>(leds, 22);

When I want to display 22 LEDs at a fast FRAME rate I make DATA_PIN1 an input and DATA_PIN2 an output. Then to show the LEDs I execute:  controllers[1]->showLeds(128);

This method works well.

Thanks all for your inputs.



Go Up