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.
http://fastled.io
MIT License
6.35k stars 1.62k forks source link

ESP32 with enabled WiFi produces random colors and flickering on Neopixel #507

Closed tbnobody closed 6 years ago

tbnobody commented 6 years ago

It seems that the interrupt handling of the wifi stack is disturbing the output of the signal to handle the ws2801 (neopixel) correctly. I have a sketch which is basically like this example: https://github.com/espressif/esp-idf/blob/master/examples/protocols/sntp/main/sntp_example_main.c

in combination with this main method:

extern "C" void app_main(void)
{
    initArduino();
    xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, NULL, ARDUINO_RUNNING_CORE);
    obtain_time();
}

The loopTask method contains e.g. the following:

FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(50);
while (1) {
    micros();
    time(&now);
    localtime_r(&now, &timeinfo);

    clearClock();
    int Hours = timeinfo.tm_hour;
    int Minutes = timeinfo.tm_min;
    int Seconds = timeinfo.tm_sec;
    timeToStrip(Hours, Minutes, Seconds);
    FastLED.show();  
    yield();
    delay(1000 / 120);
    yield();
}

If I comment out the obtain_time() method, everything works very reliable. But with the obtain_time method included, I have some leds with random colors and in general random leds lighting up.

I already tried the new version of "clockless_esp32.h" as mentioned here: https://github.com/samguyer/FastLED/commit/b1ffc707a1a7075840018ba44617be21bbccf568 but without any effect

tbnobody commented 6 years ago

I just integrated the RMT based solution into the clockless_esp32.h file https://github.com/MartyMacGyver/ESP32-Digital-RGB-LED-Drivers/blob/master/esp-idf/demo1/components/ws2812/ws2812.cpp

The timings are currently hard coded for the WS2812 but it works perfectly! Maybe thats a better solution than the bit banging.

astro0302 commented 6 years ago

I can confirm the error with WS2812B and the FastLed Library. Same script with APA102 is without this error.

tbnobody commented 6 years ago

Yes, thats clear. Please see #504 Duplicate of #504

Wetterprophet commented 6 years ago

Hey everybody, I always had the problem that my ESP32 resetted on FastLED.show(); Resolved it by calling

define FASTLED_ALLOW_INTERRUPTS 0

before including the FastLED-library. also i think that this only works with FastLED version from the 2018/01/18th on. Hope that helps ;)

themindfactory commented 5 years ago

I just integrated the RMT based solution into the clockless_esp32.h file https://github.com/MartyMacGyver/ESP32-Digital-RGB-LED-Drivers/blob/master/esp-idf/demo1/components/ws2812/ws2812.cpp

The timings are currently hard coded for the WS2812 but it works perfectly! Maybe thats a better solution than the bit banging.

I am having issues with FastLED 3.2.1, I (RMT version) have used

define FASTLED_ALLOW_INTERRUPTS 0 before all occurrences of #include within my project on Arduino IDE 1.8.5 and I get random color twinkles on the WS2812 leds when WIFI networking is accessed.

I have multiple files in the project so occurs a few times in both .cpp and .h files, I added the #FASTLED_ALLOW_INTERRUPTS 0 before each.

RichardS

themindfactory commented 5 years ago

I looked at the actual RMT code in the library and it does not use the FASTLED_ALLOW_INTERRUPTS #define so unsure how disabling interrupts works with it, but it seems it needs to be disabled, unless the flicker is caused by other RMT code issue

ghost commented 5 years ago

Which core is the RMT interrupt allocated on? I had issues with flickering when I allocated it on the system core, which means the interrupt handling also happens on that core Looking at the code the RMT interrupt is allocated from the method showPixels

ghost commented 5 years ago

Hmm, actually, I see you use Arduino, and Arduino for ESP32 starts the loop on core 1, so not on the system/wifi one (0). So probably not that :)

ghost commented 5 years ago

Actually, looking at it initialization is done the first time leds are set to a color, so there might still be a small chance you do that from somewhere which is called on core 0, for example a network callback, maybe? you might want to find the first place where you set the leds, and add Serial.println(xPortGetCoreID()); to it to double check which core it's on :)

themindfactory commented 5 years ago

I am not sure what first place I set the leds is... is this the FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, nLEDS).setCorrection(TypicalPixelString); type statement... I added the println just under that and its core 1, so same as the loop()

themindfactory commented 5 years ago

I am doing this in the Arduino IDE, I have 2 tasks setup for a web server, and websockets server, they were both in core 1, I moved them to core 0 and still flickers... just a thought.... they are setup with the xTaskCreatePinnedToCore( ) call

themindfactory commented 5 years ago

and after the FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, nLEDS).setCorrection(TypicalPixelString); I do the first FastLED.show(); so its also core 1

ghost commented 5 years ago

Ahwell, that doesn't seem to be the problem in your case then, sorry, no other ideas :)

themindfactory commented 5 years ago

Thanks! I will keep looking for issue today! and report for others...

JannesV commented 5 years ago

