Using rmt for addressable LEDs causes an error.
Posted: 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
#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 guess it has to do with the size of the blockI (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...
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.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;
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;
}
}