// I2S digital MEMS microphone driver (INMP441-family — L/R, WS, SCK, SD // pinout, confirmed against the actual module in use). // // Unlike the browser-based EVP mode's client-side voice-band FFT // (frontend/src/lib/evp.ts), this driver does NOT attempt on-device // spectral analysis — it samples a short audio block per reporting cycle // and reports its RMS energy level in dBFS as a plain numeric reading. // The backend's existing statistical anomaly detector (the same one that // already handles temperature/pressure) does the spike detection — no // need to duplicate baseline-tracking logic on the device. This is // simpler and more honest than pretending to replicate real voice-band // filtering without ever having tested it. // // Implements the sensor_driver_t interface (see sensor_driver.h). // // Wiring (module pin names: L/R, WS, SCK, SD, VCC, GND): // Mic VCC -> 3V3 // Mic GND -> GND // Mic L/R -> GND (selects left-channel output; tie to 3V3 instead for // right-channel — either is fine, this driver reads whichever // channel the mic is configured to output) // Mic WS -> ESP32 GPIO (MEMS_MIC_I2S_WS_GPIO) -- word select / LRCLK // Mic SCK -> ESP32 GPIO (MEMS_MIC_I2S_BCLK_GPIO) -- bit clock // Mic SD -> ESP32 GPIO (MEMS_MIC_I2S_DIN_GPIO) -- serial data OUT of // the mic, IN to the ESP32 // GPIO picks avoid this board's reserved SDIO range (14-19, 54), the // BMP280's I2C pins (8/9), and the RD-03E's UART pins (4/5) -- see // README.md's pinout table for the full picture. #pragma once #include "esp_err.h" #include "sensor_driver.h" #ifdef __cplusplus extern "C" { #endif #ifndef MEMS_MIC_I2S_PORT #define MEMS_MIC_I2S_PORT 0 #endif #ifndef MEMS_MIC_I2S_BCLK_GPIO #define MEMS_MIC_I2S_BCLK_GPIO 10 #endif #ifndef MEMS_MIC_I2S_WS_GPIO #define MEMS_MIC_I2S_WS_GPIO 11 #endif #ifndef MEMS_MIC_I2S_DIN_GPIO #define MEMS_MIC_I2S_DIN_GPIO 12 #endif // 16kHz is standard for voice-band work (Nyquist covers the ~300Hz-3.4kHz // band the browser-based EVP mode watches) without the data-rate/CPU cost // of a higher rate this simple RMS-only driver doesn't need. #ifndef MEMS_MIC_SAMPLE_RATE_HZ #define MEMS_MIC_SAMPLE_RATE_HZ 16000 #endif // One reporting cycle's sample block: 256ms at 16kHz. Long enough to // average out single-sample noise, short enough to stay responsive to a // genuine brief EVP-style spike. #ifndef MEMS_MIC_SAMPLES_PER_READ #define MEMS_MIC_SAMPLES_PER_READ 4096 #endif // sensor_driver_t-compatible entry points. esp_err_t mems_mic_init(void); esp_err_t mems_mic_read(sensor_reading_t *out, size_t max_out, size_t *out_count); #ifdef __cplusplus } #endif