Language: EN


How to use the I2S bus on an ESP32

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, DAC (Digital-to-Analog Converters), ADC (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 the transmission of bits between devices.

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

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

Using I2S on ESP32

To use I2S on ESP32, we first need to configure the I2S controller 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_MASTER | I2S_MODE_TX), // Master mode and transmission
        .sample_rate = 44100, // Sampling frequency 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);

Once the I2S controller is configured, we can transmit digital audio data. This involves properly packaging the audio data and sending it through the I2S bus.

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

Code Example

Let’s see an example of using I2S on ESP32 for real-time audio processing.

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 device, microphone, or speaker being used. But it looks something like this.

void processAudioData(const uint8_t *inputData, uint8_t *outputData, size_t len) {
    // Apply audio processing effects to the 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() {
    xTaskCreate(audioProcessingTask, "audio_task", 4096, NULL, 5, NULL);