Using rmt for addressable LEDs causes an error.

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Using rmt for addressable LEDs causes an error.

Postby red_Panda » Mon Jan 09, 2023 11:40 am

I tried to adapt the example with this setting
#define TEST_RMT_CHANS 4
#define TEST_LED_NUM 600

everything works, but with
#define TEST_RMT_CHANS 4
#define TEST_LED_NUM 700

there is already an error
I (29) boot: ESP-IDF v5.1-dev-2658-g0025915dc4-dirty 2nd stage bootloader
I (29) boot: compile time Jan 9 2023 14:01:56
...
W (307) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (321) app_start: Starting scheduler on CPU0
I (325) app_start: Starting scheduler on CPU1
I (325) main_task: Started on CPU0
I (335) main_task: Calling app_main()
install tx channels
I (335) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (345) gpio: GPIO[18]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (355) gpio: GPIO[19]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (365) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
install led strip encoders
register tx event callback
enable tx channels
transmit without synchronization
0 - 255 cycle_time: 0 fps inf

***ERROR*** A stack overflow in task main has been detected.

Backtrace: 0x4008158e:0x3ffb3fc0 0x40085e95:0x3ffb3fe0 0x400885ba:0x3ffb4000 0x40087623:0x3ffb4080 0x400886c8:0x3ffb40a0 0x4008867a:0x4000bff0 |<-CORRUPTED

ELF file SHA256: 78cefabb41f81e2e

Rebooting...
I guess it has to do with the size of the block
typedef struct {
...
size_t mem_block_symbols; /*!< Size of memory block, in number of `rmt_symbol_word_t`, must be even */
...
} rmt_tx_channel_config_t;
Because with the number of LEDs less than 400 and the size of the block 64 was a similar error. But I can not find explanation about this value. Please tell me why this error can occur, how to correct it and whether the size of the block affects the occurrence of the error.

Code: Select all

