FastLED / FastLED

The FastLED library for colored LED animation on Arduino. Please direct questions/requests for help to the FastLED Reddit community: http://fastled.io/r We'd like to use github "issues" just for tracking library bugs / enhancements.

Home Page:http://fastled.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

74 LED WS2812B strip is flickering when connected to ESP8266 with Wi-Fi enabled

krzychb opened this issue Β· comments

I have been testing Fire2012.ino sketch with latest FastLED library (saved directly from GitHub) using WS2812B strip with 74 and 144 LEDs together with ESP8266.

Fire2012.ino works as expected when Wi-Fi of ESP8266 is off.
If Wi-Fi is on, the strip is flickering 😞

Has anybody tested ESP8266 in similar scenario? Do I miss something in configuration?
ESP8266 is all about Wi-Fi and I would like to set Fire2012 parameters (brightness, cooling and sparking) wirelessly.

I do not observe flickering for Fire2012.ino sketch when implemented with Adafruit_NeoPixel and NeoPixelBus libraries.

Here are my test sketches:
β€’ EspNeoPixelBus
β€’ EspAdafruit_NeoPixel
β€’ EspFastLED

I really appreciate mature, feature rich and well documented code of FastLED and looking how to use it directly with ESP8266 without patching it with additional code.

Krzysztof

Try adding FastLED.delay(1000 / FRAMES_PER_SECOND); under this line https://github.com/krzychb/EspFire2012/blob/master/EspFastLED/Fire.ino#L109 instead of doing manual delay via millis.

@msurguy the problem with that is it then blocks the handling of wifi responses in a timely fashion.

@krzychb - what happens if you add #define FASTLED_ALLOW_INTERRUPTS 0 to the line immediately before you have #include <FastLED.h> - FastLED is different from the other libraries in that it allows interrupts to fire while processing WS2812 leds - however, if an interrupt takes too long to run, then it has to stop writing out the current flame.

Out of curiosity - where are you seeing flickering - is it at the beginning of the strip, the end of the strip, or across the entire strip?

(Note: I just ran an installation using esp8266's with 150 led tm1809 (similar timing issues as ws2812) with wifi on with no problems - and i was using wifi as both a heartbeat sync and to broadcast OSC data to nearly a dozen esp8266's).

Thanks, @focalintent!

Sure enough, adding #define FASTLED_ALLOW_INTERRUPTS 0 resolved the issue πŸ˜„ πŸ‘
Flickering occurred towards the end of the strip - plese see this video

Thank you again for quick help πŸ‘

Krzysztof

Seems like same issue as i had. Just a heads up. Not allowing interrupts will result in watchdog resets. On my project, roughly 1 reset every 5-10 minutes.

Ok - yeah, what's happening here is the interrupts firing are cutting off the writing out of the frame data.

If you're hitting watchdog resets, grab the latest version of the code and try re-allowing interrupts - I did some timing adjustments on the retries (and upped the number of retry attempts).

@Lightning303,

I just run about 100 min testing of Fire2012 on ESP8266 with simple web server enabled (to set up fire simulation parameters) using latest FastLED code from GitHub - 1b546b3

I am happy to confirm that I do not see any watchdog resets.

@krzychb You might want to let it run over night to be on the safe side, i had wdt resets after about 12 to 36 hours with bitbanging and wifi but haven't tried the latest version yet.

I will definitely give the latest changes a try when i find some time. However you have to take into consideration that there might be a difference between having a webserver idling and a project where there is constant traffic. In mine i send 8 byte packages to my esp 24-60 times a second.

@TheAustrian
This is very good point πŸ˜„
I have just set up a channel on ThingSpeak to monitor EspFastLed up time
Let's see if it will cut the mustard.

@Lightning303
My application is simple.
The more code and traffic, the more effort is required for successful debugging and stress testing.
I believe you will soon nail down the issue and identify the root cause!
Good luck πŸ‘

I just tested the latest github and it looks like the interupts are causing flickering for me.
My setup is im sending artnet to the ESP8266 (huzzah).
if i do a RGB walk over the leds:
interupts enabled = the leds behind the one lighting up flicker. so as the RGB walk runs the flickers get less as the walk gets to the end.
interupts disabled = no flicker, im yield()'ing right before and after FastLED.show() was running for an hour will test some more. And only calling show() when there is actually new LED info. (640 Leds configured)

