ESP32 Module with NeoPixel

Hi,

I am trying to control a NeoPixel LED-Ring with an ESP32 controller.

But the initialisation somehow doesn't work.
Here the setup section from my sketch:

#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>

const char ssid[] = "xxxx";
const char WiFipassword[] = "xxxxx";
const char mqtt_server[] = "10.0.1.10";

int interval;
long lastTime;
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels


// Setup WiFi connection and MQTT client.
WiFiClient mqttClient;
PubSubClient MQTTclient(mqttClient);

// Define the NeoPixel strip:
#define PIN        6  // Which pin on the Arduino is connected to the NeoPixels?
#define NUMPIXELS 12 // How many NeoPixels are attached to the Arduino? // Popular NeoPixel ring size
// Declare our NeoPixel strip object:
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);
  delay(10);
  
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, WiFipassword);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected with IP address:");
  Serial.println(WiFi.localIP());  

  // Setup mqtt
  MQTTclient.setServer(mqtt_server, 1883);
  MQTTclient.setCallback(callback);
  Serial.println("Start initialising NeoPixels");
  // setup NeoPixel
  pixels.begin(); // INITIALIZE NeoPixels
  Serial.println("Step 1 done");
  interval = 150;
  Serial.println("Step 2 done");
  randomSeed(analogRead(0));
  Serial.println("SETUP done");
}

In the serial monitor I can see the setup runs through to the randomSeed and then it crashes. But indeed it is the pixels.begin() command which causes the issue as it runs fine when I comment this line out.
Here what I get in the serial monitor:

15:15:25.177 -> WiFi connected with IP address:
15:15:25.177 -> 10.0.1.98
15:15:25.177 -> Start initialising NeoPixels
15:15:25.177 -> Step 1 done
15:15:25.177 -> Step 2 done
15:15:25.177 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
15:15:25.177 -> Core 1 register dump:
15:15:25.177 -> PC : 0x400813b7 PS : 0x00060430 A0 : 0x80081177 A1 : 0x3ffb1f10
15:15:25.177 -> A2 : 0x00000000 A3 : 0x000000c0 A4 : 0x3fdff7fd A5 : 0x0000ff00
15:15:25.177 -> A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x3f409458 A9 : 0x000000c0
15:15:25.215 -> A10 : 0xffffffff A11 : 0x00000044 A12 : 0x00000002 A13 : 0x0000ff00
15:15:25.215 -> A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x0000001f EXCCAUSE: 0x0000001c
15:15:25.215 -> EXCVADDR: 0xffffffff LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
15:15:25.215 ->
15:15:25.215 -> Backtrace: 0x400813b7:0x3ffb1f10 0x40081174:0x3ffb1f30 0x400812ed:0x3ffb1f50 0x400d0edb:0x3ffb1f70 0x400d3627:0x3ffb1fb0 0x40088f49:0x3ffb1fd0
15:15:25.253 ->
15:15:25.253 -> Rebooting...
15:15:25.253 -> ets Jun 8 2016 00:22:57
15:15:25.253 ->
15:15:25.253 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
15:15:25.253 -> configsip: 0, SPIWP:0xee
15:15:25.253 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
15:15:25.253 -> mode:DIO, clock div:1
15:15:25.253 -> load:0x3fff0018,len:4
15:15:25.253 -> load:0x3fff001c,len:1216
15:15:25.253 -> ho 0 tail 12 room 4
15:15:25.253 -> load:0x40078000,len:9720
15:15:25.253 -> ho 0 tail 12 room 4
15:15:25.253 -> load:0x40080400,len:6352
15:15:25.290 -> entry 0x400806b8
15:15:25.512 ->
15:15:25.512 ->
15:15:25.512 -> Connecting to Home_less

Not sure what's the is here?
Thanks for any help!

This is the pointer to your issue: EXCVADDR: 0xffffffff. see Fatal Errors - ESP32 - — ESP-IDF Programming Guide latest documentation

You'll want to narrow down which library is cause the error by commenting the line, one at a time, of

#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>

which will narrow down which part of your code you'll be looking into for the solution.

As a note the #include <Adafruit_NeoPixel.h> was written to accommodate an ESP32 and take advantage of its advanced feature set.

Here is how I use the Adafruit_Neopixel

