xTaskCreate corrupts WS2812 LED signals
xTaskCreate corrupts WS2812 LED signals
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.
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.
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.
Re: xTaskCreate corrupts WS2812 LED signals
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.
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.
- IoT-Rainer
- Posts: 6
- Joined: Sun Feb 23, 2025 10:03 am
Re: xTaskCreate corrupts WS2812 LED signals
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
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
Re: xTaskCreate corrupts WS2812 LED signals
Also notice that app_main() already is a task, just one that is implicitly created by ESP-IDF rather than explicitly.
Re: xTaskCreate corrupts WS2812 LED signals
You should try to enable this in menuconfig
Code: Select all
CONFIG_COMPILER_STACK_CHECK_MODE_ALL=y
Re: xTaskCreate corrupts WS2812 LED signals
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.
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.
Re: xTaskCreate corrupts WS2812 LED signals
Complete sources to the corrupted WS2812 signal problem
To compile these sources:
main/idf_component.yml:
main/taskstrip.h:
main/taskstrip.c:
main/testmain.c:
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
Code: Select all
set(srcs "testmain.c" "taskstrip.c")
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ".")Code: Select all
dependencies:
espressif/led_strip: "^3.0.0"Code: Select all
void vTaskStrip(void *pvParams);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);
}
}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);
//}
}Re: xTaskCreate corrupts WS2812 LED signals
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.
Re: xTaskCreate corrupts WS2812 LED signals
Thanks chegewara, but it did not help to dramatically increase the stack size of all the tasks:
$ 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?
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);...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?
Re: xTaskCreate corrupts WS2812 LED signals
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
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: Amazon [Bot], PetalBot and 2 guests