Ohh forgot to wrote im using WS2812B leds.. also without interupts it reset on me :( .
with interupts on i noticed if making fat white/black bars, it flickers white bars the same size down the line. nut zust random colors.
if i set #define FASTLED_INTERRUPT_RETRY_COUNT 0
the flicker is gone.

As suggested by @TheAustrian I let the ESP8266 run over night and got the following result:

image

Time to do some troubleshooting πŸ˜„

I run first round of testing of the three applications described in original issue report loading each of them on a separate ESP8266 module.

Test started on 29-May-2015 at about 11:00 CET and took about 30 hours. Each application was posting it's Up Time and free Heap Size to Emoncms.org. In case of self reset the Up Time is automatically reset to zero.

espfire2012_20150529

The number or self resets over the test period is summarized below:

EspFire 2012 Application Number of Self Resets
EspFastLED 4
EspNeoPixelBus 0
EspAdafruit_NeoPixel 1

The cause of resets may be s/w, h/w or both. To eliminate h/w as the source of issue, I will move the s/w around using the same three modules in sequence below.

EspFire2012 Application Test 1 Test 2 Test 3
EspFastLED ESP A ESP C ESP B
EspNeoPixelBus ESP B ESP A ESP C
EspAdafruit_NeoPixel ESP C ESP B ESP A

Later today I will stop Test 1 and move to Test 2.

Any comments are welcome.

Krzysztof

Is that with interrupts enabled or disabled?

Actually, I might have an idea of what's going on (if this is happening with interrupts enabled) - I think the resets might be getting caused by the clock count register rolling over - if it doesn't roll over at 32 bits, but instead at something lower, some of the math that I use for timing would result in really long spins.

I can see about putting some extra guards in around that when I get home tomorrow.

@focalintent,

I have disabled interrupts to avoid strip flickering:

#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h>

Thank you for review of his issue.
Resets every 500 minutes or so for my application is not a problem.
My concern is if they are due to s/w or my h/w is faulty or power supply not adequate.

I have moved the s/w around between modules after 22:00 (10:00 p.m.) CET yesterday as visible (reset of Up Time to zero) on chart below.
image
This was to eliminate h/w as potential source of module resets.
Unfortunately the issue with resets persists for EspFastLED and EspAdafruit_NeoPixel applications.
Also, as during previous test, EspNeoPixelBus did not suffer any resets at all.

This indicated to me potential issue with s/w. Therefore I attempted to compare code of all three libraries looking for differences how low level control of WS2812B is implemented.
I understand that FastLED (and Adafruit_NeoPixel) is using bit banging s/w control for ESP8266.
NeoPixelBus is using I2S DMA (as configured in my sketch) or UART, so pulse timing is done by silicon instead of s/w and interrupts.

Is my understanding correct that control of WS2812B by FastLED for ESP8266 is done using bit banging? Is there UART or DMA method implemented by FastLED for ESP8266?

I will keep this test running for another 12 hours or so and then do third swap of modules. If anybody is interested, the charts are available on-line under https://emoncms.org/dashboard/view?id=29419.

Any comments are welcome.

It is done by bit banging - and I have no plans to support the dma/usart style unless I can get it to cover all the three wire chips FastLED supports - but I do know what's causing your resets and should hopefully have a fix today or tomorrow.

Thanks, @focalintent.
Controlling of WS2812B fully by s/w, cutting in between Wi-Fi routines, is kind of acrobatics out of my reach πŸ‘
I will be happy to set up a "cluster" of couple of ESP8266's to do quicker testing πŸ˜„
Krzysztof

@krzychb grab the latest master@HEAD - this should get rid of your every 500 minute or so restarts :)

@focalintent can't wait to test the changes once I am back home today afternoon.
Guessing your local time I see why "just say no to mornings... " :)
Thank you for your time helping me out with this issue.
Krzysztof

Update:
I have configured two ESP8266 modules that run Fire2012 with the latest 96704ee.
Application up time and heap size monitoring - https://emoncms.org/dashboard/view?id=29419.
Summary of previous three rounds of tests - https://github.com/krzychb/EspFire2012#stability

I have loaded two ESP modules with latest commit 96704ee – ESP B used in previous testing, and a brand new ESP E. I have also reloaded EspNeoPixelBus application to ESP D - another brand new module.

The testing started at 20:40 CET on 2-Jun-2016 and took about 2100 minutes. The summary of results is below.

EspFire 2012 Application Number of Self Resets Module
EspFastLED_1 0 ESP B
EspFastLED_2 1 + 2 by manually cycling power ESP E (new)
EspNeoPixelBus 0 ESP D (new)
EspAdafruit_NeoPixel 3 ESP C

The new module ESP E behaved suspiciously. It stopped posting data on Emoncms.org and I had to reset it manually two times. It used on average about 2kB more flash than ESP B loaded with identical application. I decided to remove it from testing.

espfire2012_20150604

The good news is the EspFastLED_1 application on module ESP B run without any resets throughout the whole test. With previous version of FastLED librarry application restarted on average 3 times during such period.

All modules are now restarted by cycling power and testing continues. Previously tested ESP A module is brought back to testing instead of suspicious ESP E.

To be continued… πŸ˜„

To drive correctly a led strip in an ESP8266 board you need to use a hardware module. NeoPixelBus can use the I2S or UART1 modules. UART1 has a 128 bytes buffer, enough to store about 11 pixels. This gives enough time to the WiFi interrupt handler to keep the thing running. I2S uses Direct Memory Access so every pixel is written out asynchronously. I also contributed to NeoPixelBus an async mode for UART1, which uses interrupts to feed the UART1 asynchronously so the CPU can compute the next frame while the hardware module does its job.

