xTaskCreate corrupts WS2812 LED signals

espmich
Posts: 41
Joined: Tue Jan 16, 2024 8:32 pm

xTaskCreate corrupts WS2812 LED signals

Postby espmich » Sun Feb 23, 2025 12:44 pm

esptaskprob-good.gif
esptaskprob-good.gif (1.6 MiB) Viewed 3029 times
This picture shows a WS2812B LED behaving correctly. The logic is copied from the ESP-IDF/examples/get-started/blink project, and placed in a FreeRTOS task started by xTaskCreate(). There is no second task running.

esptaskprob-bad.png
esptaskprob-bad.png (213.06 KiB) Viewed 3029 times
This picture shows the same device with flawed logic. The source code is the same as the first picture, however a second task is created. The second task includes the gpio_reset_pin(), gpio_set_direction(), and gpio_set_level() functions to cycle a standard LED connected to a GPIO.

The point of this excercise is to understand how to blink two leds, one standard GPIO connected and one digital WS2812 type. The two blink circuits are controlled by two FreeRTOS tasks, which should be easy.

RMT and SPI

The RMT and SPI signalling methods have no affect on the WS2812B shown in the pictures above.

Question

Why is the WS2812B blink logic failing? It is a strange green colour and doesn't blink.

Suspicion

I think that the FreeRTOS scheduler is preempting the WS2812 blink logic and corrupting the signal when control is switched to other tasks.
Last edited by espmich on Mon Feb 24, 2025 12:26 pm, edited 1 time in total.

espmich
Posts: 41
Joined: Tue Jan 16, 2024 8:32 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby espmich » Sun Feb 23, 2025 1:10 pm

Environment

HW: ESP32-C3
FW: ESP-IDF 5.4

The development machine (compiling using idf.py build) is a Ubuntu 24.04.1 LTS.

The version of the led_strip component used is 2.4.1 or 3.0.0, both lead to the same flaw.

User avatar
IoT-Rainer
Posts: 6
Joined: Sun Feb 23, 2025 10:03 am

Re: xTaskCreate corrupts WS2812 LED signals

Postby IoT-Rainer » Sun Feb 23, 2025 1:56 pm

Hi

vTaskNone() is never started in your example, if you expect to get help finding out what goes wrong, you should provide full code.
Otherwise it can only be said, that you are doing something wrong.

Best regards, Rainer
IoT, embedded and web: https://www.kaufmann-automotive.ch

Sprite
Espressif staff
Espressif staff
Posts: 10636
Joined: Thu Nov 26, 2015 4:08 am

Re: xTaskCreate corrupts WS2812 LED signals

Postby Sprite » Mon Feb 24, 2025 2:15 am

Also notice that app_main() already is a task, just one that is implicitly created by ESP-IDF rather than explicitly.

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby chegewara » Mon Feb 24, 2025 2:21 am

You should try to enable this in menuconfig

Code: Select all

CONFIG_COMPILER_STACK_CHECK_MODE_ALL=y

espmich
Posts: 41
Joined: Tue Jan 16, 2024 8:32 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby espmich » Mon Feb 24, 2025 12:11 pm

Thanks chegewara, after setting the stack mode as you suggested I reviewed the monitor output again but nothing changed. It seems there is no problem with the task stacks.

Thanks ESP_Sprite, app_main() is indeed a task of its own. I can create a lot of tasks without corrupting the WS2812 signal, as long as the tasks do simple nonsense like just printing log messages. If I start a task that manipulates a GPIO (connected to a LED) or uses the LEDC peripheral, then the led_strip signal gets corrupted and the WS2812 fails.

Thanks IoT-Rainer, I'll upload the complete sources now, everything in the main directory. Please stay tuned.

espmich
Posts: 41
Joined: Tue Jan 16, 2024 8:32 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby espmich » Mon Feb 24, 2025 12:25 pm

Complete sources to the corrupted WS2812 signal problem

To compile these sources:
  • Put them in a folder named main
  • Change to the parent directory
  • Use a standard CMakeLists.txt
  • Type idf.py build
main/CMakeLists.txt:

Code: Select all

set(srcs "testmain.c" "taskstrip.c")

idf_component_register(SRCS "${srcs}"
                    INCLUDE_DIRS ".")
main/idf_component.yml:

Code: Select all

dependencies:
  espressif/led_strip: "^3.0.0"
main/taskstrip.h:

Code: Select all

void vTaskStrip(void *pvParams);
main/taskstrip.c:

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"

static const char *TAG = "Corruptblink";

#define BLINK_GPIO 8

static uint8_t s_led_state = 0;

static led_strip_handle_t led_strip;

