Atelier.

atelier · lecții

Lecția 07 25 min intermediar 3 întrebări quiz

Microfonul I2S — cum aude ESP32 sirena de ambulanță

INMP441 e un microfon digital cu 3 fire de date. ESP32 'numără' undele de sunet — sirena = nivel mare, liniștea = nivel mic. Aici înveți de ce nu-i nevoie de FFT complicat pentru concurs.

Ce înveți

  • Diferența între microfon analog și digital (I2S)
  • Ce-i I2S — 3 fire (SCK, WS, SD) ca un alfabet morse cu ritm
  • Sample rate: de ce 16000 'poze de sunet' pe secundă ajunge pentru sirenă
  • Cum 'numeri' amplitudinea (max-min) fără să faci FFT
  • De ce pinul L/R legat la GND alege canalul stânga

Înainte de această lecție: ai trecut Test 1 (LED-uri + OLED + buton) din planul VIA. Acum adaugi auz plăcii N1. Lecția asta îți deschide mintea înainte să cablezi microfonul pe joi 21 mai.

De ce microfon digital, nu analog?

Microfoanele clasice (cum sunt cele din căști sau din telefon) sunt analoage: scot o tensiune pe un fir care variază cu sunetul. Tare = tensiune mare, liniște = tensiune mică.

Problema cu analog: firul scurtă pe lângă cablajul ESP32, prinde zgomot electromagnetic, ADC-ul ESP32 nu-i super precis (12 biți). Rezultat: prinzi sunete dar și mult zgomot care nu-i acolo.

I2S e digital: microfonul (INMP441) măsoară singur sunetul, îl transformă în numere și trimite numerele pe fire. Numerele nu se „murdăresc” — fie ajung corect, fie nu ajung deloc.

Pentru un semafor care trebuie să recunoască o sirenă reală, digital e singura opțiune serioasă.

Cele 3 fire I2S — ca un alfabet morse cu ritm

Imaginează-ți că vrei să dictezi numere prietenului tău prin telefon. Aveți nevoie de 3 lucruri:

  1. SCK (ceasul) — bătăile inimii: „acum, acum, acum” la fiecare microsecundă. Microfonul folosește bătaia ca să știe când să trimită un bit.
  2. WS (Word Select) — semnalizatorul de canal: „următorul număr e pe canalul stânga” sau „următorul e pe dreapta”. Schimbă alternativ.
  3. SD (Serial Data) — datele propriu-zise: bitul curent al numărului actual (0 sau 1, citit la fiecare bătaie SCK).

Cu 3 fire transmiți milioane de numere pe secundă dintr-un microfon într-un ESP32. Nu-i magie — e doar disciplină perfectă de ritm.

Cele 3 fire I2S — SCK ritmul, WS canalul, SD biții

Ce-i interesant: I2S e folosit și de DAC-urile audio scumpe, de difuzoarele Bluetooth de top, de procesoare audio profesionale. Același protocol pe care-l folosești tu pentru un semafor de 110 lei.

Sample rate — câte „poze” pe secundă

Microfonul ia poze ale sunetului, foarte des. Câte? Asta-i sample rate: numărul de samples (numere) pe secundă.

  • 8000 Hz — calitatea telefonului fix din anii 1990 (înțelegi vocea, dar nu super clar)
  • 16000 Hz — calitate „voce decentă” (Whatsapp folosește asta)
  • 44100 Hz — calitate CD (muzică)
  • 96000 Hz — calitate studio profesional

Pentru sirenă: 16000 Hz e perfect.

De ce nu mai mult?

Regula Nyquist din fizică: ca să detectezi o frecvență de N Hz, trebuie să iei poze la minim 2N Hz. Sirena de ambulanță e între 500-1700 Hz, deci ai nevoie minim 3400 Hz. La 16000 Hz ai marjă de — sigur o prinzi.

Mai mult înseamnă mai multe date = ESP32 nu mai are timp să facă altceva. La 96000 Hz ar primi 96000 numere pe secundă pe canal × 2 canale × 4 bytes = 768 KB/s. ESP32 are doar 320 KB RAM total. Nu merge.

Cum detectezi sirena fără FFT

FFT (Fast Fourier Transform) e modul „științific” de a detecta o frecvență: descompui sunetul în frecvențele componente. E precis dar complicat și greu de înțeles la 12 ani.

Vestea bună: pentru concurs n-ai nevoie de FFT. Sirena de ambulanță e mai tare decât zgomotul ambiental (vocile, vântul, foșnetul).

Ce faci în schimb:

1. Citești 512 mostre (samples) de la microfon (~32 ms la 16 kHz)
2. Calculezi MAX dintre ele
3. Calculezi MIN dintre ele
4. Diferența MAX-MIN = AMPLITUDINEA — cât de tare-i sunetul
5. Dacă amplitudinea > PRAG_SIRENA → e gălăgie → posibil sirenă