You don't need to - I have multiple projects that are using esp8266's with WS2812 style leds without using hardware - partly because, for me, parallel output is more important (and parallel output + shorter strips + interrupt's being enabled allows FastLED to work with this - I need to clean up the parallel output a bit more, then I should be able to publish that for everyone to use).

I can reliably drive an 800 led strip with NeoPixelBus and output 30 frames per second. 2 parallel outputs is fine: you can put the ESP8266 in the middle of a led strip. But I see no point for more than 2 parallel outputs for two reasons:

  • ESP8266 modules only have 9 usable GPIO pins and, usually, you want to connect some extra hardware to it (a button, a proximity sensor, an ambient light sensor...)
  • You need extra point-to-point cables

PD: I just want to point you towards a solution. I don't want to start a flamewar.

@krzychb Great information there. Could you include tests for using the NeoEsp8266BitBangMethod with the NeoPixelBus in the loop? This would provide a direct comparison with the others (Adafruit was based on the original NeoPixelBus bitbang work).

And note, I moved away from bitbang due to locking the interrupts would cause intermittent exception in the wifi core that I was told directly from company to avoid; and without them wifi traffic can cause a malformed pulse train (seen as flickering).

Thank you for all the comments, good discussion and interesting information.

Below is quick β€œexecutive summary” πŸ˜„ and update on test progress:

  1. H/w: four ESP8266 NodeMCU 1.0 modules, WS2812B strip with 144 LEDs connected to GPIO3
  2. S/w: Fire2012 application running at 60 frames/s with FastLED, Adafruit_NeoPixel and NeoPixelBus libraries.
  3. Six test runs done so far, each for about 2000 min / 33 h, total testing time of about 8 days
  4. Application s/w is loaded to next module in the row for each test run to probe for h/w as a potential source of issues
  5. EspNeoPixelBus was the only application that that survived all six test runs without any issues.
  6. EspAdafruit_NeoPixel and EspFastLED experienced self-resets on average 1 time per 10 hours.
  7. Commit 96704ee unfortunately did not help to eliminate self-resets

test_update

If you are interested, please see live results and check on technical details:

I feel like I have tested all the s/w almost to death. To bring some fresh facts to the discussion, now I am planning to use methodology proposed by @igrr and implemented by @djoele here to capture and save the stack trace for post mortem analysis where exactly each application fails.

Any comments are welcome.

@Makuma,
This is good idea to test NeoEsp8266BitBangMethod πŸ‘
I am planning to implement it later in the afternoon CET time.

Krzysztof

Update: I have just configured new ESP8266 module using NeoPixelBus library with NeoEsp8266BitBang800KbpsMethod and sending feed "EspNeoPixelBusBB Up Time"- http://emoncms.org/dashboard/view&id=29419

@krzychb Are you running your 8266's at 80 or 160mhz?

@focalintent,
Currently I am running all 8266's at 80MHz

@krzychb can you run a slight variation for me? Comment out the #define FASTLED_ALLOW_INTERRUPTS 0 line you have in Fire.h - yes, you'll get flickering (I'm setting up a tst rig now to try to see if I have any more room to control for that) - but I want to verify that it's the disabling interrupts for 4.3ms at a time that's tripping up your device.

@focalintent β€” disabling interrupts for 4.3ms is way too long. For a busy WiFi network the stack can tolerate 20-50 microseconds at most. SDK API guide recommends not to disable interrupts for more than 10 microseconds (page 14).
@krzychb β€” another thing regarding stack traces: you will likely not get any. If an assertion is triggered in WiFi code which runs from level 1 interrupt, device will lock up and go into hardware WDT reset after a few seconds. Exception handler will not be called.

@igrr I know that, which is why I asked him to comment out that line - that re-allows interrupts being handled roughly every 30Β΅s (I have some local bug fixes that take care of some end of strip flickering issues people were seeing with interrupts enabled).

@krzychb I've got a version of your fire code running here (with some extra local diagnostic information in the web page that gets served up) that has interrupts enabled (which should take care of the random resets you were seeing) and also takes care of the end-of strip flickering. I basically have to hit loading the webpage 10-20/s in a continual while loop for it to effect the end of the strip, and even then it seems to only have the effect of bringing the apparent frame rate down a little bit (but still north of 10fps).

I'm going to let this run overnight here and see what kind of uptime i get with it, and if it all looks good, i'll check in these changes in the morning.

@igrr - now I need to look for another user case to try out exception handler πŸ˜„ Thank you for supporting this discussion.

@focalintent - I will then wait for you checking in the changes in the morning. I will be happy to test out the test variations you recommend.

11 hours runtime overnight - I've commented out the #define FASTLED_ALLOW_INTERRUPTS 0 line in your code for this run. I'm going to leave it running all day as well to be sure (then I need to pull the hardware off into some other work in about another 8 or so hours).

Now back to RGBW related work.

Below is configuration I have just loaded using FastLED commit 7a6a223.
Suggestions by @focalintent and @Makuna above are included and modules swapped between.

EspFire2012 Application Functionality Module
EspNeoPixelBus Neo800KbpsMethod ESP F
EspAdafruit_NeoPixel n/a ESP A
EspFastLED #define FASTLED_ALLOW_INTERRUPTS 0 ESP B
EspFastLED_1 // #define FASTLED_ALLOW_INTERRUPTS 0 ESP D
EspNeoPixelBusBB NeoEsp8266BitBang800KbpsMethod ESP C

Live data log - http://emoncms.org/dashboard/view&id=29419.

@krzychb it appears there was an initial reset but after that seems like the library has been holding up pretty well so far? Thanks for the graphs!

@msurguy,
I am happy to see you watching this this endurance run with me πŸ˜„
After over 1500 min run time now, out of the five players above, the following two are holding tight (did not experience any resets):

EspFire2012 Application Functionality Module
EspNeoPixelBus Neo800KbpsMethod ESP F
EspFastLED_1 // #define FASTLED_ALLOW_INTERRUPTS 0 ESP D

I am planning to reset all of them and swap modules in about 11 hours, after they exceed 2000 min run time as in previous tests.

@krzychb I forgot to ask this, but does your test sketch include WiFi activity? The more WiFi activity, the higher chance of interference with bit banging. This was something that caused early investigation issue for flickering.

@Makuna,

Yes, my test sketch includes WiFi activity.

ESP8266 is all about Wi-Fi and I would like to set Fire2012 parameters (brightness, cooling and sparking) wirelessly. Transmitting of small packets of data (application up time and heap size) to Emoncms.org once per minute is a way to test what particular library can handle.

Basing on test results so far, statement by @igrr above, as well as according to your documentation to NeoEsp8266BitBang800KbpsMethod, it is clear that bit bang method for ESP8266 driving 144 WS2812B NeoPixels with Fire2012 application will not cut the mustard without occasional wdt resets.

Depending on particular application occasional wdt resets may not be a big deal. If they are, then the solution is using library like yours that supports I2S DMA method (or likely UART but not tested here).

Krzysztof

@krzychb By default on Esp8266 with my library, the I2S DMA method is used, you have to specify either uart or bitgang to use these other methods.

Thanks, @Makuna - I have corrected text above.
This also explains bigger consumption of heap reported by EspNeoPixelBus as opposed to EspNeoPixelBusBB.

@focalintent - I feel like this tread is getting too long and I should wrap up this testing.
Thank you for support with this issue and hosting discussion about testing of two other LED libraries.

@krzychb is there anymore insight into FastLED stability?

@msurguy here is summary for last test that I just stopped after 10 days of run time:

EspFire2012 Application Functionality Number of Self Resets
EspFastLED #define FASTLED_ALLOW_INTERRUPTS 0 22
EspFastLED_1 // #define FASTLED_ALLOW_INTERRUPTS 0 0

Both application control WS2812B strip with 144 LEDs connected to GPIO3 of ESP8266.

With disabled interrupts (EspFastLED), Fire2012 simulation runs smoothly but ESP module self-resets on random basis (on average 2 times a day).

If interrupts are enabled (EspFastLED_1) then there are no self-resets at all but Fire2012 simulation is flickering towards end of the strip.

I am planning to provide more detailed update of testing in couple of days in EspFire2012 repository.

In last test run I am going to add OTA to provide automatic scheduled distribution of application to 5 test modules and verify if they deliver 60 frames/s.

The flickering at the end of the strip is caused by an interrupt taking too long and forcing FastLED to abandon writing the frame - FastLED can attempt to retry a frame if it detects that it was interrupted - you can control how many times it attempts to retry by adding:

#define FASTLED_INTERRUPT_RETRY_COUNT 3

before the include of FastLED.h. I had it at 2 and wasn't seeing any flickering when running fire on an active wifi network across 180 leds with a test rig last week.

I can also see about extending the time before FastLED will treat an interrupt gap as being "too long" - though in my experience, going much above 5Β΅s caused problems.

Also - this is a problem you can mitigate somewhat by running at 160Mhz. At 80Mhz, an interrupt has 400 cycles to do its thing before it causes a problem for writing out WS2812 data. At 160Mhz, that same interrupt has 800 cycles - increases the odds that the interrupt handling will fit in the gap.

(And really, if an interrupt handler is taking 400 cycles to do anything then it is a very poorly written interrupt handler and should be fixed - interrupt handlers should move as little data as possible, and set flags - heavy lifting should be done outside of the interrupt handler).

Are you still seeing flickering on the most recent FastLED@master with 144 leds? I wasn't with 180.

Hi @focalintent,

I hope not to distract you with this issue as I understand you are in the middle of big overhaul of FastLED. I will keep quiet here unless asked for specific update.

I just did testing with:

  1. Latest FastLED library a3641f0
  2. EspFastLED_1 - posted on GitHub for reference
  3. esp8266 / Arduino core stable 2.2.0 as well as staging 2.3.0-rc2
  4. CPU speed 80MHz and 160MHz
  5. WS2812B strip with 144 LEDs as on picture below

I am still seeing flickering with:

#define FASTLED_ESP8266_RAW_PIN_ORDER
// #define FASTLED_ALLOW_INTERRUPTS 0
#define FASTLED_INTERRUPT_RETRY_COUNT 3
#include <FastLED.h>

Flickering is gone with:

#define FASTLED_ESP8266_RAW_PIN_ORDER
#define FASTLED_ALLOW_INTERRUPTS 0
// #define FASTLED_INTERRUPT_RETRY_COUNT 3
#include <FastLED.h>

img_0682

I know that flickering goes away when you disable interrupts, what I'm interested in is trying to tune things so that when interrupts are enabled I can recover from the frame writing being interrupted by bad interrupt handlers. (Also curious why you're seeing flickering in your setup and I wasn't here).

In https://github.com/FastLED/FastLED/blob/master/platforms/esp/8266/clockless_esp8266.h - if you get a chance, try adjusting the time for WAIT_TIME - currently set at 5us - that's how long of a gap that is allowed for interrupts. If interrupts take longer than that value, then the frame writing is cut off (which causes the LEDs at the end of the strip to be updated at a much slower rate) - if you set that value too high, however, you run this risk of causing flickering at the front of your strip (as the chips will reset and led data meant for LEDs near the end of the strip will instead be picked up by the LEDs at the beginning).

@focalintent,

I will then focus on scenario with interrupts enabled by tuning the following variables:

  • CPU speed 80 MHz or 160 MHz
  • WAIT_TIME around default 5us
  • FASTLED_INTERRUPT_RETRY_COUNT 1 or 2 or 3 or 4

Now I thinking how to measure flickering other than by looking at it that may be subjective.
Will tracking of _retry_cnt and _frame_cnt over the run-time be the way to go?

Update: finally I have good news:

  • Setting WAIT_TIME = 9 us and CPU speed = 160 MHz removed flickering.
  • I still need to test how this affect stability of application over time.
  • So far I was unable to identify WAIT_TIME that would work with CPU speed = 80 MHz and not causing flickering.
  • I believe that any single retry (that can be monitored with _retry_cnt) is visible as a single flicker of the strip.

I have set up a test rig with five NodeMCU 1.0 modules each one with different WAIT_TIME ranging from 8 to 16us. Number of retries per minute (using _retry_cnt) when writing a frame recorded so far is shown below:

image
It is clearly visible that number of retries is decreasing if WAIT_TIME is extended. I will leave this set up working as before to check how different WAIT_TIME is affecting stability of EspFire2012 application.

Full set of on-line charts for motioning of other variables is available on Emoncms.org as before.

@focalintent @krzychb
I will start by saying I am nowhere near as knowledgeable on this as you guys. I'm a self taught coder, and I have a limited grasp on the h/w and s/w relationships (do's and don't do's, etc). I edited clockless_esp8266.h as mentioned by @focalintent in his last post and kept getting flickering until I incremented the WAIT_TIME up to 18us (also I set FASTLED_INTERRUPT_RETRY_COUNT to 3).