static void blink_led(void)
{
    /* If the addressable LED is enabled */
    if (s_led_state) {
    /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
        led_strip_set_pixel(led_strip, 0, 16, 16, 16);
        /* Refresh the strip to send data */
        led_strip_refresh(led_strip);
    } else {
        /* Set all LED off to clear all pixels */
        led_strip_clear(led_strip);
    }
}

static void configure_led(void)
{
    ESP_LOGI(TAG, "Example configured to blink addressable LED!");
    /* LED strip initialization with the GPIO and pixels number*/
    led_strip_config_t strip_config = {
        .strip_gpio_num = BLINK_GPIO,
        .max_leds = 1, // at least one LED on board
        .led_model = LED_MODEL_WS2812,
        .color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
        .flags = {
            .invert_out = false, // don't invert the output signal
        }
    };
    led_strip_rmt_config_t rmt_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 10 * 1000 * 1000, // 10MHz
        .mem_block_symbols = 64,
        .flags.with_dma = false,
    };
    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
    //led_strip_spi_config_t spi_config = {
    //    .spi_bus = SPI2_HOST,
    //    .flags.with_dma = true,
    //};
    //ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip));
    /* Set all LED off to clear all pixels */
    led_strip_clear(led_strip);
}

void vTaskStrip(void *pvParams)
{

    /* Configure the peripheral according to the LED type */
    configure_led();

    while (1) {
        ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
        blink_led();
        s_led_state = !s_led_state;
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}
main/testmain.c:

Code: Select all

#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "taskstrip.h"

#define LED_GPIO 12  // Simple discrete LED

static uint8_t s_gpio_state = 0;

// Implementation of a GPIO on-off cycle
void vTaskGpio(void *pvParams)
{
    gpio_reset_pin(LED_GPIO);
    gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);

    while(1) {
        ESP_LOGI("Gpiotask", "Turning the LED!\n");
        s_gpio_state = !s_gpio_state;
        gpio_set_level(LED_GPIO, s_gpio_state);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

// Implementation of a silly do nothing task
void vTaskNone(void *pvParams)
{
    while(1) {
        ESP_LOGI("Nonetask", "Not doing anything!\n");
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    // Declare handles for the different tasks to run
    TaskHandle_t xHandleStrip = NULL, xHandleGpio = NULL, xHandleNone = NULL;

    // Create tasks to run concurrently
    xTaskCreate(vTaskStrip, "RGBStrip", 2048, NULL, 8, &xHandleStrip);
    configASSERT(xHandleStrip);
    xTaskCreate(vTaskGpio, "GPIOFlip", 2048, NULL, 8, &xHandleGpio);
    configASSERT(xHandleGpio);
    xTaskCreate(vTaskNone, "NOPTask", 2048, NULL, 8, &xHandleNone);
    configASSERT(xHandleNone);

    // Clean up task resources
    //if (xHandle != NULL) {
    //    vTaskDelete(xHandle);
    //}
}

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby chegewara » Tue Feb 25, 2025 1:41 am

It is highly recommended to increase tasks stack to 3500+ for tasks with logs. Even if this flag didnt catch tasks stack corruption it does not mean that task cant corrupt other part of code.

espmich
Posts: 41
Joined: Tue Jan 16, 2024 8:32 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby espmich » Tue Feb 25, 2025 10:58 am

Thanks chegewara, but it did not help to dramatically increase the stack size of all the tasks:

Code: Select all

// Create tasks to run concurrently
xTaskCreate(vTaskStrip, "RGBStrip", 4096, NULL, 8, &xHandleStrip);
configASSERT(xHandleStrip);
xTaskCreate(vTaskGpio, "GPIOFlip", 4096, NULL, 8, &xHandleGpio);
configASSERT(xHandleGpio);
xTaskCreate(vTaskNone, "NOPTask", 4096, NULL, 8, &xHandleNone);
configASSERT(xHandleNone);
$ idf.py flash

...causes the WS2812B (controlled by vTaskStrip) to stop blinking, freezing, and changing from its medium white to bright green. The signal is clearly corrupted (as described before) even with the larger stack size.

Do you have any more ideas that I should test?

chegewara
Posts: 2505
Joined: Wed Jun 14, 2017 9:00 pm

Re: xTaskCreate corrupts WS2812 LED signals

Postby chegewara » Tue Feb 25, 2025 1:59 pm

I checked the code and it looks fine, but i recollect now i had similar issue with esp32-c6 few months ago on espressif workshops in Brno.
To be honest i dont remember what was the reason and if i solved the problem. Funny fact is that i was the only one having the issue back then.

For couple weeks i am using led_strip component on S3 mesh nodes and all works great, so it may be related to library on C3/C6 or some weird hardware problem.

Summary:
- LED init is ok
- the way you are using tasks is ok
- no obvious issue with the code

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], PerplexityBot and 1 guest