Neopixel crash with >75 pixels using ESP32 Core 3.0.x

Hi,

I'm running into an issue where after upgrading the ESP32 package from 2.0.17 to 3.0.x, Neopixel sketches with an LED count of 76 or more get into a crash loop.

Adafruit NeoPixel v1.12.2
Arduino IDE Version: 2.3.2 (Date: 2024-02-20T10:04:35.814Z / CLI Version: 0.35.3)
Board: Adafruit ESP32 Feather (Huzzah32, https://learn.adafruit.com/adafruit-huzzah32-esp32-feather)
Board package: esp32 by Espressif Systems, version 3.0.0 (same behavior with 3.0.1)

Minimal sketch:

#include <Adafruit_NeoPixel.h>

// with esp32 v2.0.17: LED_COUNT 75 works, LED_COUNT 76 (and higher) works
// with esp32 v3.0.0:  LED_COUNT 75 works, LED_COUNT 76 crashes
#define LED_COUNT  50
#define LED_PIN    14

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);
  Serial.printf("Testing with %d pixels...\n", LED_COUNT);
  strip.begin();
  strip.show();
}

void loop() {};

Note that for the purpose of this test (and this reproduction), one does need any LEDs physically and actually connected (and therefore also rules out power supply issues etc).. I can reproduce this on a bare Huzzah32 board without any additional hardware attached.

Works with ESP32 package 2.0.17

As said in the comments in the sketch, when using ESP32 package 2.0.17:

  • Compiling and running sketch with LED_COUNT=75 works,
  • Compiling and running sketch with LED_COUNT=76 works (and higher - tested up to 200 at least; I could swear I've also used longer in the past).

Errors with ESP32 package 3.0.x and LED_COUNT > 75

With ESP32, the above sketch works up to, and including, LED_COUNT 75.

With a higher LED count, the sketch puts the ESP32 into a crash loop, albeit with different symptoms depending on the count.

WIth LED_COUNT 76:

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
Testing with 76 pixels...
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception). 
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core  1 register dump:
PC      : 0x4008a8ea  PS      : 0x00060636  A0      : 0x8008c55c  A1      : 0x3ffb0320  
A2      : 0x3ffb0300  A3      : 0xffffffff  A4      : 0x00060623  A5      : 0x3f406dac  
A6      : 0xb33fffff  A7      : 0xb33fffff  A8      : 0x800842d1  A9      : 0x3ffb0420  
A10     : 0x00000001  A11     : 0x00060020  A12     : 0x00000004  A13     : 0x00060023  
A14     : 0xb33fffff  A15     : 0xb33fffff  SAR     : 0x0000001f  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x40086208  LEND    : 0x4008621e  LCOUNT  : 0xffffffff  


Backtrace: 0x4008a8e7:0x3ffb0320 0x4008c559:0x3ffb0350 0x4008c6bd:0x3ffb0370 0x4008376e:0x3ffb0390 0x40083781:0x3ffb03c0 0x4008afd8:0x3ffb03e0 0x40087fc9:0x3ffb0400 0x400881dc:0x3ffb0420 0x400842ce:0x3ffb0440 0x40084316:0x3ffb0460 0x40084461:0x3ffb04a0 0x400d487b:0x3ffb04c0 0x400d59a4:0x3ffb04e0 0x400d2173:0x3ffb0540 0x400d1751:0x3ffb0590 0x400d16b3:0x3ffb2250 0x400d1584:0x3ffb2270 0x400d224e:0x3ffb2290

Stack trace decode:

0x4008a8e7: xPortEnterCriticalTimeout at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos\portmacro.h:560
0x4008c559: multi_heap_internal_lock at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos\portmacro.h:575
0x4008c6bd: multi_heap_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\multi_heap_poisoning.c:250
0x4008376e: heap_caps_malloc_base at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\heap_caps.c:176
0x40083781: heap_caps_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\heap_caps.c:197
0x4008afd8: pvPortMalloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos\heap_idf.c:83
0x40087fc9: xQueueGenericCreate at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel\queue.c:501
0x400881dc: xQueueCreateMutex at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel\queue.c:619
0x400842ce: lock_init_generic at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:64
0x40084316: lock_acquire_generic at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:118
0x40084461: _lock_acquire at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:154
0x400d487b: rmt_acquire_group_handle at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/rmt\rmt_common.c:40
0x400d59a4: rmt_new_tx_channel at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/rmt\rmt_tx.c:108
0x400d2173: rmtInit at C:\Users\carst\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.0\cores\esp32\esp32-hal-rmt.c:534
0x400d1751: espShow at C:\Users\carst\OneDrive\Documents\Arduino\libraries\Adafruit_NeoPixel\esp.c:40
0x400d16b3: Adafruit_NeoPixel::show() at C:\Users\carst\OneDrive\Documents\Arduino\libraries\Adafruit_NeoPixel\Adafruit_NeoPixel.cpp:3008
0x400d1584: setup() at C:\Users\carst\OneDrive\Documents\Arduino\debugtest\debugtest.ino:12
0x400d224e: loopTask(void*) at C:\Users\carst\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.0\cores\esp32\main.cpp:58