My setup is described in the readme here: https://github.com/russp81/LEDLAMP_FASTLEDs/blob/master/README.md

If you guys are up for duplicating the setup, or just offering your observation from what you can see I would greatly appreciate it! This is a great learning opportunity for me, as I'm just now starting to get into the h/w and s/w interactions, any pointers or wisdom you guys can share would be awesome. For instance, what is bad about having WAIT_TIME = 18 us? It seems to be running great (to the naked eye).

Thanks!!

Thanks @krzychb for the scientific analysis on the flickering issue. I just wanted to tell that I came to the same conclusion using the information you provided in this thread.

As soon as you use Wifi features on the ESP8266, the WS2812 will start to flicker. Using the #define FASTLED_ALLOW_INTERRUPTS 0 workaround will however cause the board to make unpredictable resets (according to the serial output these resets are invoked by the watchdog). The NeoPixel library will work fine, with the small restriction that you won't be able to use Serial input anymore, since GPIO3 is the same pin as RXD0.

I ended up replacing just the output procedure by the NeoPixel library, since the FastLED has some pretty cool and easy features for animation.
So starting from a working FastLED-based code, just alter the parts from something like this

void setup() {

  // ...

  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
  
  // ...

  FastLED.show();
  FastLED.delay(1000/FRAMES_PER_SECOND);
}

