Hi all,
I’ve got a weird problem here with the FastLED.setBrightness() call. I’m normally using Nanos to run somewhere between 100-500 LEDs. The setBrightness calls work very quickly and reliably across all of my WS2812 based RGB LEDs. Now I’m working on a larger project which runs with 1200 LEDs, so I’ve had to move to a MEGA to have enough storage for the data to be displayed on the LEDs. Using 1200 LEDs (and using the exact same code as the smaller projects with just the number of LEDs changed) I’m now running into the problem that only the first call to setBrightness() is executed. Any subsequent calls simply don’t have any effect on the LEDs. Is there perhaps an upper limit to how many LEDs fastLED is happy to support?
EDIT: I should add that I only have 2 strips of 100 LEDs each connected at the moment for testing. The blinking code which sets the entire strip brightness to 0 and back to 255 repeatedly works fine on the nano, it blinks the 200 LEDs. The same code on the MEGA only works for the first time it switches off the LEDs. They never come back on. All grounds of course are common, I’ve double and triple checked the electrical connections.
It would help if you provided the code that you were running - please post it to http://gist.github.com or paste in so we can see what you’re doing. (There’s no limit on how many LED’s FastLED can support - you’ll run out of ram on your hardware before you run into problems with FastLED - and I’ve run thousands of LED’s off of a single device)
Code is very simple (and identical across a dozen or so imlementations using Nanos where it works fine). In the loop section, there’s this:
// Turn on the LED13 for control:
if ( millis() > nextLED13switch ) {
nextLED13switch = millis() + 250;
if ( LED13 == 0 ) {
digitalWrite(13, HIGH);
FastLED.setBrightness(255);
FastLED.show();
LED13 = 1;
} else {
digitalWrite(13, LOW);
FastLED.setBrightness(0);
FastLED.show();
LED13 = 0;
}
}
This also blinks the onboard LED13 as a convenient check it runs through the code. And it does.
And what I’d want to see is the rest of your loop function as well as the setup function , etc… - again, post the whole thing to gist or pastebin.
Ok, here’s the whole thing. Simply adjust the LEDS_PER_POLE and NUM_POLES numbers if you want to hook up some LEDS yourself to test:
I asked you to put the code on http://gist.github.com or pastebin because trying to read through code in g+ comments is a pain in the ass.
Ok - so there’s a couple potential problems in this code. One is that with 1200 leds, interrupts are going to be disabled for 36ms - note that the millis timer is also incremented by interrupt. So, I think that’s happening with your setup here is that millis isn’t ever advancing, or if it is, it’s advancing very very slowly. For a test - replace the FastLED.show(); at the end of your loop function with a delay(10);
Generally speaking, you only need to call FastLED.show when you’ve actually made changes to the leds, which right now you’re only doing once every 250ms (or, it would be every 250ms if the millis timer was actually incrementing at the rate that it should be - my guess is that it’s taking 30-100 times as long for millis to advance as it does normally).
Meanwhile - it looks like the timer adjustment code that tries to account for this might have a problem - but in the meantime, trying what I suggested with swapping out the call to FastLED.show() with a delay call would be a quick test of things.
Also, what version of the arduino software are you using, and what version of FastLED?
Very sorry about the long post - I wasn’t familiar with gist, I am now, looks very useful! So I moved the code to that URL https://gist.github.com/nebukadnezar/b592bde9e399125775399b6f3711141d
Thanks very much for your comments thus far. Some replies:
So FastLED disables interrupts? That I didn’t know. I also didn’t know that the timer is incremented by an interrupt, I thought it had some kind of free running oscillator that’s bit flipping a memory segment that is interrogated by the millis() call. All very interesting to know! How do you calculate the 36ms of time needed to set 1200 LEDs?
About sending a show() on every loop: I find it generally necessary to keep sending the current colors down the strips on every loop due to interference causing random flips in the LEDs. Walk by while on the phone, or flick a light switch in the room, and the colors usually go random in one to several LEDs (out of a few hundred). That’s not really acceptable. I have a 300 Ohm resistor on the data line, it used to be much worse before that. If there are any other electronic solutions to RFI proof this setup please let me know.
I’m using FastLED 3.001.000 and the Aduino 1.6.9 dev environment. I don’t think the environment ever offered me an update to FastLED which seems odd in hindsight (it prompts me for all other installed modules). Unless of course that is indeed the latest version?
There’ve been a lot of changes to the library that are on github that you’d have to download yourself to replace the version that arduino will download/install.
Every library that writes to WS2812 style leds disables interrupts on AVR (and actually, on all platforms) - chipsets like the APA102 that have separate clock/data lines don’t need to disable the interrupts… It’s because the WS2812 has some fairly precise timing requirements that interrupts can throw off. (On arm platforms, I have enough clock cycles that between each led, i can briefly enable interrupts, then disable them again before writing out the next led’s worth of data - but that won’t happen on a mega). It takes 30µs to write out a single led’s worth of data with the WS2812 - so, with 1200 leds, it’s going to be 36,000µs, or 36ms.
Anyway - for purposes of testing whether or not your problem is being caused by interrupts not firing often enough, please replace that last FastLED.show() with a delay - just as a test.
Thanks Daniel, I’ll test that when back where I have the longer LED strips available. I just tested the code here with a single 19 LED strand and strangely, it works on the MEGA, even when “faking” 1200 LEDs. It’s noticeably slower when ramping up the brightness when claiming to have 1200 LEDs. I don’t think your library is aware of how many LEDs are actually connected, it writes to the LED strips blindly, correct? So interrupt wise, it shouldn’t matter how many LEDs are actually connected?
No, it just writes blindly to them - so, if you tell it to write to 1200 leds, it’ll write out 1200 led’s worth of data - there’s no good way to detect how many leds are connected.
This is why most folks, once they get above 100 or 200 WS2812 leds move to something like the teensy 3.2 where they can do 8 to 16 way parallel output and get something back to reasonable frame rates.
Also - when things change how they behave based on how many leds you have physically connected (with no other code changes), then I start wondering if you’re having a power problem of some sort.
So I ran some tests yesterday with the Mega and the brightness controls worked as advertised. So it suddenly works and I have no idea why. Oh well. Power should be fine - I’m running a 120W supply with 115W demand.
I bet you have a power problem. When you run a power supply at 90%+ of rated maximum, it starts to droop, unless its very fancy and expensive.