void app_main(void)
{
    uint32_t red = 0;
    uint32_t green = 0;
    uint32_t blue = 0;
    uint16_t hue = 0;
    uint16_t value = 0;
    uint16_t start_rgb = 0;
    uint64_t cycle_time = 0;

    rmt_tx_channel_config_t tx_channel_cfg = {
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 10000000, // 10MHz, 1 tick = 0.1us (led strip needs a high resolution)
        .trans_queue_depth = 4,
    };

    printf("install tx channels\r\n");
    rmt_channel_handle_t tx_channels[TEST_RMT_CHANS] = {NULL};
    int gpio_nums[TEST_RMT_CHANS] = {5, 18, 19, 16};
    size_t mem_blk_syms = 128;
    for (int i = 0; i < TEST_RMT_CHANS; i++)
    {
        tx_channel_cfg.gpio_num = gpio_nums[i];
        tx_channel_cfg.mem_block_symbols = mem_blk_syms;
        ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_channel_cfg, &tx_channels[i]));
    }

    printf("install led strip encoders\r\n");
    rmt_encoder_handle_t led_strip_encoders[TEST_RMT_CHANS] = {NULL};

    led_strip_encoder_config_t encoder_config = {
        .resolution = RMT_LED_STRIP_RESOLUTION_HZ,
    };

    for (int i = 0; i < TEST_RMT_CHANS; i++)
    {
        ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_strip_encoders[i]));
    }
    printf("register tx event callback\r\n");
    rmt_tx_event_callbacks_t cbs = {
        .on_trans_done = test_rmt_tx_done_cb_record_time};
    int64_t record_stop_time[TEST_RMT_CHANS] = {};
    for (int i = 0; i < TEST_RMT_CHANS; i++)
    {
        ESP_ERROR_CHECK(rmt_tx_register_event_callbacks(tx_channels[i], &cbs, &record_stop_time[i]));
    }

    printf("enable tx channels\r\n");
    for (int i = 0; i < TEST_RMT_CHANS; i++)
    {
        ESP_ERROR_CHECK(rmt_enable(tx_channels[i]));
    }

    uint8_t leds_grb[TEST_LED_NUM * 3] = {};
    // color: Material Design Green-A200 (#69F0AE)
    for (int i = 0; i < TEST_LED_NUM * 3; i += 3)
    {
        leds_grb[i + 0] = 0xF0;
        leds_grb[i + 1] = 0x69;
        leds_grb[i + 2] = 0xAE;
    }

    printf("transmit without synchronization\r\n");
    rmt_transmit_config_t transmit_config = {
        .loop_count = 0, // no loop
    };

    while (1)
    {
        if (value == 0){
            struct timeval cycle_time_now;
            gettimeofday(&cycle_time_now, NULL);
            cycle_time = (int64_t)cycle_time_now.tv_sec * 1000000L + (int64_t)cycle_time_now.tv_usec;
        }
        if(value % 255 == 0)
        {
            struct timeval cycle_time_now;
            gettimeofday(&cycle_time_now, NULL);
            cycle_time = (int64_t)cycle_time_now.tv_sec * 1000000L + (int64_t)cycle_time_now.tv_usec - cycle_time;
            double fps = (int)cycle_time / 1000 / 255;
            fps = 1000 / fps;
            printf("\t\t\t0 - 255 cycle_time: %lld fps %.2f\n", cycle_time / 1000, fps);
            cycle_time = (int64_t)cycle_time_now.tv_sec * 1000000L + (int64_t)cycle_time_now.tv_usec;
        }
        for (int i = 0; i < 3; i++)
        {
            for (int j = i; j < TEST_LED_NUM; j += 3)
            {
                // Build RGB pixels
                hue = j * 360 / TEST_LED_NUM + start_rgb;
                // hue = start_rgb;
                led_strip_hsv2rgb(hue, 0, value % 255, &red, &green, &blue);
                leds_grb[j * 3 + 0] = green;
                leds_grb[j * 3 + 1] = blue;
                leds_grb[j * 3 + 2] = red;
            }
        }
        // printf("start_rgb: %d\thue: %d\tred: %d\tgreen: %d\tblue: %d\t\n", start_rgb, hue, (uint16_t)red, (uint16_t)green, (uint16_t)blue);
        
        struct timeval tv_now;
        uint64_t last_time[TEST_RMT_CHANS] = {NULL};
        for (int i = 0; i < TEST_RMT_CHANS; i++)
        {
            gettimeofday(&tv_now, NULL);
            last_time[i] = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
            ESP_ERROR_CHECK(rmt_transmit(tx_channels[i], led_strip_encoders[i], leds_grb, TEST_LED_NUM * 3, &transmit_config));
        }
        for (int i = 0; i < TEST_RMT_CHANS; i++)
        {
            ESP_ERROR_CHECK(rmt_tx_wait_all_done(tx_channels[i], -1));
        }
        start_rgb = 1;
        value += 1;
    }
}

cruvus
Posts: 59
Joined: Fri Jul 08, 2022 5:08 pm
Location: Planet Earth

Re: Using rmt for addressable LEDs causes an error.

Postby cruvus » Mon Jan 09, 2023 11:22 pm

You can increase the stack size of the main task in sdkconfig.
ESP32 / ESP-IDF 5.1.4

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Re: Using rmt for addressable LEDs causes an error.

Postby red_Panda » Tue Jan 10, 2023 12:38 pm

cruvus wrote:
Mon Jan 09, 2023 11:22 pm
You can increase the stack size of the main task in sdkconfig.
Thank you, I really didn't think of that reason. But now a second problem has arisen, and nothing is clear at all. When trying to create more than 4 RMT channels I get an error "no free tx channels".
rmt_tx.c
131 ESP_RETURN_ON_FALSE(channel_id >= 0, ESP_ERR_NOT_FOUND, TAG, "no free tx channels");
If I understood correctly, there can't be more than 4 channels in a group, but I can't figure out how to make two groups. Maybe you can tell me where to read it?

savage
Posts: 23
Joined: Mon Jul 15, 2019 9:24 pm

Re: Using rmt for addressable LEDs causes an error.

Postby savage » Tue Jan 10, 2023 1:50 pm

Which board are you using? Some boards, like the ESP32-S3, only have 4 TX and 4 RX channels.

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Re: Using rmt for addressable LEDs causes an error.

Postby red_Panda » Tue Jan 10, 2023 5:25 pm