to

#include <NeoPixelBus.h>
NeoPixelBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod> strip(NUM_LEDS);

// ...

void setup() {

  // ...

  strip.Begin();
  strip.Show(); // Set to black (^= off) after reset
}

void loop() {
  
  // ...

  static uint32_t fireTimer;
  if (millis() > fireTimer + 1000 / FRAMES_PER_SECOND)
  {
    fireTimer = millis();

    RgbColor pixel;
    for (int i = 0; i < NUM_LEDS; i++)
    {
      pixel = RgbColor(leds[i].r, leds[i].g, leds[i].b);
      strip.SetPixelColor(i, pixel);
    }
    strip.Show();
  }
}

assuming you defined the leds array like this CRGB leds[NUM_LEDS];

dersimn can you please explain more in detail how you did this mashup of both libraries...Can you maybe make a repository with best parts of both libraries :D.

So what is the consensus here, resets or flickering in any case or how?

Another side-effect of disabling the interrupts is that the "Smart Config" doesn't work anymore. Smart Config allows sending wifi essid/password from the app to ESP8266 to allow it connecting to the wifi.
wifi.beginSmartConfig()

Very useful thread. I'll add my anecdotal data...
β€’ Using Wemos D1 Mini (8266's at 80mhz) boards
β€’ Using FastLED (whose api I like very much! thank you!)
β€’ FastLED 3.1.3 release
β€’ using #define FASTLED_ALLOW_INTERRUPTS 0
β€’ Project One has 24 LEDs, runs well, but resets every few hours (casual observation)
β€’ Project Two has 300 LEDs. Sometimes the second half (or so) of the LED strip will lock up while animation continues on the first 140 or so LEDs. Often will "come back" after a while.
β€’ Project Two's web API works reliably from laptop (Safari or Chrome browser), but intermittently from iPhone. Sometimes many retries/reloads are needed before it "locks in". (again, casual observation)

Any insights appreciated! Hope the anecdotal info is handy for others to see.

Hi, has there been any improvements in the meanwhile? Could this problem be solved by replacing an ESP8266 with an ESP32?

For what it's worth, I've added DMA support for ESP8266 on my own fork of FastLED:
https://github.com/coryking/FastLED

I've been using it for a week now on three of my lighting projects. One is a 300 light ws2812b strip, another is a 160 light rgbw sk6812 strip. All have been buttery smooth after switching to DMA. Way better than the big-banging method. The one drawback is you are forced to use GPIO pin 3 (aka the "RX" pin on a lot of dev boards).

If you pull down my repo, to use the DMA you'll just:
#define FASTLED_ESP8266_DMA

Also note that while I haven't tried, I'm 99% sure this won't work with FastLED's multiple strip feature...

PS: The fork also has support for RGBW strips and actually makes use of the White LED (only esp8266 though). For RGBW, you'll have to:
#define FASTLED_RGBW

commented

@coryking im unable to light up at all my 5 led WS2811 strip with your fork.
i installed it right into Arduino IDE removing the official FastLED

if i just comment out //#define FASTLED_ESP8266_DMA it works just like before

maybe its because im not using a 3v3 <-> 5v level shifter? but should it matter on a strip so short?

and yes, im using pin 3:

#define FASTLED_ESP8266_DMA
#define FASTLED_ALLOW_INTERRUPTS 0
#define FASTLED_INTERNAL
#include "FastLED.h"
/*********************************** FastLED Defintions ********************************/
#define NUM_LEDS    5
#define DATA_PIN    3
//#define CLOCK_PIN 5
#define CHIPSET     WS2811
#define COLOR_ORDER BRG

edit: compilers seems to imply RGBW controller even if i havent defined FASTLED_RGBW.


 #    pragma message "Using RGBW controller as per FASTLED_RGBW define"

maybe that's the culprit?

commented

I kinda doubt it is a level-shift issue....

Yeah same. tried it this morting on a 5m (98 IC) strip with a level shifter and had the same result.
What u mean timing? i seem to be unable to even light up my strip on the blink example. if i even mention #define FASTLED_ESP8266_DMA

i got a "workbench" set-up with a 5 led strip attached if you wanna take a guess...

commented

Turns out, i was using D3 and not RX afterall...

buttery-smooth. great work.

Hi guys - if someone is still visiting this thread...
My conclusion after many hours wasting precious time is that ESP8266 is not suitable for driving large WS8212 strips. What I finally did was I use Glediator protocol instead.
For those who are not familiar with Glediator, it is communicating over serial TTL logic. It starts with sending a 0x1 byte followed by red, green, blue byte for pixel 0, red, green, blue byte for pixel 1, etc. I added ten introduction bytes of 0x4 in front of this sequence to ensure some sync activity on the line. That way the starting 0x1 is easier to detect. So I attach a plain always reliable 5V Arduino mini for under $3 (so I do not need the level conversion) to my LED-matrix panel and run on it a trivial driver sketch translating Glediator protocol to WS8212. The ESP8266 is connected to the Arduino with serial cable from TX1 on ESP8266 to RX on Arduino. With the baudrate 1000000 I can easily control 32 x 16 = 512 pixels. (Remember the WS8266 control pulses are 800 kHz). By this I am also free from the risky hassle with electrical connections to LED-strips, jeopardizing both the strips and the ESP8266 output. This solution is so robust that I wish all of you struggling with FastLED or Adafruit_NeoPixel, NeoPixelBus library or whatever on ESP8266 good luck. My theory is, that Expressif has totally underestimated the possibility to run anything time-consuming and time-sensitive (like FastLED.show) without interruption. Their interrupt routines are far too long in time to be suitable as interrupt routines. The LED stripes need a very customized communication, that was obviously not tested by Expressif. On the other hand, serial communication is so well standardized, so that they would hardly dare to introduce any instability or unreliability in it. And it is not time critical. The serial sequence of one frame can be interrupted. First, when the whole frame is transferred, the Arduino sends it to the LED-matrix. People, who play with LED-matrices use the Glediator or Jinx! with Glediator protocol anyhow, so they might appreciate the same connection from the PC or the ESP8266. The only thing you need to do is replacing FastLED.show with something like @dersimn suggested on Nov 27, 2016

void ShowAsGlediator(bool doit) {
  static uint32_t fireTimer;
  if ((millis() > fireTimer + 1000 / FRAMES_PER_SECOND) || doit)
  {
    fireTimer = millis();

// dummy prefix for synchronisation
    for (int i = 0; i < 10; i++)
      Serial1.write(4);

// start byte          
    Serial1.write(1);
    
    for (int i = 0; i < NUM_LEDS; i++)
    {
      Serial1.write(leds[i].r);
      Serial1.write(leds[i].g);
      Serial1.write(leds[i].b);
    }
  } 
}

do not forget to initialize
Serial1.begin(1000000);
in the setup()

The doit parameter is there for bypassing the fireTimer. If you use this show-function for a sequence of animation, it is not critical to skip some frame, so you can send false as a parameter. But if you for ex. need to clear the matrix with one command, send true as a parameter.

If you declare the function prototype
void ShowAsGlediator(bool doit=false);
before the setup() you can skip the false parameter and call just
ShowAsGlediator();

Sorry wiseguys for this newbie talk :-)

