: ESP32-S3 + INMP441 on PlatformIO; build/upload OK and model runs, but I2S samples are always zero, ESP32-S3-DevKitC-1-N16R8V, INMP441 wired BCLK=GPIO17, WS=GPIO18, SD=GPIO16, L/R=GND, VCC=3.3V, GND=GND. USB-C on COM11 (CDC).PlatformIO board=esp32-s3-dev

.ino file

#define I2S_BCK_PIN 17 // Bit clock
#define I2S_WS_PIN 18  // Word select
#define I2S_SD_PIN 16  // Serial data
#define I2S_PORT I2S_NUM_0
 this is my hardware config


.cpp file

AudioProcessor::AudioProcessor(int bckPin, int wsPin, int sdPin,

                               float input_scale, int input_zero_point, i2s_port_t port)

    : _audio_buffer(nullptr), _i2sPort(port), _sampleRate(0),

      _write_index(0), _samples_collected(0),

      _frame_position(0), _hop_counter(0),

      _input_scale(input_scale), _input_zero_point(input_zero_point)

{

    _pinConfig.bck_io_num = bckPin;

    _pinConfig.ws_io_num = wsPin;

    _pinConfig.data_out_num = I2S_PIN_NO_CHANGE;

    _pinConfig.data_in_num = sdPin;



    memset(_frame_buffer, 0, sizeof(_frame_buffer));

}



AudioProcessor::~AudioProcessor()

{

    i2s_driver_uninstall(_i2sPort);

}



bool AudioProcessor::begin(int sampleRate)

{

    _sampleRate = sampleRate;



    Serial.println("Initializing Audio Processor...");

    Serial.printf("Sample rate: %d Hz\n", _sampleRate);

    Serial.printf("Analysis window: %d seconds\n", ANALYSIS_SECONDS);

    Serial.printf("Buffer size: %d samples\n", BUFFER_SAMPLES);



    // Initialize MFCC extractor

    if (!_mfcc_extractor.begin())

    {

        Serial.println("Failed to initialize MFCC extractor");

        return false;

    }



    // Configure I2S

    i2s_config_t i2sConfig = {

        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),

        .sample_rate = static_cast<uint32_t>(_sampleRate),

        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,

        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,

        .communication_format = I2S_COMM_FORMAT_STAND_I2S,

        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,

        .dma_buf_count = 8,

        .dma_buf_len = 256,

        .use_apll = false,

        .tx_desc_auto_clear = false,

        .fixed_mclk = 0};



    // Install I2S driver

    esp_err_t err = i2s_driver_install(_i2sPort, &i2sConfig, 0, NULL);

    if (err != ESP_OK)

    {

        Serial.printf("Failed installing I2S driver: %d\n", err);

        return false;

    }



    // Set I2S pins

    err = i2s_set_pin(_i2sPort, &_pinConfig);

    if (err != ESP_OK)

    {

        Serial.printf("Failed setting I2S pins: %d\n", err);

        i2s_driver_uninstall(_i2sPort);

        return false;

    }



    // Explicitly set clock for mono 32-bit samples

    err = i2s_set_clk(_i2sPort, _sampleRate, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO);

    if (err != ESP_OK)

    {

        Serial.printf("Failed setting I2S clock: %d\n", err);

        i2s_driver_uninstall(_i2sPort);

        return false;

    }



    // Clear DMA buffer

    i2s_zero_dma_buffer(_i2sPort);



    Serial.println("Audio Processor initialized successfully");

    return true;

}



float AudioProcessor::convertI2SToFloat(int32_t i2s_sample)

{

    // INMP441: 24-bit audio in 32-bit container

    // Extract 24-bit value (right-shift 8 bits)

    int32_t audio_24bit = i2s_sample >> 8;



    // Sign extend if negative (24-bit signed to 32-bit signed)

    if (audio_24bit & 0x00800000)

    {

        audio_24bit |= 0xFF000000;

    }



    // Convert to float in range [-1.0, 1.0]

    // 24-bit signed range: -8388608 to 8388607

    return (float)audio_24bit / 8388608.0f;

}



void AudioProcessor::quantizeMFCC(const float *mfcc_float, int8_t *mfcc_int8)

{

    // Quantize using model's exact parameters

    for (int i = 0; i < NUM_INPUTS; i++)

    {

        // Formula: quantized = round(value / scale + zero_point)

        float scaled = mfcc_float[i] / _input_scale;

        int32_t quantized = (int32_t)roundf(scaled + _input_zero_point);



        // Clamp to int8 range (safety)

        if (quantized > 127)

            quantized = 127;

        if (quantized < -128)

            quantized = -128;



        mfcc_int8[i] = (int8_t)quantized;

    }

}



int AudioProcessor::read(int32_t *buffer, int bufferLength)

{

    size_t bytesRead = 0;



    // Read I2S data (blocking)

    esp_err_t err = i2s_read(_i2sPort,

                             (void *)buffer,

                             bufferLength * sizeof(int32_t),

                             &bytesRead,

                             portMAX_DELAY);



    if (err != ESP_OK)

    {

        Serial.printf("I2S read error: %d\n", err);

        return 0;

    }



    int samplesRead = (int)(bytesRead / sizeof(int32_t));



    // Convert and store in circular buffer

    for (int i = 0; i < samplesRead; i++)

    {

        float sample = convertI2SToFloat(buffer[i]);



        // Store in circular buffer

        _audio_buffer[_write_index] = sample;

        _write_index = (_write_index + 1) % BUFFER_SAMPLES;

        _samples_collected++;



        // Keep track of the most recent samples

        if (_samples_collected > BUFFER_SAMPLES)

        {

            _samples_collected = BUFFER_SAMPLES;

        }

    }



    return samplesRead;

}