So, if I have a 32x24 neopixel matrix and it displays/animates ok with ESP32

So, if I have a 32x24 neopixel matrix and it displays/animates ok with ESP32 and teensy 3.1, but with ESP8266, I get huge display glitches (wrong LEDs being toggled, output offset by a certain amount, etc…), are there some non default ESP8266 #defines I’m supposed to set?
Am I supposed to turn off wifi or other things that make the ESP8266 mess with FastLED timing?
Currently my code does nothing with interrupts or anything else outside of shoving a bunch of data with show()
This is with FastLED from git updated today.
I’d have to check again, but I think with 16x16, i.e. 256 pixels, the glitches are a lot more rare, so it seems that the timing issues seem to stack up with the string is longer (which is understandable).

Try turning down the retry count:

#define FASTLED_INTERRUPT_RETRY_COUNT 1
#include <FastLED.h>

when interrupts are enabled, FastLED tries to figure out whether or not an interrupt has gone too long, and if it has, it re-starts the frame - if the amount of time delayed actually wasn’t high enough for the leds to reset, then the frame can “restart” in the middle - the other possibility is turning off interrupts. Also see if

#define FASTLED_ALLOW_INTERRUPTS 0

also makes the issue go away, though if it does, that mostly blocks being able to use wifi. (Writing out a 32x24 matrix is going to take 23ms – that’s a long chunk of time!)

(the RGBW rewrite is going to make it easier to tweak the timing of delays for chipsets, to account for variances there).

Thanks @Daniel_Garcia , FASTLED_INTERRUPT_RETRY_COUNT 1 did not help, but disabling interrupts did. Sadly, I’ll be needing interrupts, so maybe ESP8266 will not be the right chip for that many LEDs.
I remember from reading the code the teensy 3.1 can actually re-enable interrupts between each pixel and not have this problem. Should I assume that ESP8266 isn’t fast enough to do that?

By the way, I’ll need interrupts for infrared, not wifi, so I could turn off Wifi if that’s likely to help, and maybe IR interrupts won’t be as bad?

@Marc_MERLIN it is - and it has that code in there - but it sounds like the timing for when it decides that an interrupt has taken “too long” vs the actual reset time of the leds on the strip may be a bit off from each other. Of course, if the esp8266 interrupt handlers are poorly written and take more than, say, 50us to run, there’s not much that can be done in that case (without moving to other output mechanisms that are hardware based)

@Daniel_Garcia ok, so I’ll see how to turn off wifi on esp8266 and see if that helps, and then start turning on IR interrupts and see if things still work after that. Will report back.

@Marc_MERLIN That’s the big advantage of the ESP32 over the 8266 – two cores, plus the ability to use the RMT device – so WiFi can have its own core and interrupts

@Sam_Guyer Yeah, I have an esp32 also, I know why it’s better, but as you saw the fastled code for it is still work in progress, I found a few bugs

I can’t wait until I get the ability to tune the timeouts into the code, it should help in cases like this (unless, as I mentioned above, the interrupt handlers run longer than the led’s timeout)

@Daniel_Garcia , sadly disabling Wifi wasn’t enough to fix things :frowning: If I have no interrupt code, is there another way to disable other ESP8266 background tasks? For now, here is my diff, but that means IR will never work if I have to disable interrupts altogether.
Sadly, it may also mean that disabling interrupts on ESP8266 may be needed as a default for any string that is more than 256 or some amount.
You can look at the diff to see how I’m turning off Wifi (maybe there is another/better way?)

It’s also possible that the esp8266 timings are off by enough that it causes a problem on long strings - I don’t have any easy way to test setups right now - or alternatively, you’re being bitten by a lack of voltage regulator or voltage drop (and/or the combination of all of the above).

@Daniel_Garcia it’s not a voltage problem because the problem goes away by disabling interrupts, or switching to an ESP32 or teensy3.1.
But the timing could be off by a bit, you’re right.

Actually - looking at the code, the wait time might be way too low in there - change this line:

https://github.com/FastLED/FastLED/blob/master/platforms/esp/8266/clockless_esp8266.h#L19