This is very interesting! I will have to try that out for sure. I had so much trouble to make all my different test LED strips display patterns correctly. I was thinking about off-loading the uC <-> LED strip communication to a simple Arduino but then again it adds to the hardware and requires two firmwares etc. etc. ... anyway, sounds great what you've written. :-)

Hi @andgeno. Good to know someone is listening :-)
My journey started when I played with Glediator and tried to replace the Arduino Uno based WS8212 driver with ESP-01 (to save money !!!) I had never "enjoyed" so much frustration, as with this. It was just about conversion from serial to HIGH-LOW pulses!!! I suspected the WS8212 for their sensitivity, I tested condensators, resistors, pull-ups, level converters. and God knows what. I had no idea, that ESP-01 ambition is to handle probably 128 bytes serial buffer in one interrupt call - how stupid that might sound. Then I tried to use more sophisticated ESP8266 and ended up with ESP-32. None of them worked reliably for me. And from reading this thread - not for anyone else. And there were even scientifical analyses of random reboots etc. Hallelujah!
The most sophisticated of my projects was to use both cores in ESP-32 (one for WiFi server and the other for LED sequences). But the Arduino mini driver is the most reliable solution of them all.
With the Arduino IDE there is no trouble having two firmwares. The Arduino hardware driver is just there, attached to the LED-matrix, so you can forget it. You will never need to reprogram it unless you rebuild your LED-matrix. And it will gladly use the 5V power from the LED-matrix (with a 1000uF/6V capacitor over the terminals).

