ESP32 I2S Data Stream Problem
Posted: Thu Jan 21, 2021 1:42 am
I am using an oscilloscope to investigate the problems I have when driving a 16x16 WS2812B LED array with ESP32 Pico D4 using I2S interface. Occasionally I am seeing a gap in the beginning and end of the color bit stream. All the bits are there, but it seems that the I2S DMA goes to sleep for 4..6 us without an explanation. Obviously the LED array will fail with the extra gaps in the stream.
First the application sends 256 zero bytes to reset all the LEDs before starting with the color information. My conclusion is that the problem is in the ESP32 hardware or IDF libraries.
In the test setup, the software sets the zero bytes and constant color bytes in a buffer and sends them out once per second with the following statement
The I2S is initialized with
It is possible that I am overlooking something obvious, but the variations in the scope picture are difficult to explain. The scope picture shows that the WS clock works perfectly OK and indicates the left and right channels.
If the gaps would be there all the time with the constant data, then the problem could be in my code or ESP IDF 4.1, but now it probably is in the hardware.
First the application sends 256 zero bytes to reset all the LEDs before starting with the color information. My conclusion is that the problem is in the ESP32 hardware or IDF libraries.
In the test setup, the software sets the zero bytes and constant color bytes in a buffer and sends them out once per second with the following statement
Code: Select all
esp_err_t err = i2s_write(I2S_NUM, colorBuffer, bufferSize, &byteCount, 10);
Code: Select all
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX,
.sample_rate = BIT_RATE / SAMPLE_SIZE2, // = 69444
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // = 16
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.dma_buf_count = 2 + LEDBUFFSIZE / MAX_DMA_BUFFER, // min = 2, max = 128
.dma_buf_len = MAX_DMA_BUFFER,
.use_apll = false,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1};
esp_err_t stat1 = i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_BCK_IO,
.ws_io_num = I2S_WS_IO,
.data_out_num = I2S_DO_IO,
.data_in_num = I2S_DI_IO};
esp_err_t stat2 = i2s_set_pin(I2S_NUM, &pin_config);
If the gaps would be there all the time with the constant data, then the problem could be in my code or ESP IDF 4.1, but now it probably is in the hardware.