esp32-i2s

How to use the I2S bus on an ESP32

  • 3 min

The Inter-Integrated Circuit Sound (I2S) is a synchronous serial communication protocol used to transmit digital audio data between devices.

I2S is a protocol designed to transmit digital audio data between devices (such as microphones, audio sensors, DACs (Digital-to-Analog Converters), ADCs (Analog-to-Digital Converters), and other audio peripherals).

Unlike other communication protocols, such as I2C or SPI, I2S is optimized for real-time audio data transmission.

The I2S protocol uses three main lines:

  1. Serial Clock (SCK): This line provides the master clock that synchronizes bit transmission between devices.

  2. Word Select (WS): Also known as the word clock line, it indicates when a new word of data begins (for example, a new audio channel).

  3. Data Line (SD): Carries the actual digital audio data.

Using I2S on ESP32

To use I2S on the ESP32, we must first configure the I2S driver parameters using the libraries and functions provided by the Espressif SDK.

This includes configuring the clock, audio data format, number of channels, data direction, among others.

#include "driver/i2s.h"

void configureI2S() {
    i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_LEADER | I2S_MODE_TX), // Leader mode and transmission
        .sample_rate = 44100, // Sample rate in Hz
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // Only right channel
        .communication_format = I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 8,
        .dma_buf_len = 64,
        .use_apll = false
    };
    
    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
}
Copied!

Once the I2S driver is configured, we can transmit digital audio data. This involves properly packing the audio data and sending it over the I2S bus.

void transmitAudioData(const uint8_t *data, size_t len) {
    i2s_write_bytes(I2S_NUM_0, (const char *)data, len, portMAX_DELAY);
}
Copied!

Code Example

Let’s see what an example of using I2S on the ESP32 for real-time audio processing would look like.

We can capture audio from a microphone, apply sound effects, and then play the processed audio through a speaker or headphones.

The final code will depend on the specific device, microphone, or speaker we are using. But it generally looks something like this.

void processAudioData(const uint8_t *inputData, uint8_t *outputData, size_t len) {
    // Apply audio processing effects to inputData and store the result in outputData
}

void audioProcessingTask(void *arg) {
    uint8_t inputData[1024];
    uint8_t outputData[1024];
    
    while (1) {
        // Capture audio data from the microphone using I2S
        i2s_read_bytes(I2S_NUM_0, inputData, sizeof(inputData), portMAX_DELAY);
        
        // Process the audio data
        processAudioData(inputData, outputData, sizeof(inputData));
        
        // Transmit the processed audio data through I2S
        transmitAudioData(outputData, sizeof(outputData));
    }
}

void app_main() {
    configureI2S();
    
    xTaskCreate(audioProcessingTask, "audio_task", 4096, NULL, 5, NULL);
}
Copied!