wokwi-features icon indicating copy to clipboard operation
wokwi-features copied to clipboard

The onboard Neopixel led does not work on every ESP32-xx board.

Open Koepel opened this issue 1 year ago • 14 comments
trafficstars

There is a discussion on the Discord channel about the Neopixel led on the ESP32-xx boards. Espressif provides a function for the onboard Neopixel led when Arduino code is used, but also a common Neopixel library can be used. The led works in real life, but not for every board in Wokwi.

The function neopixelWrite(): https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-rgb-led.h

Test code:

void setup() {}

void loop() 
{
  neopixelWrite(RGB_BUILTIN, 255,0,0);
  delay(400);
  neopixelWrite(RGB_BUILTIN, 0,255,0);
  delay(400);
  neopixelWrite(RGB_BUILTIN, 0,0,255);
  delay(400);
}

Result: ESP32-S2 : works ESP32-S3 : does not work ESP32-C3 : works ESP32-C6 : does not work ESP32-H2 : does not work

[EDIT] Setting the pinMode for the pin for the Neopixel was removed from setup(), according to the explanation by sivar2311 below.

Koepel avatar Aug 17 '24 11:08 Koepel

Note: for ESP32-S3, this works if we replace RGB_BUILTIN with 38. For some reason, RGB_BUILTIN equals to 97, which maps to pin 48. Not sure yet why.

urish avatar Aug 17 '24 12:08 urish

Okay, I found the source of the confusion:

Both the initial and v1.1 versions of ESP32-S3-DevKitC-1 are available on the market. The main difference lies in the GPIO assignment for the RGB LED: the initial version uses GPIO48, whereas v1.1 uses GPIO38.

Wokwi implements the newer version, v1.1. The arduino core seems to target the older version, using pin 48.

urish avatar Aug 17 '24 12:08 urish

Test-Projects:

ESP32 ESP32-S2 ESP32-S3 ESP32-C3 ESP32-C6 ESP32-H2

sivar2311 avatar Aug 17 '24 12:08 sivar2311

For C6/H2, I looked at the logic analyzer, and it seems like the RMT peripheral clock is off by about a factor of two. Investigating.

urish avatar Aug 17 '24 12:08 urish

Issue found, working on a fix.

urish avatar Aug 17 '24 12:08 urish

Fix is up!

urish avatar Aug 17 '24 12:08 urish

For the ESP32-S3 and the ESP32-C6: The onboard LED still doesn't work: image

sivar2311 avatar Aug 17 '24 13:08 sivar2311

@Koepel

{ pinMode(RGB_BUILTIN,OUTPUT); // probably not needed }

This is in fact not necessary, as the RMT unit is used for neopixelWrite.

Also digitalWrite(RGB_BUILTIN, <HIGH/LOW>); will work because there is a builtin check for the RGB-GPIO which will be translated to a call to the neopixelWrite function.

sivar2311 avatar Aug 17 '24 13:08 sivar2311

For the S3: see my comment above For the C6: right, the pin was wrong in the board definition. Fixed now.

urish avatar Aug 17 '24 13:08 urish

Looking at the code for the Arduino core, pin number 48 is hard coded. The ESP32-S3-DevKitM-1, which is a different board, also uses 48.

IMHO we should keep 38, as it's compatible with the latest version of the ESP32-S3-DevKitC-1, and the official documentation says the LED should be on pin 38.

urish avatar Aug 17 '24 13:08 urish

For the user experience: As a (Wokwi) user, I would expect neopixelWrite(RGB_BUILTIN, r, g, b); to work.

Unfortunately, neither the DevKitM-1 nor the specific version of the DevKitC-1 can be selected in Wokwi.

sivar2311 avatar Aug 17 '24 14:08 sivar2311

As a (Wokwi) user, I would expect neopixelWrite(RGB_BUILTIN, r, g, b); to work

I hear you. Let's ping Espressif to get their opinion about this.

urish avatar Aug 17 '24 16:08 urish

RGB_BUILTIN is composed by WS2812 pin_num + SOC_GPIO_PIN_COUNT -- it works like an "extra" special pin number This is declared by variants/board_name/pins_arduino.h

neopixelWrite(RGB_BUILTIN, Red, Green, Blue); only works when RGB_BUILTIN matches the value of actual_rgbled_pin + SOC_GPIO_PIN_COUNT or when a valid pin_num is used as an argument.

This is the code from esp32-hal-rgb-led.c:

// Verify if the pin used is RGB_BUILTIN and fix GPIO number
#ifdef RGB_BUILTIN
  pin = pin == RGB_BUILTIN ? pin - SOC_GPIO_PIN_COUNT : pin;
#endif

If the actual WS2812 pin is 38 and RGB_BUILTIN is declared as 48+SOC_GPIO_PIN_COUNT, neopixelWrite(RGB_BUILTIN, r, g, b); won't work. By other hand, neopixelWrite(38, r, g, b); will work properly.

SuGlider avatar Aug 20 '24 13:08 SuGlider

if RGB_BUILTIN is declared as 38, it also won't work, given that the code will calculate 38 - SOC_GPIO_PIN_COUNT Therefore, it is necessary that the variants/board_model_name/pins_arduino.h declare the Actual WS2812 pin correctly.

SuGlider avatar Aug 20 '24 13:08 SuGlider