Загрузка данных


#include <driver/i2s_std.h>

i2s_chan_handle_t rx_chan;

// Настройки для усреднения
const int SAMPLES_TO_READ = 160; // 16000 Гц * 0.01 сек = 160 сэмплов за 10мс

void setup() {
  Serial.begin(115200);
  while (!Serial) { delay(10); } // Ожидание подключения Serial (для CDC)

  i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
  i2s_new_channel(&chan_cfg, NULL, &rx_chan);

  i2s_std_config_t cfg = {
    .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
    .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
    .gpio_cfg = {
      .mclk = I2S_GPIO_UNUSED,
      .bclk = GPIO_NUM_4,
      .ws   = GPIO_NUM_5,
      .dout = I2S_GPIO_UNUSED,
      .din  = GPIO_NUM_3,
      .invert_flags = { .mclk_inv = false, .bclk_inv = false, .ws_inv = false }
    }
  };

  i2s_channel_init_std_mode(rx_chan, &cfg);
  i2s_channel_enable(rx_chan);
}

void loop() {
  // Буфер для накопления 160 сэмплов по 32 бита
  int32_t samples_buffer[SAMPLES_TO_READ];
  size_t bytes_read = 0;

  // Читаем сразу пачку сэмплов на 10 мс
  esp_err_t err = i2s_channel_read(rx_chan, samples_buffer, sizeof(samples_buffer), &bytes_read, 100);

  if (err == ESP_OK && bytes_read > 0) {
    int samples_count = bytes_read / sizeof(int32_t);
    
    uint64_t sum = 0;
    for (int i = 0; i < samples_count; i++) {
      // Некоторые I2S микрофоны (например, INMP441) выдают знаковое число.
      // Берем модуль значения, чтобы избавиться от отрицательной полуволны.
      sum += abs(samples_buffer[i]);
    }

    if (samples_count > 0) {
      uint32_t average_amplitude = sum / samples_count;
      Serial.println(average_amplitude);
    }
  }
}