esp32-i2s

Cómo usar el bus I2S en un ESP32

El Inter-Integrated Circuit Sound (I2S) es un **protocolo de comunicación serial síncrono **utilizado para transmitir datos de audio digital entre dispositivos.

El I2S es un protocolo diseñado para transmitir datos de audio digital entre dispositivos (como micrófonos, sensores de audio, DAC (Convertidores Analógico-Digital), ADC (Convertidores Digital-Analógico) y otros periféricos de audio).

A diferencia de otros protocolos de comunicación, como el I2C o el SPI, el I2S está optimizado para la transmisión de datos de audio en tiempo real.

El protocolo I2S utiliza tres líneas principales:

  1. Serial Clock (SCK): Esta línea proporciona el reloj maestro que sincroniza la transmisión de bits entre los dispositivos.

  2. Word Select (WS): También conocida como línea de reloj de palabra, indica cuándo comienza un nuevo dato de palabra (por ejemplo, un nuevo canal de audio).

  3. Data Line (SD): Transporta los datos digitales de audio en sí.

Uso del I2S en ESP32

Para utilizar el I2S en el ESP32 primero debemos configurar los parámetros del controlador I2S utilizando las bibliotecas y funciones proporcionadas por el SDK de Espressif.

Esto incluye la configuración del reloj, el formato de los datos de audio, el número de canales, la dirección de datos, entre otros.

#include "driver/i2s.h"

void configureI2S() {
    i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), // Modo maestro y transmisión
        .sample_rate = 44100, // Frecuencia de muestreo en Hz
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // Solo canal derecho
        .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);
}

Una vez configurado el controlador I2S, podemos transmitir datos de audio digital. Esto implica empaquetar adecuadamente los datos de audio y enviarlos a través del bus I2S.

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

Ejemplo de código

Vamos a ver cómo sería un ejemplo de uso del I2S en ESP32 es el procesamiento de audio en tiempo real.

Podemos capturar audio de un micrófono, aplicar efectos de sonido y luego reproducir el audio procesado a través de un altavoz o auriculares.

El código final dependerá del dispositivo, micrófono, o altavoz, que estemos usando. Pero más o menos tienen una pinta así.

void processAudioData(const uint8_t *inputData, uint8_t *outputData, size_t len) {
    // Aplicar efectos de procesamiento de audio al inputData y almacenar el resultado en outputData
}

void audioProcessingTask(void *arg) {
    uint8_t inputData[1024];
    uint8_t outputData[1024];
    
    while (1) {
        // Capturar datos de audio desde el micrófono utilizando I2S
        i2s_read_bytes(I2S_NUM_0, inputData, sizeof(inputData), portMAX_DELAY);
        
        // Procesar los datos de audio
        processAudioData(inputData, outputData, sizeof(inputData));
        
        // Transmitir los datos de audio procesados a través de I2S
        transmitAudioData(outputData, sizeof(outputData));
    }
}

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