@tonys0 Glad you kept messing with it and thank you for sharing what worked for you. Good stuff.

Hi @marmilicious, "messing" is the right word for it. No documentation on ESP8266 circuit and firmware and no documentation on WS8212 real schematics and electrical specifications. And if exists, it does not make sense (except maybe for some Chinese of course). To this, I must add usual Murphys law (secretly broken jumpers, missing groundings, things suddenly starting/stopping to work just by connecting the osciloscope probe, the GND level shift with USB - serial device etc.) The most frustrating thing was, that when it sometimes worked with one sketch it did not with another. I could never rely on it.
It is, of course, a little mess to have to add an extra custom routine with a few pre-requisites instead of FastLED.show, but it's worth it. Maybe some "nice guys" will eventually wrap it in a small Glediator library, because I am not that GIT-clever. After all, the pulse control of WS8212 is designed for short wires, while the serial (RS232) is for long wires (start, stop and parity bit if you want) which could be handy setting up a real control scenario for LED-matrix. Sooner or later you will need to connect your PC to it and run a real thing generated by a powerful CPU.

By the way - has someone here tested the ESPixelStick ???

I am going to just clear up a general comment made here. Esp8266 is able to sustain a solid signal for ws2812 (compatible) but you must use hardware features to do so; just like on the esp32 (and a lot of ARM chips as well). The issue for esp8266 is that there are only two hardware methods, i2s and uart, and each is tied to specific pins (there is no pin muxer); giving you a total of only three channels (i2s, uart0 an uart1) possible if you give up on serial support completely. NeoPixelBus supports all these as asynchronous sends.

The number of LEDs is a memory and time constraint (the comm protocol takes time to send thus long strips will have lower update frequency).

The FastLEds use of RMT hardware on esp32 allows it to split the update across multiple bus and increase the update frequency.

And yes, having long lead wires between the uC and the first LED can be a problem, especially on a 3.3v uC when the LED expects a 5v signal.

Hi Michael @Makuna.
You should only know, how much I tried to use the NeoPixelBus library of yours - a genious work. But I gave up upon that too - and so did many others - there are followers with other libraries. Why would so many people struggle with different approaches to solve such a simple issue, if it was reliable from the beginning? It should be implemented in the FastLED and Adafruit NeoPixel long time ago.

But I am really happy to have the opportunity to get in touch with you, great man. Can you suggest to me, how do I solve the conversion from Glediator protocol (USB serial) to the WS8212B with an ESP-01 ? Where do I find the document saying that the DMA is not on ESP-01 ? Can I use the TX1 for UART1 output (IO2) method while using RXD for serial input? What do you mean by "asynchronous UART" method opposed to "normal UART" method? Isn't UART asynchronous by definition?
When using ESP-32 two cores. Both cores use the same I/O HW right? How are the interrupts treated? Will one core take care of the interrupts, while the other works uninterrupted? Why do I have to make the core 0 busy with some dummy I/O to prevent reboot?
Sorry for all these questions, that may not belong right here. I was just caught by the chance to ask you.

Can anyone reopen this "Closed" thread, since it is obviously visited and the issue is not solved ?

For what it's worth I have done multiple installations with ESP8266's and ~150 WS2812 leds using wifi for communication/synchronization and no flickering issues (I almost always use level shifters, and power injection and such) -- including one that had ~32 esp8266's sharing a wifi network for synchronization/communication - and this is with using the stock FastLED software - so this isn't a constant issue - and I think it's an issue of wider hardware/software/wiring/power/etc... and beyond the scope of a FastLED issue to be fixed at just the library level.

