← До всіх проєктів
Сенсори Складний

Шумомір на цифровому мікрофоні INMP441 (I2S)

Цифровий MEMS-мікрофон передає звук по I2S без шумів АЦП. Рахуємо RMS, переводимо в децибели й вмикаємо сигнал, коли в кімнаті стає занадто гучно. Основа для голосових і звукореактивних проєктів.

Складність
Складний
Час
2 h
Категорія
Сенсори

Чому I2S, а не аналоговий мікрофон

Аналогові модулі (MAX4466, KY-038) читаються через АЦП ESP32, який шумить і нелінійний. INMP441 — цифровий мікрофон: він сам оцифровує звук (24 біти) і віддає його по шині I2S. Результат — чистий сигнал, який годиться і для вимірювання гучності, і для FFT, і для розпізнавання голосу.

Компоненти

  • ESP32 DevKit
  • Модуль мікрофона INMP441
  • Світлодіод (або вбудований на GPIO 2) — індикатор «занадто гучно»

Підключення

INMP441 ESP32
VDD 3V3
GND GND
L/R GND (лівий канал)
WS GPIO 25
SCK GPIO 32
SD GPIO 33

Код

Використовуємо бібліотеку ESP_I2S з ядра arduino-esp32 3.x — встановлювати нічого не потрібно.

#include <ESP_I2S.h>
#include <math.h>

const int PIN_SCK = 32;
const int PIN_WS  = 25;
const int PIN_SD  = 33;
const int LED_PIN = 2;

const uint32_t SAMPLE_RATE = 16000;
const int SAMPLES = 1024;               // 64 мс звуку
const float LOUD_DB = 70.0;             // поріг «занадто гучно»

// INMP441: −26 dBFS при 94 dB SPL → dB SPL ≈ dBFS + 120
const float DBFS_TO_SPL = 120.0;

I2SClass i2s;
int32_t buffer[SAMPLES];
float smoothed = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);

  i2s.setPins(PIN_SCK, PIN_WS, -1, PIN_SD);   // bclk, ws, dout (не використовується), din
  if (!i2s.begin(I2S_MODE_STD, SAMPLE_RATE, I2S_DATA_BIT_WIDTH_32BIT,
                 I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT)) {
    Serial.println("I2S init failed");
    while (true) delay(1000);
  }
  // Перші миттєвості після старту мікрофон видає сміття — пропускаємо
  i2s.readBytes((char *)buffer, sizeof(buffer));
}

void loop() {
  size_t bytes = i2s.readBytes((char *)buffer, sizeof(buffer));
  int n = bytes / sizeof(int32_t);
  if (n == 0) return;

  // 24-бітний звук лежить у старших бітах 32-бітного слова
  double sum = 0;
  for (int i = 0; i < n; i++) sum += buffer[i] >> 8;
  double mean = sum / n;                     // постійна складова

  double sq = 0;
  for (int i = 0; i < n; i++) {
    double s = (buffer[i] >> 8) - mean;
    sq += s * s;
  }
  double rms = sqrt(sq / n);
  if (rms < 1) rms = 1;

  float dbfs = 20.0 * log10(rms / 8388608.0);   // 2^23 — повна шкала
  float spl = dbfs + DBFS_TO_SPL;

  // Згладжування, щоб цифри не «скакали»
  smoothed = smoothed == 0 ? spl : smoothed * 0.8 + spl * 0.2;

  digitalWrite(LED_PIN, smoothed > LOUD_DB ? HIGH : LOW);
  Serial.printf("dB:%.1f\n", smoothed);          // формат для Serial Plotter
}

Перевірка

  1. Відкрийте Tools → Serial Plotter — побачите графік рівня звуку.
  2. Тиха кімната — близько 30–40 dB, розмова — 55–65 dB, плескіт у долоні — 80+ dB.
  3. Коли рівень перевищить 70 dB, засвітиться світлодіод.

Точність

Це оцінка, а не сертифікований шумомір:

  • Поправка +120 взята з паспортної чутливості INMP441 (−26 dBFS @ 94 dB SPL); конкретний екземпляр може відрізнятися на ±1–3 dB. Відкалібруйте за справжнім шумоміром або застосунком на телефоні, змінивши DBFS_TO_SPL.
  • Справжні шумоміри застосовують частотну корекцію A (dBA). Для цього потрібен цифровий фільтр — хороша наступна задача.
  • Мікрофон не любить вологи й пилу — у корпусі залиште для нього отвір із сіткою.

Ідеї

  • Індикатор шуму в класі чи open space: зелений / жовтий / червоний на WS2812.
  • Лог гучності вночі в Home Assistant (див. проєкт «MQTT Discovery») — доказ для сусідів з гучною вечіркою.
  • FFT-спектроаналізатор на матриці світлодіодів (бібліотека arduinoFFT).
  • Звукореактивний WLED: INMP441 — стандартний мікрофон для збірок WLED Sound Reactive.