Thanks! I will keep looking for issue today! and report for others...

@themindfactory Any progress on what the issue was? Experiencing the same.

usc31391 commented 4 years ago

Hmm, actually, I see you use Arduino, and Arduino for ESP32 starts the loop on core 1, so not on the system/wifi one (0). So probably not that :)

Thank you so much @cranphin .....you were right systemwifi is allocated on core 0 and even if you try to assign it on core 1 (which i did in my arduino void setup()) the system wifi function doesn't run on 1...............I am using latest fastled library, and it is not Fastled.show() issue at all, it is very logical if you turn on wifi (WiFi.begin()) the core 0 starts to maintain the connection continuously and hence obviously their will be delay.....so you need to move that Fastled.show() tight clock connection loop to core 1

My config: WS2812 all Fastled libraries on core 1, 30 leds MQTT and WiFi.h functions on core 0

How to check flickering issue: Turn all leds to Red, a dim white flickering will occur intermittently

Works flawlessly with ESP32...... Many thanks to you again for pointing out that system wifi runs on core 0 👍

Superfluxx commented 3 years ago

Hmm, actually, I see you use Arduino, and Arduino for ESP32 starts the loop on core 1, so not on the system/wifi one (0). So probably not that :)

Thank you so much @cranphin .....you were right systemwifi is allocated on core 0 and even if you try to assign it on core 1 (which i did in my arduino void setup()) the system wifi function doesn't run on 1...............I am using latest fastled library, and it is not Fastled.show() issue at all, it is very logical if you turn on wifi (WiFi.begin()) the core 0 starts to maintain the connection continuously and hence obviously their will be delay.....so you need to move that Fastled.show() tight clock connection loop to core 1

My config: WS2812 all Fastled libraries on core 1, 30 leds MQTT and WiFi.h functions on core 0

How to check flickering issue: Turn all leds to Red, a dim white flickering will occur intermittently

Works flawlessly with ESP32...... Many thanks to you again for pointing out that system wifi runs on core 0 👍

Hello,

I have the same problem in my projet, but i don't understant how do you did for runnig all fastLED's libraries on core 0. Can you explain it to me (in simple english ;) ) ?

usc31391 commented 3 years ago

Hmm, actually, I see you use Arduino, and Arduino for ESP32 starts the loop on core 1, so not on the system/wifi one (0). So probably not that :)

Thank you so much @cranphin .....you were right systemwifi is allocated on core 0 and even if you try to assign it on core 1 (which i did in my arduino void setup()) the system wifi function doesn't run on 1...............I am using latest fastled library, and it is not Fastled.show() issue at all, it is very logical if you turn on wifi (WiFi.begin()) the core 0 starts to maintain the connection continuously and hence obviously their will be delay.....so you need to move that Fastled.show() tight clock connection loop to core 1 My config: WS2812 all Fastled libraries on core 1, 30 leds MQTT and WiFi.h functions on core 0 How to check flickering issue: Turn all leds to Red, a dim white flickering will occur intermittently Works flawlessly with ESP32...... Many thanks to you again for pointing out that system wifi runs on core 0 👍

Hello,

I have the same problem in my projet, but i don't understant how do you did for runnig all fastLED's libraries on core 0. Can you explain it to me (in simple english ;) ) ?

Hi friend, I think the libraries are stored in flash memory which is around 4M or 512KiloBytes SPI memory in case of ESP32. Whenever any line is executed by the Xtensa (processor) it fetches the data or next line of code from this 512KB flash memory. So when you put the code(fastled.show()) in core 1, ARM processor will run this code in only core 1 processor. All your arduino .cpp or .h files (also called as libraries) will be stored in SPI memory. Storing files/libraries is independent of code execution by any processor(0 or 1).

I have referred rui santos https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/ tutorial. Remember: Core 0: All wifi handling processes Core 1: Fastled

Superfluxx commented 3 years ago

Hi friend and thank you for responding quickly, In my program i use the libraries ESPAsyncWebServer.

I followed the tutorial. So I have 2 tasks, one with the wifi, the request, and SPIFFS code on core 0. On the second task i wrote fasled code and "my code".

when i upload the code on ESP32, the monitor confirms that the task1(wifi...) is runnig on core 0 and the task2(fastLed) is runnig on core 1. But when i send request to ESP, the request is runnig on core 1 and my leds produce random colors during 0.5 seconds. I don't understand why, do you have an idea ?

usc31391 commented 3 years ago

Hi friend no problem with that :)

Can you share any snapshot of the code in your core 0,1, (parent)void setup and (parent)void loop (only parts which you are comfortable)

Suggestions only 1) (Parent)Void loop should be empty 2) Do not initialize any WiFi related classes in (Parent) Void Setup 3) Function core0 has two parts: setup and loop mentioned in-explicitly. Anything above for (;;) is to be considered as void setup while anything inside for(;;){ code } is your void loop 4) So now initialise WiFi parameters/classes in void setup of Core0 only. 5) Pass variables from Core0 to Core1 using global variables 6) The random leds colour might be due to lower stack on core1. below is my config: xTaskCreatePinnedToCore(core0code,"core0",10000,NULL,1,&core0,0); xTaskCreatePinnedToCore(core1code,"core1",20000,NULL,1,&core1,1);

