wokwi / wokwi-features

Wokwi Feature requests & Bug Reports
https://wokwi.com
73 stars 17 forks source link

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

Open Koepel opened 2 months ago

Koepel commented 2 months ago

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.

urish commented 2 months ago

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 commented 2 months ago

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.

sivar2311 commented 2 months ago

Test-Projects:

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

urish commented 2 months ago

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 commented 2 months ago

Issue found, working on a fix.

urish commented 2 months ago

Fix is up!

sivar2311 commented 2 months ago

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

sivar2311 commented 2 months ago

@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.

urish commented 2 months ago

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

urish commented 2 months ago

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.

sivar2311 commented 2 months ago

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.

urish commented 2 months ago

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.

SuGlider commented 2 months ago

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 commented 2 months ago

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.