That said - where I see people run into major problems is where they are effectively using FastLED as a frame buffer, where they are pushing full frames of LED data over wireless or serial (or less frequently, ethernet) - and this is decidedly a mode of use that is not a priority for FastLED development - my focus and interest has almost always been for on-device generation of animation and LED data (in my own installations, I use wifi for sync and command and control - I'm not slinging full frames around). For situations where folks just want a frame buffer that's driven by computer, there are dedicated solutions that are designed just for that (pixel pusher, fade candy), and I will admit that it is not a style of use I've ever prioritized for FastLED.

Hi Daniel @focalintent and welcome to the closed thread.
150 LEDs is hardly a decent matrix. If you don't send frames, then you probably have them recorded on SD card as notoriously repeating ads or some other dead content. I am using a 32 x 16 matrix and I want to build another one just for more space for complex graphics. My interest for LEDs started with watching LED-cubes, but I soon realized that no matter how big (read: expensive) cube I build, I would want bigger. So I built it in VR in Unity with the size (LED count) as a parameter. And yes, I can roll the cube in 3D space while running the light show in it.
Later I was impressed by the people doing this: https://www.youtube.com/watch?v=E8Ecz_sntDo and I was curious, how could so many elements be individually controlled with almost no wires. The intelligent LED-stripes with one-wire control was the answer.
Recently I am impressed by the Glediator and Jinx! software (Jinx! for the possibility to create images and effects with its simple script language). Unfortunately, both seem to be abandonware today. I really want to play with the light show effects and not spend long nights tweaking the hardware to work without flickering.
You see, I don't know much, so I am trying to find my way experimenting by myself and listening to other peoples problems. And on this thread, you can see quite a few of them. When the uC is randomly rebooting, it is a disaster that I cannot accept. You don't want to have randomly rebooting webs, do you? I am not going to make statistics on reboots and be happy, when they are only twice a night. That would be probably acceptable in China. But I want things to work and rely on them, so I can sleep.
With that said - I am going to use the Glediator protocol until the day someone tells me there is a reliable (and cheap enough) device programmable in Arduino IDE for WS8212 control.

If you don't send frames, then you probably have them recorded on SD card as notoriously repeating ads or some other dead content.

Wrong, on so many accounts. Everything I build runs dynamically generated and responsive animations on MCU. If I'm using the wifi connection for anything, it's for synchronization/high level control across multiple devices.

If what you want is to send frames from a computer for display on a cube or a matrix then FastLED is the wrong platform to be using. You should be using pixel pusher, fade candy, octows2811, or a setup similar what you've stumbled onto with gladiator. This is a use case that I have repeatedly made the conscious, explicit decision to not focus on supporting with FastLED.

And on this thread, you can see quite a few of them. When the uC is randomly rebooting, it is a disaster that I cannot accept. You don't want to have randomly rebooting webs, do you?

And the reboot cycling is setup/code/environment specific (and there have been fixes added in the two years since this was opened that mitigated the ones that can be at the FastLED level) - my esp8266 projects only reboot when I hit the reset button (or flash new code to them).

I can reliably drive an 800 led strip with NeoPixelBus and output 30 frames per second.

Hi, can you describe your situation in more detail? How do you feed the pixel-data to the ESP8266 or is the pixel-data generated from the ESP8266? Do you use WiFi or serial communication? Which method do you use for NeoPixelBus? How is the physical connection between the ESP8266 and WS8212 ?
Thank you.

following on to what @focalintent stated I have focused NeoPixelBus to support updating even with WiFi, I have limitiation due to it, but it will work without crashing.

I will link to my Wiki for esp8266 specifics and I will discontinue on the topic here.

You can chat on the NeoPixelBus gitter channel if you have questions about it.

Hi Daniel,
I have to apologize to you. As a stupid newbie, I did not know, that you are the father of the ingenious FastLED, which is by many people preferred for driving LED-strips before NeoPixel library. So for what it's worth, you have my full respect and admiration.
You see for a newbie it is difficult to see what a class can offer. He starts with some fancy examples and uses the properties and methods from the example. For me, it is still a mystery, where all the properties and methods are documented for a human (I am not capable to understand them reading the C-code). Next thing to expect would be a list of limitations and recommendations on how to use it, what to use it for and what not. I know, programmers hate to create documentation which is soon obsolete, when they change the program. But it would save millions of people (your supporters) time and disappointment.
Or am I missing it, just because I don't know, where to find it?

I can respect your conscious, explicit decision not to prioritize "slinging full frames around". Just tell me, how do you create an animation with 32 devices, that (I suppose) display one complete picture, without sending at least parts of the frame around? I can see, that the power of FastLED is in creating animation in the device. But there must be a way to send the displayed objects between the devices...(?)

Your personal preference not to sling full frames around should not prevent you from using the hardware in devices, that are offering DMA. Believe me, there are many people, who would appreciate having a solution like NeoPixelBus integrated into FastLED. Even if you like "banging" there are certainly other useful tasks for the CPU that can be performed, while the hardware takes care of sending the pixels to the strip uninterrupted. Why don't you join your forces and experiences with Michael instead of trying to convince each other about the advantages and limitations of each other's work? Isn't that what Github is for?

Another thing. ESP8266 is a risc processor, isn't it. What I do not see is how are the principles of risc processor applied in the code. You still write
for (i = 0; i < n; i++) a[i] += 5;
instead of
apply a[i] += 5 to following amount of consecutive bytes, pixels etc.
or does the C-compiler take care of it?

So yeah - this is still happening - now I'm only on 46 LEDs and get resets even when all LEDs are off...

Has there been any progress / consensus on solving this as yet?

Release 3.3.3 - flickering with interrupts enabled, watchdog resets within minutes if interrupts disabled.