Sometimes I see a slight variation of that:

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
Testing with 76 pixels...
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception). 
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core  1 register dump:
PC      : 0x4008d186  PS      : 0x00060836  A0      : 0x8008d0f8  A1      : 0x3ffb0330  
A2      : 0x3ffb8da8  A3      : 0x00000000  A4      : 0x00000001  A5      : 0x00000000  
A6      : 0x3ffb8cf4  A7      : 0x00000000  A8      : 0x3ffb8dfc  A9      : 0xbaad5678  
A10     : 0x3ffb8000  A11     : 0x3ffb8da0  A12     : 0xfffffffe  A13     : 0xfffffffd  
A14     : 0xb33fffff  A15     : 0xb33fffff  SAR     : 0x0000001c  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x400862c8  LEND    : 0x400862de  LCOUNT  : 0xffffffff  


Backtrace: 0x4008d183:0x3ffb0330 0x4008d0f5:0x3ffb0360 0x4008382e:0x3ffb0380 0x40083841:0x3ffb03b0 0x4008ba00:0x3ffb03d0 0x400889f1:0x3ffb03f0 0x40088c04:0x3ffb0410 0x4008438e:0x3ffb0430 0x400843d6:0x3ffb0450 0x40084521:0x3ffb0490 0x400d5203:0x3ffb04b0 0x400d632c:0x3ffb04d0 0x400d2a9b:0x3ffb0530 0x400d1829:0x3ffb0580 0x400d178b:0x3ffb2240 0x400d165f:0x3ffb2260 0x400d3bbe:0x3ffb2290
0x4008d183: poison_allocated_region at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\multi_heap_poisoning.c:77
0x4008d0f5: multi_heap_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\multi_heap_poisoning.c:254
0x4008382e: heap_caps_malloc_base at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\heap_caps.c:176
0x40083841: heap_caps_malloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/heap\heap_caps.c:197
0x4008ba00: pvPortMalloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos\heap_idf.c:83
0x400889f1: xQueueGenericCreate at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel\queue.c:501
0x40088c04: xQueueCreateMutex at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel\queue.c:619
0x4008438e: lock_init_generic at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:64
0x400843d6: lock_acquire_generic at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:118
0x40084521: _lock_acquire at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:154
0x400d5203: rmt_acquire_group_handle at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/rmt\rmt_common.c:40
0x400d632c: rmt_new_tx_channel at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/rmt\rmt_tx.c:108
0x400d2a9b: rmtInit at C:\Users\carst\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.0\cores\esp32\esp32-hal-rmt.c:534
0x400d1829: espShow at C:\Users\carst\OneDrive\Documents\Arduino\libraries\Adafruit_NeoPixel\esp.c:40
0x400d178b: Adafruit_NeoPixel::show() at C:\Users\carst\OneDrive\Documents\Arduino\libraries\Adafruit_NeoPixel\Adafruit_NeoPixel.cpp:3008
0x400d165f: setup() at C:\Users\carst\OneDrive\Documents\Arduino\debugtest\debugtest.ino:14
0x400d3bbe: loopTask(void*) at C:\Users\carst\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.0\cores\esp32\main.cpp:58

With LED-COUNT 100 (don't know where the exact cutoff is; I've just tried different numbers in increments), the crash signature changes:

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
Testing with 100 pixels...

***ERROR*** A stack overflow in task loopTask has been detected.


Backtrace: 0x4008285d:0x3ffafa20 0x4008874d:0x3ffafa40 0x4008b4f9:0x3ffafa60 0x400899ea:0x3ffafae0 0x4008b6b0:0x3ffafb10 0x4008b660:0x3ffafb30 0x400843d6:0x00000001 |<-CORRUPTED