5 pași. Nicio matematică complicată. Funcționează pentru concurs.

Dezavantajul

Dacă cineva strigă tare lângă microfon, contează ca „sirenă”. Adică ai false alarms. Dar pentru demo, judecătorii vor pune sirena MP3-ului pe telefon — care-i clar mai tare ca o voce normală.

După concurs, dacă vrei să fii sigur că-i ÎNTR-ADEVĂR sirenă (nu plâns de copil), atunci treci la FFT. Asta-i lecția 10+ a viitorului.

Cele 6 fire de conexiune

Microfonul INMP441 are 6 pini:

Pin INMP441La ce-l legiDe ce
VCC3.3V pe ESP32Alimentare — NU 5V, ar arde cipul
GNDGND comunPunctul de referință (lacul)
L/RGNDSelectează canalul stânga
WSGPIO 15Word Select — canal stânga/dreapta
SCKGPIO 14Clock — ritmul
SDGPIO 32Serial Data — biții propriu-ziși

Atenție: GPIO 15 și GPIO 32 sunt pini „normali” pe ESP32. Evită GPIO 0, 2, 12 (strapping) — pot strica boot-ul. Vezi lecția 07 — ESP32 pini.

Codul minim (Arduino)

#include <driver/i2s.h>

#define I2S_PORT     I2S_NUM_0
#define SCK_PIN      14
#define WS_PIN       15
#define SD_PIN       32
#define SAMPLE_RATE  16000
#define BUFFER_SIZE  512

int32_t buffer[BUFFER_SIZE];

void setup() {
  Serial.begin(115200);

  // Configurez I2S în mod „master receive"
  i2s_config_t cfg = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = SAMPLE_RATE,
    .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 = 0,
    .dma_buf_count = 4,
    .dma_buf_len = 512,
    .use_apll = false,
  };
  i2s_pin_config_t pins = {
    .bck_io_num = SCK_PIN,
    .ws_io_num = WS_PIN,
    .data_out_num = -1,
    .data_in_num = SD_PIN,
  };

  i2s_driver_install(I2S_PORT, &cfg, 0, NULL);
  i2s_set_pin(I2S_PORT, &pins);
  Serial.println("OK: Microfon I2S");
}

void loop() {
  size_t citit = 0;
  i2s_read(I2S_PORT, buffer, sizeof(buffer), &citit, portMAX_DELAY);

  // Calculez amplitudinea (max - min)
  int32_t maxim = -2147483648, minim = 2147483647;
  for (int i = 0; i < BUFFER_SIZE; i++) {
    if (buffer[i] > maxim) maxim = buffer[i];
    if (buffer[i] < minim) minim = buffer[i];
  }
  int32_t amplitudine = (maxim - minim) >> 16;  // scalez

  Serial.print("Amplitudine: ");
  Serial.println(amplitudine);

  if (amplitudine > 3000) {  // PRAG_SIRENA, reglezi prin observație
    Serial.println("!! SIRENA !!");
  }

  delay(50);  // 20 măsurători pe secundă, destul pentru sirenă
}

Cum reglezi PRAG_SIRENA:

  1. Flashezi codul cu PRAG=3000 (estimare inițială)
  2. Deschizi Serial Monitor la 115200
  3. Stai într-o cameră liniștită — vezi amplitudinea naturală (~500-1500)
  4. Pornești sirena MP3 lângă microfon — vezi cât urcă (probabil 5000-15000)
  5. Setezi PRAG undeva la mijloc, ex: 3500

Pragul depinde de distanță și volum. Reglezi pentru locul tău.

Troubleshoot rapid

Tabelul complet e în planul VIA — Test 2. Aici doar cele mai dese probleme:

SimptomVerifici
Serial Monitor blankBaud rate setat la 115200
„OK: Microfon I2S” nu apareCablajul SCK→14, WS→15, SD→32 (verifică cu schița)
Levelul oscilează fără sunetL/R neconectat — leagă la GND
Sună mereu sirenaPRAG_SIRENA prea jos — crește

Pas următor — Test 3 (mesh ESP-NOW)

Acum că placa N1 aude, e timpul să vorbească cu N2. Lecția 07e — ESP-NOW radio direct îți arată cum 2 ESP32-uri vorbesc fără router, ca walkie-talkies.

După lecția asta, poți

  • Conectezi orice microfon I2S fără să te uiți la datasheet de 30 pagini
  • Citești samples brute în Serial Monitor și recunoști sunete diferite (liniște / vorbă / sirenă)
  • Știi când amplitudinea simplă ajunge și când chiar ai nevoie de FFT
  • Înțelegi de ce I2S e mai precis decât microfonul analog din telefon