make the value for WAIT_TIME be something like 50 and see if that helps - tweak the value a bit - if WAIT_TIME is set to too long, then what’ll happen is you’ll see colors for the end of the strip showing up at the beginning (because an interrupt was allowed to run for too long and the strip reset to the beginning). If WAIT_TIME is set too short, then the library’s going to abort frames too rapidly, and if it attempts a retry, instead of starting at the beginning it’ll start with whatever led the previous frame got to (because the LEDs wouldn’t have latched/reset yet)

@Daniel_Garcia well, that was a super nice call. I increased it from 5 to 20 and things work now (10 was not enough). Before that I had a glitch on regular interval every second or so.

diff --git a/platforms/esp/8266/clockless_esp8266.h b/platforms/esp/8266/clockless_esp8266.h
index 20ae641…80fe60e 100644
— a/platforms/esp/8266/clockless_esp8266.h
+++ b/platforms/esp/8266/clockless_esp8266.h
@@ -16,7 +16,7 @@ attribute ((always_inline)) inline static uint32_t __clock_cycles() {

#define FASTLED_HAS_CLOCKLESS 1

-template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 5>
+template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 20>
class ClocklessController : public CPixelLEDController<RGB_ORDER> {
typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
typedef typename FastPin<DATA_PIN>::port_t data_t;

@Daniel_Garcia , you said:
"The wait time value is actually how long an interrupt is allowed to take before we reset the frame and retry. "
So, 5 is too low, 20 is big enough for my amount of pixels but I think you’re saying that if I had an even bigger array, I’d get in trouble again
And I think you’re also saying that this value should be increased to something as high as the hardware will allow without waiting so long that the next pixel cannot be displayed in time, Correct?

Either way, I’ll let you decide/figure out what the best value is here, all I know is that 20 is high enough for my use right now, but higher may still be ok and allow even longer ISRs without breaking anything else

No - the value for wait time has nothing to do with the size of the array (other than the fact that the longer your array is, the more likely that interrupts will happen while writing out led data).

For “allowing interrupts” what FastLED does is, after writing out each pixel, gets the current value of a cycle counter/timer, turn on interrupts for a moment, then turn the interrupts back off, and reads the current value of the cycle counter/timer - it then figures out if “too much time” passed during an interrupt handling, where too much time is “a long enough period of time that the leds have reset, and the next bit of data written will go back to the first led, not to the n’th”, and if too much time has passed, it stops writing out the current frame.

WAIT_TIME defines what “too much time” is – an ideal starting value is the reset/latch time of the leds being dealt with. For WS2812’s that’s somewhere between 5 and 50µs depending on the variant/which datasheet you believe. WS2813’s have a value closer to something like 500µs.

@Daniel_Garcia aah, gotcha. So basically you should set it to something as big as your pixels will allow, but given that there are so many that claim to be WS2812B, you have no way to know how far you can push this parameter, you put the smallest safe value as per the most conservative datasheet.
So, for what it’s worth, mine seem to work ok with 50, so if there is no downside in my case and it lets me run longer interrupts, I’ll change it back to 50 then.
And now I understand why someone else was asking for this to be a config option in the led setup, or at a very least a #define you can set in your code without modifying the library itself.
Would you be ok with maybe a simple patch to make it a #define until it can be something better?

@Daniel_Garcia , so I have good news. FastLED 3.8 is working ok on ESP8266 with WAIT_TIME = 20, and 2 strips on separate ports + IRremoteESP8266
Now, I have to check whether

  1. I can have show() only update one small 48 pixel strip (updated more frequently) and not the longer one (1024 pixel matrix), because the small one updates too slowly now.
  2. whether I can get 4 port parallel output working in ESP8266 (https://github.com/FastLED/FastLED/wiki/Parallel-Output) and still get IR somehow

https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples has a section on calling individual controllers directly

@Daniel_Garcia Oh, FastLED[0|1], awesome, thanks.
Am I also correct that parallel output is automatically enabled on ESP2866 as long as I don’t have more than 4 strips and I use the required pins 12, 13, 14 and 15?