I just moved from an Arduino Nano to a Teensy-LC. The only thing I’ve changed in my code is the data pin. It seems that, in the code, 1 second is 3 seconds in reality. Is it expected that the timer drift will cause everything to be off by this much?
You really should post the code, ideally a complete program that can be copied into Arduino and actually run on a board to reproduce the problem.
Agreed, Paul. However it’s roughly 1800 lines and company property. I was hoping that I was missing something simple.
Maybe write a small program which demonstrates the problem.
This may sound a little blunt, but frankly your message doesn’t make any sense. It simply doesn’t have any useful info. You’re not even saying which type of LEDs you have! I do not believe anyone can help with so little info.
Valid point, Paul. I’m using 252 WS2812B’s. I’ll make an effort to put together a small program that demonstrates my issue. Thanks
Ok. Here’s some code: https://pastebin.com/KbrT0JJt
When run on an Arduino Nano, this animation takes 1 second almost exactly. On a Teensy-LC, it seems to take around 3.5 seconds.
I believe the problem is due to FastLED’s disable of interrupts. Updating a 252 LED strip takes 7.56 ms. During that update, the timer interrupt can’t happen. On AVR, FastLED has special code to poll the millis() timer. But it doesn’t do this on Teensy LC. So when your code reads millis(), the number hasn’t incremented as much as it should because FastLED had interrupts disabled.
You can try adding “#define FASTLED_ALLOW_INTERRUPTS 1” before you include FastLED.h. But this has other disadvantages, very likely causing bad LED waveforms (the reason FastLED disables interrupts by default for WS2812).
Perhaps someday the WS2811 code in FastLED will update the millis() count for more boards. But Arduino doesn’t provide any API for how to do that, which means Daniel & Mark have to implement it manually for every board. AVR is so widely used and so old that this was done years ago. Seems unlikely it’ll happen for most other boards.
Ok, I just looked at the code. Seems like Daniel & Mark have already done almost all the hard work… just need to copy a bit of the code from other platforms. Inside the FastLED folder, find platforms/arm/kl26/clockless_arm_kl26.h.
Change the showPixels() function to this:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
mWait.wait();
cli();
uint32_t clocks = showRGBInternal(pixels);
if(!clocks) {
sei(); delayMicroseconds(WAIT_TIME); cli();
clocks = showRGBInternal(pixels);
}
long microsTaken = CLKS_TO_MICROS(clocks * ((T1 + T2 + T3) * 24));
MS_COUNTER += (microsTaken / 1000);
sei();
mWait.mark();
}
Please let me know if that solves the problem for you? Is so, I’ll send it as a pull request.
Awesome Paul! Thank you. This is pretty close. I did a little timing testing and for an animation that should last 2000ms, it lasted 1890ms. Which is close enough, I think. Definitely way better.
Sorry about that - I had thought I had set things up so that the m0 code would allow interrupts to fire while writing out leds- but it appears there’s another piece that I need to do for that to work on the LC - i’ll take paul’s pull request for now - and add that to the list of things to work on when I get back to working on things.
Cool Daniel, thanks. Glad we found this. Take your time.