savage wrote:
Tue Jan 10, 2023 1:50 pm
Which board are you using? Some boards, like the ESP32-S3, only have 4 TX and 4 RX channels.
I'm using esp32 and the datasheet on page 43 says RMT_SIG_OUT0~7 (8 channels), but in ~/me/espressif/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h line 216
#define SOC_RMT_CHANNELS_PER_GROUP 4 /*!< Total 4 channels */
which means that there can only be 4 channels in a group, if I understood correctly.
I don't understand how to dispose of this information, and most importantly how to create a second group.
esp-idf v5.1

ESP_Sprite
Posts: 9759
Joined: Thu Nov 26, 2015 4:08 am

Re: Using rmt for addressable LEDs causes an error.

Postby ESP_Sprite » Wed Jan 11, 2023 12:34 am

red_Panda wrote:
Tue Jan 10, 2023 5:25 pm


I'm using esp32 and the datasheet on page 43 says RMT_SIG_OUT0~7 (8 channels), but in ~/me/espressif/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h line 216
#define SOC_RMT_CHANNELS_PER_GROUP 4 /*!< Total 4 channels */
which means that there can only be 4 channels in a group, if I understood correctly.
That's a header for the ESP32C3, not for the (original) ESP32.

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Re: Using rmt for addressable LEDs causes an error.

Postby red_Panda » Wed Jan 11, 2023 6:25 am

ESP_Sprite wrote:
Wed Jan 11, 2023 12:34 am
red_Panda wrote:
Tue Jan 10, 2023 5:25 pm


I'm using esp32 and the datasheet on page 43 says RMT_SIG_OUT0~7 (8 channels), but in ~/me/espressif/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h line 216
#define SOC_RMT_CHANNELS_PER_GROUP 4 /*!< Total 4 channels */
which means that there can only be 4 channels in a group, if I understood correctly.
That's a header for the ESP32C3, not for the (original) ESP32.
This is strange since the firmware compiles and works. Maybe I have prepared an example incorrectly? I took an example, copied it, opened it in vscode and ran idf.py set-target esp32. If I had specified set-target esp32c3, then, as I understand it, when uploading to the MCU, I would have received an error.
Before that I used platformio, but decided I wanted version 5.1 and tried it in esp-idf. Please tell me, did I do everything right?

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Re: Using rmt for addressable LEDs causes an error.

Postby red_Panda » Wed Jan 11, 2023 8:29 am

ESP_Sprite wrote:
Wed Jan 11, 2023 12:34 am
red_Panda wrote:
Tue Jan 10, 2023 5:25 pm


I'm using esp32 and the datasheet on page 43 says RMT_SIG_OUT0~7 (8 channels), but in ~/me/espressif/esp-idf/components/soc/esp32c3/include/soc/soc_caps.h line 216
#define SOC_RMT_CHANNELS_PER_GROUP 4 /*!< Total 4 channels */
which means that there can only be 4 channels in a group, if I understood correctly.
That's a header for the ESP32C3, not for the (original) ESP32.
You are absolutely right! But I don't understand at all why this happened.
https://prnt.sc/7TNUXnX7Y9RU

I made a full clean and specified the target, but the path still leads to the file for esp32c3
https://prnt.sc/Kgpep5VCCnhN

The sdk config also specifies esp32, but I can't understand why the path leads to the header for esp32c3.
https://prnt.sc/XcPPLRSme1dX

red_Panda
Posts: 12
Joined: Mon Dec 21, 2020 7:22 am

Re: Using rmt for addressable LEDs causes an error.

Postby red_Panda » Wed Jan 11, 2023 10:27 pm

Based on what I was able to understand, vscode incorrectly walks through header files and for some reason user soc/esp32c3/include/soc/soc_caps.h instead of soc/esp32/include/soc/soc_caps.h when building the project.h I deleted .vscode and build from the project folder, made
idf.py clean,
idf.py fullclean,
idf.py set-target esp32
and build after all this, but nevertheless the path leads back to soc/esp32c3/include/soc/soc_caps.h. What can I check or try again? I'm desperate.

Who is online

Users browsing this forum: No registered users and 140 guests