Superfluxx commented 3 years ago

I tried with 20000 in the core 1 but the problem is the same

marmilicious commented 3 years ago

Hello @Superfluxx When sharing that much code, please consider using pastebin.com or gist.github.com and share a link to the code. It will be formatted correctly and much easier to read, and line numbers can even be referenced.

usc31391 commented 3 years ago

Hello @Superfluxx When sharing that much code, please consider using pastebin.com or gist.github.com and share a link to the code. It will be formatted correctly and much easier to read, and line numbers can even be referenced.

Hello @marmilicious thank you for the suggestion. Will follow this practice :)

usc31391 commented 3 years ago

I tried with 20000 in the core 1 but the problem is the same

Hi,

i have suggested some changes which might help https://gist.github.com/usc31391/2ccd5fea4f0832321b102e94576117d7 will delete it when you say.

Comments: 1) Try changing the stack of esp32 put more on core 0. I just experiment in the ratios of 2:1 or 1:2 or 4:1 or 1:4 etc. 2) I never used Asyncwebserver for any of my FASTLED projects, so i do not how cores interact with Webserver or the stack values or the core priorities. For mqtt i use pubsubclient and nodered. So my knowledge is limited to only client based calling. 3)I assume that Webserver consumes lot of stack size and even intialization it properly might not help. 4)If you want to go for production then i suggest use ESP12 for running a Webserver & use STM32/ESP12/ArduinoNano for running FASTLED. Use UART for communication. 5) Use Elimination trick. Start 1st by commenting out communication leds code and replace it with another sudo code. By this you will be able to point out the exact block of problem code. Do this for libraries also, sometime asynclibrary might be a problem also. I use this elimination method for developing customised libraries, i have even modified the existing pubsubclient library for esp32 and esp8266 since they had some bugs during production. So you might need to change this asynclibrary to suit your need.

Superfluxx commented 3 years ago

Hi friend and thank you all! I tried to change the stack nothing change about the random color. I'll will use elimination trick in librairesand i'll tell you if I found the problem.

Why do you think it's better to have an esp12 and an arduino nano with communication uart? It's just for my problem or a better reliability in general ?

Superfluxx commented 3 years ago

And when i use the function "communicationLed" on core 0, i have randoms colors all the time

Superfluxx commented 3 years ago

Hi,

I just noticed that the query is executed on core 0 only if fastledshow is running on core 0

usc31391 commented 3 years ago

Hi freind, Core 0 and Core 1 are totally independents as you might have noticed now. So just remember if you need to pass values such as hue,sat,variation,numleds from core0 to core1 then use globals. Or best is way to create switch cases or if statements and pass only the byte variable 0 or 1 or 2.....so on from your webserver.

Earlier i suggested to separate Wifi module(ESP12) and Fastled module(ESP12/STM32/Nano) because you can upgrade your wifi module with Bluetooth or zigbee etc. while the code on Fastled module remains unaffected. For test and building purposes you can only focus on Faslted module, and so you will avoid such errors. Also it is cheaper and most important thing is that Esp12/Arduino has plenty of examples on github and youtube, so you can directly copy paste without applying much brain i.e. running into problems and saves time too 😅.

ESP32 is best module at the price (it is a beast, doesnt even heat), but is probably a overkill for your project. But it is very difficult to identify problems compared to Esp12 or arduino. Esp32 has a steep learning curve, more time you spend with it the more you will learn. And to be honest i have no experience in using Webserver on esp32 :) but if you have any queries regarding pubsubclient and Fastled then i can help.

sblantipodi commented 3 years ago

@usc31391 can you show us a snippet of fastled running on ESP32 and WiFi using both cores please? Using pubsubclient here and it produces a lot of flickering.

usc31391 commented 3 years ago

@sblantipodi Hi friend please find the below setup code. It is almost a year i have stopped working on the MQTT with ESP32, but during that time the below snippet worked without any flickering. Hope it helps you.

//-------------------------------SETUP LOOP BEGIN--------------------------------------------//

TaskHandle_t core0; TaskHandle_t core1;

void setup() {
/*

void core0code( void * pvParameters ){ WS.connect_to_wifi();
time_now = millis(); //required for 1st quick wifi connection mqttConnect(0);

for(;;){ delay(10); //delay is very important, else system crashes if (!client.loop()) { mqttConnect(mqttimeout); } }

}

void core1code( void * pvParameters ){ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds1, NUM_LEDS); FastLED.setBrightness(max_bright);

for(;;){ esp32bootbutton (); Pixel.summarymodes(armode);
} }

void loop() { }

/ Findings: 1) Default timing of reconnection of 30s is as good as 60s, means flickering is almost equal for both of them 2) Flickering is also caused when any command is received /