#include "sdkconfig.h"
#include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include <Adafruit_NeoPixel.h>
#include "AudioAnalyzer.h"
////
/* define event group and event bits */
EventGroupHandle_t eg;
#define evtDo_AudioReadFreq       ( 1 << 0 ) // 1
////
TickType_t xTicksToWait0 = 0;
////
QueueHandle_t xQ_LED_Info;
////
const int NeoPixelPin = 26;
const int LED_COUNT = 24; //total number of leds in the strip
const int NOISE = 10; // noise that you want to chop off
const int SEG = 6; // how many parts you want to separate the led strip into
const int Priority4 = 4;
const int TaskStack40K = 40000;
const int TaskCore1  = 1;
const int TaskCore0 = 0;
const int AudioSampleSize = 6;
const int Brightness = 180;
const int A_D_ConversionBits = 4096; // arduino use 1024, ESP32 use 4096
////
Analyzer Audio = Analyzer( 5, 15, 36 );//Strobe pin ->15  RST pin ->2 Analog Pin ->36
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel leds = Adafruit_NeoPixel( LED_COUNT, NeoPixelPin, NEO_GRB + NEO_KHZ800 );
////
int FreqVal[7];//create an array to store the value of different freq
////
void ULP_BLINK_RUN(uint32_t us);
////
void setup()
{
  ULP_BLINK_RUN(100000);
  eg = xEventGroupCreate();
  Audio.Init(); // start the audio analyzer
  leds.begin(); // Call this to start up the LED strip.
  clearLEDs();  // This function, defined below, de-energizes all LEDs...
  leds.show();  // ...but the LEDs don't actually update until you call this.
  ////
  xQ_LED_Info = xQueueCreate ( 1, sizeof(FreqVal) );
  //////////////////////////////////////////////////////////////////////////////////////////////
  xTaskCreatePinnedToCore( fDo_AudioReadFreq, "fDo_ AudioReadFreq", TaskStack40K, NULL, Priority4, NULL, TaskCore1 ); //assigned to core
  xTaskCreatePinnedToCore( fDo_LEDs, "fDo_ LEDs", TaskStack40K, NULL, Priority4, NULL, TaskCore0 ); //assigned to core
  xEventGroupSetBits( eg, evtDo_AudioReadFreq );
} // setup()
////
void loop() {} // void loop
////
void fDo_LEDs( void *pvParameters )
{
  int iFreqVal[7];
  int j;
  leds.setBrightness( Brightness ); //  1 = min brightness (off), 255 = max brightness.
  for (;;)
  {
    if (xQueueReceive( xQ_LED_Info, &iFreqVal,  portMAX_DELAY) == pdTRUE)
    {
      j = 0;
      //assign different values for different parts of the led strip
      for (j = 0; j < LED_COUNT; j++)
      {
        if ( (0 <= j) && (j < (LED_COUNT / SEG)) )
        {
          set(j, iFreqVal[0]); // set the color of led
        }
        else if ( ((LED_COUNT / SEG) <= j) && (j < (LED_COUNT / SEG * 2)) )
        {
          set(j, iFreqVal[1]); //orginal code
        }
        else if ( ((LED_COUNT / SEG * 2) <= j) && (j < (LED_COUNT / SEG * 3)) )
        {
          set(j, iFreqVal[2]);
        }
        else if ( ((LED_COUNT / SEG * 3) <= j) && (j < (LED_COUNT / SEG * 4)) )
        {
          set(j, iFreqVal[3]);
        }
        else if ( ((LED_COUNT / SEG * 4) <= j) && (j < (LED_COUNT / SEG * 5)) )
        {
          set(j, iFreqVal[4]);
        }
        else
        {
          set(j, iFreqVal[5]);
        }
      }
      leds.show();
    }
    xEventGroupSetBits( eg, evtDo_AudioReadFreq );
  }
  vTaskDelete( NULL );
} // void fDo_ LEDs( void *pvParameters )
////
void fDo_AudioReadFreq( void *pvParameters )
{
  int64_t EndTime = esp_timer_get_time();
  int64_t StartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros
  for (;;)
  {
    xEventGroupWaitBits (eg, evtDo_AudioReadFreq, pdTRUE, pdTRUE, portMAX_DELAY);
    EndTime = esp_timer_get_time() - StartTime;
    // log_i( "TimeSpentOnTasks: %d", EndTime );
    Audio.ReadFreq(FreqVal);
    for (int i = 0; i < 7; i++)
    {
      FreqVal[i] = constrain( FreqVal[i], NOISE, A_D_ConversionBits );
      FreqVal[i] = map( FreqVal[i], NOISE, A_D_ConversionBits, 0, 255 );
      // log_i( "Freq %d Value: %d", i, FreqVal[i]);//used for debugging and Freq choosing
    }
    xQueueSend( xQ_LED_Info, ( void * ) &FreqVal, xTicksToWait0 );
    StartTime = esp_timer_get_time();
  }
  vTaskDelete( NULL );
} // fDo_ AudioReadFreq( void *pvParameters )
////
//the following function set the led color based on its position and freq value
//
void set(byte position, int value)
{
  // segment 0, red
  if ( (0 <= position) && (position < LED_COUNT / SEG) ) // segment 0 (bottom to top), red
  {
    if ( value == 0 )
    {
      leds.setPixelColor( position, 0, 0, 0 );
    } else {
      // increase light output of a low number
      // value += 10;
      // value = constrain( value, 0, 255 ); // keep raised value within limits
      if ( value <= 10 )
      {
        leds.setPixelColor( position, leds.Color( value , 0, 0) );
      } else {
        if ( (value * 1.1) >= 255 )
        {
          leds.setPixelColor( position, leds.Color( 255 , 0, 0) );
        } else {
          leds.setPixelColor( position, leds.Color( (value * 1.1) , 0, 0) );
        }
      }
    }
  }
 else if ( (LED_COUNT / SEG <= position) && (position < LED_COUNT / SEG * 2) ) // segment 1 yellow
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color(0, 0, 0));
    }
    else
    {
      leds.setPixelColor(position, leds.Color( value, value, 0)); // works better to make yellow
    }
  }
  else if ( (LED_COUNT / SEG * 2 <= position) && (position < LED_COUNT / SEG * 3) ) // segment 2 pink
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color(0, 0, 0));
    }
    else
    {
      leds.setPixelColor(position, leds.Color( value, 0, value * .91) ); // pink
    }
  }
  else if ( (LED_COUNT / SEG * 3 <= position) && (position < LED_COUNT / SEG * 4) ) // seg 3, green
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0));
    }
    else //
    {
      leds.setPixelColor( position, leds.Color( 0, value, 0) ); //
    }
  }
  else if ( (LED_COUNT / SEG * 4 <= position) && (position < LED_COUNT / SEG * 5) ) // segment 4, leds.color( R, G, B ), blue
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0));
    }
    else //
    {
      leds.setPixelColor(position, leds.Color( 0, 0, value) ); // blue
    }
  }
  else // segment 5
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0)); // only helps a little bit in turning the leds off
    }
    else
    {
      leds.setPixelColor( position, leds.Color( value, value * .3, 0) ); // orange
    }
  }
} // void set(byte position, int value)
////
void clearLEDs()
{
  for (int i = 0; i < LED_COUNT; i++)
  {
    leds.setPixelColor(i, 0);
  }
} // void clearLEDs()
//////////////////////////////////////////////
/*
  Each I_XXX preprocessor define translates into a single 32-bit instruction. So you can count instructions to learn which memory address are used and where the free mem space starts.

  To generate branch instructions, special M_ preprocessor defines are used. M_LABEL define can be used to define a branch target.
  Implementation note: these M_ preprocessor defines will be translated into two ulp_insn_t values: one is a token value which contains label number, and the other is the actual instruction.

*/
void ULP_BLINK_RUN(uint32_t us)
{
  size_t load_addr = 0;
  RTC_SLOW_MEM[12] = 0;
  ulp_set_wakeup_period(0, us);
  const ulp_insn_t  ulp_blink[] =
  {
    I_MOVI(R3, 12),                         // #12 -> R3
    I_LD(R0, R3, 0),                        // R0 = RTC_SLOW_MEM[R3(#12)]
    M_BL(1, 1),                             // GOTO M_LABEL(1) IF R0 < 1
    I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 1),  // RTC_GPIO2 = 1
    I_SUBI(R0, R0, 1),                      // R0 = R0 - 1, R0 = 1, R0 = 0
    I_ST(R0, R3, 0),                        // RTC_SLOW_MEM[R3(#12)] = R0
    M_BX(2),                                // GOTO M_LABEL(2)
    M_LABEL(1),                             // M_LABEL(1)
    I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 0),// RTC_GPIO2 = 0
    I_ADDI(R0, R0, 1),                    // R0 = R0 + 1, R0 = 0, R0 = 1
    I_ST(R0, R3, 0),                      // RTC_SLOW_MEM[R3(#12)] = R0
    M_LABEL(2),                             // M_LABEL(2)
    I_HALT()                                // HALT COPROCESSOR
  };
  const gpio_num_t led_gpios[] =
  {
    GPIO_NUM_2,
    // GPIO_NUM_0,
    // GPIO_NUM_4
  };
  for (size_t i = 0; i < sizeof(led_gpios) / sizeof(led_gpios[0]); ++i) {
    rtc_gpio_init(led_gpios[i]);
    rtc_gpio_set_direction(led_gpios[i], RTC_GPIO_MODE_OUTPUT_ONLY);
    rtc_gpio_set_level(led_gpios[i], 0);
  }
  size_t size = sizeof(ulp_blink) / sizeof(ulp_insn_t);
  ulp_process_macros_and_load( load_addr, ulp_blink, &size);
  ulp_run( load_addr );
} // void ULP_BLINK_RUN(uint32_t us)
//////////////////////////////////////////////

Maybe try the FastLED library. A cursory search shows there was some sort of issue with the neopixel library on esp8266... but that was a post from 2016 so I’m not sure how relevant it is.

Idahowalker:
This is the pointer to your issue: EXCVADDR: 0xffffffff. see Fatal Errors - ESP32 - — ESP-IDF Programming Guide latest documentation

You'll want to narrow down which library is cause the error by commenting the line, one at a time, of

#include <WiFi.h>

#include <PubSubClient.h>
#include <Adafruit_NeoPixel.h>


which will narrow down which part of your code you'll be looking into for the solution.

As a note the #include <Adafruit_NeoPixel.h> was written to accommodate an ESP32 and take advantage of its advanced feature set.

But I believe it must come from the Adafruit library. Because when I comment the pixels.show() line it the sketch works without any issue.

if you add these

#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include <Adafruit_NeoPixel.h>

before the neopixel does the issue go away>

Idahowalker:
if you add these

#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include <Adafruit_NeoPixel.h>



before the neopixel does the issue go away>

No.
Same behaviour.

Btw - even the strandtest sketch from the samples doesn't work.
Is it possible there is a hardware failure?

Could be.

Could be.