FastLED CLEDController Brightness, Color, and flickering

Hello - thank you for any help you can provide to my situation below!

I would like to run two strips of LEDs from a single Arduino, with independent brightness control. My understanding is that FastLED.show uses a global brightness setting and I would need to use CLEDController showLeds(); in order to have the independent brightness control. I am using the example at the very bottom of this section as a reference.

Here is what I want the first strip of LEDs to look like. This is with the global brightness and FastLED.show function:

I then want a second strip I can add elsewhere which can have a dynamic brightness... sometimes it will be a low brightness and occasionally it will flash very brightly. All the while, this 20x10 matrix will stay the same brightness just like in the picture above.

If there is a solution I am not considering, or if you have tips on how to correct this approach, please let me know! Below is more info on what I have tried and what the result is.

When I try to manage this with CLEDcontroller to prepare for multiple controllers in the future, the Brightness setting is disrupting the color of the LEDs. At a low Brightness setting, every other LED is a different color:

At a high brightness setting, the lights do not flicker or alternate, but they are much too bright. And if I use .setCorrection(CRGB(x,y,z); to dim them to the brightness I want, they go back to the flickering and alternating pattern above.

Here is the individual controller code:

#include <FastLED.h>
// SID LED intialization
#define NUM_LEDS 200 // How many leds are in the strip?
#define SID_DATA_PIN 7
#define CLOCK_PIN 13 // not needed?
#define BRIGHTNESS 255
#define GREEN 255,50,50   //this board does color in GRB, not RGB
#define YELLOW 103,255,30 //this board does color in GRB, not RGB
#define RED 23,255,0      //this board does color in GRB, not RGB
int rows;
int columnArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int ledMatrix[10][20] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
  {39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
  {79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
  {119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100},
  {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139},
  {159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140},
  {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179},
  {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180}
};
CRGB SIDleds[NUM_LEDS];
CRGB Secondleds[10];
void setup() {
  FastLED.addLeds<WS2811, SID_DATA_PIN, RGB>(SIDleds, NUM_LEDS).setCorrection(CRGB(10,15,10));
  FastLED.addLeds<WS2811, 8, RGB>(Secondleds, 1);
  FastLED.addLeds<WS2811, 6, RGB>(Thirdleds, 1);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 500);
  FastLED.clear();
  FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
    rows = 19;
    for (int x = 0; x < 10; x++) {
      for (int y = 0; y < 13; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(GREEN);
      }
    }
    for (int x = 0; x < 10; x++) {
      for (int y = 13; y < 19; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(YELLOW);
      }
    }
    for (int x = 0; x < 10; x++) {
      for (int y = rows; y < rows + 1; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(RED);
      }
    }
    FastLED[0].showLeds(BRIGHTNESS);
}

And here is the original code which has the desired behavior, but would not allow me to add a new LED string with its own brightness:

#include <FastLED.h>
// SID LED intialization
#define NUM_LEDS 200 // How many leds are in the strip?
#define SID_DATA_PIN 7
#define CLOCK_PIN 13 // not needed?
#define BRIGHTNESS 5
#define GREEN 255,50,50   //this board does color in GRB, not RGB
#define YELLOW 103,255,30 //this board does color in GRB, not RGB
#define RED 23,255,0      //this board does color in GRB, not RGB
int rows;
int columnArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int arrayPosition = 0;
int ledMatrix[10][20] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
  {39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
  {79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
  {119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100},
  {120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139},
  {159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140},
  {160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179},
  {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180}
};
CRGB SIDleds[NUM_LEDS];
void setup() {
 FastLED.addLeds<WS2811, SID_DATA_PIN, RGB>(SIDleds, NUM_LEDS);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 500);
  FastLED.clear();
  FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
    rows = 19;
    for (int x = 0; x < 10; x++) {
      for (int y = 0; y < 13; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(GREEN);
      }
    }
    for (int x = 0; x < 10; x++) {
      for (int y = 13; y < 19; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(YELLOW);
      }
    }
    for (int x = 0; x < 10; x++) {
      for (int y = rows; y < rows + 1; y++) {
        SIDleds[ledMatrix[x][y]] = CRGB(RED);
      }
    }
    FastLED.show();
}

What sort of Arduino do you have?
Not many have enough memory to handle 400 LEDs. Each LED needs 3 bytes to store the data.

The brightness controls act as a scaling factor, both the FastLed and adaFruit libraries have a brightness control.

This array

Is unnecessary as you can simply calculate the LED number on a serpentine raster.

Thanks Grumpy_Mike!

What sort of Arduino do you have?
Not many have enough memory to handle 400 LEDs. Each LED needs 3 bytes to store the data.

I am using a Mega. Yes, I originally had a Nano or Uno running the 200 LEDs and I kind of overdid it with variables (I am new to coding) and it was hitting some memory issues. With the Mega it appears I will be fine.

My second strip is going to be much smaller, probably on the order of 30 LEDs or so. Interestingly, they will be all the same color and that will be white or a white-blue. So I am wondering if I can use FastLED.show() and global brightness for the 20x10 Green-Yellow-Red matrix, and FastLED.showLeds(brightness) for the second string of 30 that I want to brighten up and I'm less concerned about the colors.

This array is unnecessary as you can simply calculate the LED number on a serpentine raster.

I treat it as 10 indepenedent columns of 20 and have the lights go up and down like a spectrum analyzer, so I thought this made sense as a way to clean up the code and make it easier to do what I wanted. It was still a huge pain but I learned a little bit about arrays and matrices which I had never heard of before, so that was good :slight_smile:

Yes a Mega should have enough memory.

First of all the documentation for the Fast Led library is large and somewhat complex. It has a lot of features and can be overwhelming for a beginner.
Fast LED Documentation

Personally I much prefer the AdaFruit library as it is simpler to understand.

If these are in effect two separate strips with there own data output pin then they will have their own show method, if you make two instances of the library.
Note that there is a new version of FastLED out version 3.0 and this adds lots of new features.

If you are new consider the advice on this page that tells you what you loose when writing to LED strips. This is more of a problem the longer the strips are.
Interrupt problems

So you can calculate the LED number in the matrix for a given X- Y coordinate on the display by using this function:-

int getPixPos(int x, int y){ // for a serpentine raster
   int pos;
   if(x &0x1) {
      pos = x * yMax + (yMax -1 - y) ;
   } else {
   pos = x * yMax + y;
   } 
   return pos;
}

where xMax and yMax are global variables giving the number of LEDs in each direction.

as long as you use less then 256 LEDs you could use an uint8_t for your matrix and save a ton of memory:

uint8_t ledMatrix[10][20]

but as already mentioned you should calculated the current matrix anyway.

Thank you - that is clever! I never would have thought of it that way. For a matrix much larger than mine, that would definitely make sense.

Thank you! I did find a few tips there, namely:

  • removing the max milliamps and volts, in case it was causing issues (it doesn't seem to have been though)
  • trying a different pin on my Mega, though I am using v3.5 so maybe this isn't a concern (and it didn't change any behavior when I tried it so I guess not)
  • using random8() rather than random() which might have saved a bit of memory
  • updating my use of "int" throughout my code to uint8_t where I could

I didn't realize the int --> uint8_t savings would be 200x for my 20x10 matrix but I guess it makes sense in hindsight! Indeed this plus some other variable optimization dropped me from 16,362 bytes of code to 15,414, and from 1,818 bytes of dynamic memory down to 1,589. I am still well below the limits of the Mega but still feels nice to do things better!

That was an interesting read. That might explain some of the issues I described in this thread when I was trying to run a bunch of stuff with individual Arduinos and Serial communication. It was suggested I consolidate into one, which was a pain but I learned a lot about cycling through a program to do things pseudo-simultaneously.

Right now I have

FastLED.addLeds<WS2811, SID_DATA_PIN, RGB>(SIDleds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);

Are you saying with two strings, I would have:

FastLED.addLeds<WS2811, SID_DATA_PIN, RGB>(SIDleds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
FastLED2.addLeds<WS2811, DATA_PIN2, RGB>(Secondleds, NUM_LEDS2);
FastLED2.setBrightness(BRIGHTNESS2);

If so, I think that would fully resolve my issue!

Here is what I have working:

FastLED.addLeds<WS2811, SID_DATA_PIN, RGB>(SIDleds, NUM_LEDS);
FastLED2 .addLeds<WS2811, DATA_PIN2 , RGB>(SECONDleds, NUM_LEDS2 );
FastLED.setBrightness(BRIGHTNESS);

The BRIGHTNESS parameter is my "normal" scenario and applies to all FastLED.show(); statements.

If I want to increase the brightness for strip 2 only, I just use FastLED.showLeds(255); instead. Normally I think I would need to do some kind of color correction or something else, but because the second strip is always white (255,255,255), there doesn't seem to be any issues.

Thanks, I did work that out myself, I haven't seen anyone else do that.

Yes. I have done this many times with the AdaFruit library which I tend to use mainly, but it should work for the FastLED library as well. give it a try. If not exactly that syntax then there should be something in the document and examples to do this.

I don't know what you mean here. The Mega is a 5V system with 5V systems. What is 3V3, the power to the strip?

The two string lines works for setup, but having two BRIGHTNESS parameters does not seem to work with FastLED.show();. I can't find anything about this in the documentation, other than using the CLEDController stuff which results in the flickering and different colors in my first picture above.

That was in reference to this page of the documentation which used to say:

On the Arduino Megas, you can't use pins 6,7,8,9,14,15,16,17,42,43,44,45,46,47,48,49,62,63,64,65,66,67,68,69 with 3-wire chipsets. This is because the timing for accessing PORT H-L is more expensive than the other ports, and it throws all the timing off.

I thought this might be the source of my CLEDController color issues, because I am using a Mega and coincidentally I was originally using pin 9. But I am using Version 3.5 of the library and it sounds like:

fixed on the FastLED 3.1 branch now

I also moved this to pin 10 just to be totally safe, and was still seeing the CLEDController color and flickering issues in my Green/Yellow/Red 20x10 matrix. But now I am controlling that with FastLED.show(); which works perfectly of course, and controlling my second strip with CLEDController's FastLED.showLeds(brightness); because I only want the second strip to be either white or off and there are no color issues with that.

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