Как заставить ESP32 петь: аудио через I2S

Решил разобраться, как вывести звук с ESP32. В моих проектах часто использую эту плату, но с аудио раньше не сталкивался. Оказалось, всё не так сложно, как кажется на первый взгляд.

Под капотом I2S

I2S — это интерфейс для передачи аудиоданных. На ESP32 он реализован через встроенный модуль. Подключил я его к DAC (цифро-аналоговому преобразователю) и вуаля — звук пошёл. Главное — правильно настроить конфиг.

Пример кода

Вот пример кода, который позволяет выводить звук через I2S:



#include "driver/i2s.h"

// Создаем тестовый буфер (например, на 64 сэмпла)
const int size = 128;
uint8_t buffer[size] = {0}; 

void setup() {
  // 1. Конфигурация самого I2S
  i2s_config_t cfg = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = 44100,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S, 
    .dma_buf_count = 8,                                 // Обязательные параметры DMA
    .dma_buf_len = 64,
    .use_apll = false
  };
  
  i2s_driver_install(I2S_NUM_0, &cfg, 0, NULL);

  // 2. Обязательное назначение пинов (укажите свои GPIO)
  i2s_pin_config_t pins = {
    .bck_io_num = 26,   // Bit Clock
    .ws_io_num = 25,    // Word Select (L/R Clock)
    .data_out_num = 22, // Data Out
    .data_in_num = I2S_PIN_NO_CHANGE
  };
  i2s_set_pin(I2S_NUM_0, &pins);
}

void loop() {
  size_t bytes_written; // Переменная для записи результата
  
  // Отправка данных на выход с контролем отправленных байт
  i2s_write(I2S_NUM_0, buffer, size, &bytes_written, portMAX_DELAY);
}#include "driver/i2s.h" // Корректное подключение библиотеки

// Создаем тестовый буфер (например, на 64 сэмпла)
const int size = 128;
uint8_t buffer[size] = {0}; 

void setup() {
  // 1. Конфигурация самого I2S
  i2s_config_t cfg = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
    .sample_rate = 44100,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S, // Исправленный флаг формата
    .dma_buf_count = 8,                                 // Обязательные параметры DMA
    .dma_buf_len = 64,
    .use_apll = false
  };
  
  i2s_driver_install(I2S_NUM_0, &cfg, 0, NULL);

  // 2. Обязательное назначение пинов (укажите свои GPIO)
  i2s_pin_config_t pins = {
    .bck_io_num = 26,   // Bit Clock
    .ws_io_num = 25,    // Word Select (L/R Clock)
    .data_out_num = 22, // Data Out
    .data_in_num = I2S_PIN_NO_CHANGE
  };
  i2s_set_pin(I2S_NUM_0, &pins);
}

void loop() {
  size_t bytes_written; // Переменная для записи результата
  
  // Отправка данных на выход с контролем отправленных байт
  i2s_write(I2S_NUM_0, buffer, size, &bytes_written, portMAX_DELAY);
}

Теперь можно накатить любую мелодию и послушать, как ESP32 поёт. Главное — не забыть про костыли для подключения динамика.