It works - ESP32 with WS2812B / WS2812 / NEOPIXEL and FastLED

Hello World

       For the past few days, I have been struggling to get my WS2812B LED display to work properly with an ESP32 WROOM32 using 3.3v logic.  One thing to note here is that I previously had the same LEDs working on an STM32 on both 3.3v Logic and 5v logic and of course they work fine on an Arduino with 5V Logic and Power.  Yesterday I finally got it working and working quite well.  If you’re facing the same problems or symptoms listed below, give this code edit a try and see if it works for you.  I've listed down the steps to recreate the problem I was having and what all I did in my setup and Arduino sketch to finally get my LED display panel working.

Problem: WS2812 / WS2812B / NEOPIXEL not working with ESP32 code compiled in Arduino using the FastLED or Adafruit libraries

 

Symptoms: 

  • LED shows dim blue color.
  • LED blinks erratically and jams on a single color.
  • LED Does not start up even if power and signal is supplied.

 

  1. Hardware:
  2. MCU: ESP32 WROOM32
  3. LED: WS2812B Breakout board (Sparkfun Link)
  4. Voltages: Supply – 3.3v, Logic 3.3v
  5. NOTE: The diagram below shows a connection to the 5V VIN pin on the ESP32 board, this is converted to 3.3v by the ESP32 voltage regulator.

 Breadboard:

Solution: After messing around with logic shifters, different libraries, and power supply levels, I finally got the ESP32 to communicate with the WS2812B LED using a couple of changes to my software code. The first change was in the colorWipe function which would pass a singular color to all my LEDs in one shot.  Previously, when I compiled and ran this code for an Arduino Nano/Mega or STM32 Blue pill it would work fine, but did not do so on the ESP32.  Turns out that this is caused by the ESP32 being too fast and bit banging the data to the LED driver too quickly and a timing difference on the ESP32 possibly due to RTOS.  To compensate for this, I added a delay(1) function call after each FastLED.show() call.  This change alone caused my entire 10 x 10 Panel of 100 LEDs to work correctly.  Even the 3 LEDs on our FJ40 Gauge cluster benefitted from this.  The code would look like this:

 

void colorWipe(uint8_t R,uint8_t G,uint8_t B , uint8_t wait) {

 

  if(wait < 1)

  {

    wait = 1;

  }

  for(uint16_t i=0; i<NUM_LEDS; i++) {

      leds[i] = CRGB(R,G,B);

    

    

  }

   FastLED.show();  /*Note the FastLED.show() function can be placed inside or outside the loop, but the delay function must be placed immediately after this */

      delay(wait);  

}

The second code change I made was to add the following line before my #include <FastLED.h> statement:

#define FASTLED_RMT_MAX_CHANNELS 1

This restricts the FastLED library to using a single RMT channel.  If you’re using the Adafruit library then there is no need for this line.

 

Here is the complete sketch:

public-ESP32/ESP32_WS2812B_FastLED.ino at main · nqtech/public-ESP32 (github.com)

 

The following Forums and Resources really helped me figure this out:

ESP32: timing error every 1ms corrupts LED pixel data · Issue #139 · adafruit/Adafruit_NeoPixel · GitHub

driving a RGB LED (WS2812) on an esp32-s2-saola-1 - ESP32 Forum

 

 

Thanks

NQ

 


Older Post


Leave a comment

Please note, comments must be approved before they are published