Decode:

Backtrace: 0x4008285d:0x3ffafa20 0x4008874d:0x3ffafa40 0x4008b4f9:0x3ffafa60 0x400899ea:0x3ffafae0 0x4008b6b0:0x3ffafb10 0x4008b660:0x3ffafb30 0x400843d6:0x00000001 |<-CORRUPTED

Decoding stack results
0x4008285d: panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system\panic.c:466
0x4008874d: esp_system_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/port\esp_system_chip.c:84
0x4008b4f9: vApplicationStackOverflowHook at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa\port.c:581
0x400899ea: vTaskSwitchContext at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/xtensa/include\xt_utils.h:40
0x400843d6: lock_acquire_generic at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib\locks.c:118

and with LED_COUNT 200, I see yet another signature - in this case it is just a TG1WDT_SYS_RESET.

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
Testing with 200 pixels...
ets Jun  8 2016 00:22:57

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
Testing with 200 pixels...
ets Jun  8 2016 00:22:57

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

I see that in other scenarios, TG1WDT_SYS_RESET was read as an indication of power supply issues(?), but again, I can reproduce this with or without any actual NeoPixel attached.

Behavior with ESP32 package 3.0.1 seems identical to that with 3.0.0.

Downgrading to 2.0.17, and all is working again.

Any help would be much appreciated :slight_smile:

Show your wiring diagram.

LED count of 76 or more

Just to be clear - by that I mean purely changing the value of LED_COUNT in the sketch. I'm not changing any hardware to trigger this.

Show your wiring diagram.

I don't have a good diagram, partly because there isn't much custom wiring involved. The original setup where I first ran into this is an Arduino Huzzah32 board, with Arduino PropMaker wing connected via the feather stacking headers, and Arduino NeoPixel LED strips connected and chained via JST connector. In the orinal/full code, there's of course also a digitalWrite in there to pull the PropMaker's PWR pin to high.

But for the context of the issue described here, and to reproduce this with a minimal setup, none of that is necessary. I see the same issue with just a Huzzah32 board and a USB cable (for power and serial console); without the propmaker or without any LEDs attached.

The 3.0 core definitely seems to have some issues. There are some workarounds for NeoPixel and 3.0 in the following issue reports:

The Neopixel code does dynamic storage allocation based on the number of pixels. Has the default heap size or allocation changed with the new ESP32 version?

Indeed there are issues.

I had problems with a well established display library, had to go back to the version 2.0.14 I was using previously.

I have exactly the same problem. With version higher than 2.0.17, impossible to make more than 75 leds work with neopixels. Stack overflow errors reboot the esp

Same problem here. Is there any new knowledge? Is there a solution to get the Neopixel library to work with more than 75 LEDs on an ESP32 version 3.x?

Same problem here, I can go up to 78 LEDS but on the 79th it crash at boot with same errors. Im using a XIAO ESP32C3 signal on D9

@termic @Tobi90as @rcflo-59 @carstenkoester

Sounds like a good reason to visit the ESPRESSIF ESP32 forum... and see Post #4.

This seems to be a known problem.

EDIT:
It seems to also affect the FastLED and NeoPixelBus libraries - different failures but (maybe) similar cause.

Am I right in assuming that the problem has already been fixed and that the pull request will be merged into the next version of the NeoPixel library?

My neopixel also crashes with 76+ leds. do you know more or less how often does neopixel updates?

Update, The problem is fixed and to save you some time reading, the problem is that with a strand of LEDs between 70-80 the memory allocation in the stack uses the full stack and it gets overflowed, by changing not to use the stack and use the regular ram that is big enough, the problem was solved by teknynja and he created a fork for the adafruit neopixel library with the problem solved. you can get the fork [here] (GitHub - teknynja/Adafruit_NeoPixel at esp32_rmt_memory_allocation_fix_safe) but first uninstall the master library from adafruit (neopixel) then download the zip file and install it in your library. hopefully, it will soon be incorporated into the master.

1 Like

Thank you for summarizing, making this clear and helpful.

I didnt have the problem on show(), (with <75 LEDs) until I suddenly did.
This branch didnt fix it , but here's what did:
I had my Adafruit_NeoPixel object created and initialized as a class member (within the class's ::init()) ; moving it to outside the class, fixed it.

Go figure, eh?