Шумомір на цифровому мікрофоні INMP441 (I2S)
Цифровий MEMS-мікрофон передає звук по I2S без шумів АЦП. Рахуємо RMS, переводимо в децибели й вмикаємо сигнал, коли в кімнаті стає занадто гучно. Основа для голосових і звукореактивних проєктів.
Чому 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
}
Перевірка
- Відкрийте Tools → Serial Plotter — побачите графік рівня звуку.
- Тиха кімната — близько 30–40 dB, розмова — 55–65 dB, плескіт у долоні — 80+ dB.
- Коли рівень перевищить 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.