Zvukový senzor MAX9814

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Zvukový senzor MAX9814

Příspěvek od kiRRow » 27 úno 2023, 20:43

Proběhni si komentáře pod tím návodem co jsi okopíroval. Lidi tam breptají, že je to pro špatný senzor a že ta část kódu s přepočítáváním na dB je špatně napsaná.

Další způsob jak detekci vylepšit je nemít pouze jeden sample, ale nasaplovat od určitého okamžiku určitý počet vzorků a sledovat v nich určité vzory. Jako příklad si vem třeba detektor rozbití skla u alarmu. Ten funguje tak, že očekává nízkofrekvenční zvuk (tlakovou vlnu, která vznikne prohnutím okenní tabule - těsně předtím než praskne), když jí zachytí začne "vyhledávat" vysokofrekvenční zvuk, který vydává tříštící se sklo dopadající na zem. Když se tento detektor testuje, tak máš krabičku kterou položíš na hlídanou střeženou plochu a opatrně udeříš do skla (abys ho nerozbil, ale jen vyvolal onu tlakovou vlnu) a ta krabička (pozná že si klepnul do skla) ti vydá zvuk tříštění skla. Taky se dá spustit tak, že do něj ťukneš a zatřepeš před ním svazkem klíčů :lol:

Pin AR je k nastavení zesílení toho zesilovače ... nepřipojen má 60dB, propojený s zemí má 50dB a propojený se VCC má 40dB

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Zvukový senzor MAX9814

Příspěvek od kiRRow » 27 úno 2023, 21:43

pokornja píše:
26 úno 2023, 16:12
Dívám se ještě na tu dolní propust - chápu to správně, že by mi stačilo dát mezi analogový výstup ze zvukového snímače a pin arduina odpor (např. 220 ohm) a k tomu paralelně se zemí kondenzátor 100 nF a ořeže mi to vše nad cca 7 kHz? :o
Jedná se o sériové zapojení, je to v podstatě odporový dělič, kde R1 je odpor a místo R2 je kondenzátor. Na kondenzátor pak připojíš analogový vstup arduina. Fígl je v tom, že kondenzátor klade při různých frekvencích různý odpor, tohle závisí na kapacitě toho kondenzátoru. Nízkým frekvencím bude klást velký odpor a proto je dostaneš na ten analogový pin, vysoké frekvence svede k zemi, protože jim neklade odpor. V podstatě se ten kondenzátor brání tomu, že mu chceš přehodit napětí - nízká frekvence ho déle nabíjí a je na něm větší napětí a náboj, když ho pak chceš pomalu změnit na opačnou polaritu bude se více bránit = bude mít větší "odpor", vznikne na něm úbytek napětí a ten čteš. Se zvyšující se frekvencí se nestíhá tak moc nabíjet a nemá pak takovou tendenci klást odpor, nevznikne úbytek napětí a na pinu arduina máš 0V.

pokornja
Příspěvky: 25
Registrován: 09 led 2023, 13:50
Reputation: 0

Re: Zvukový senzor MAX9814

Příspěvek od pokornja » 27 úno 2023, 22:22

Děkuju moc za pěkné vysvětlení, teď tomu rozumím. Zkusil jsem tu dolní propust zapojit už včera, měl jsem tu jeden 10 uF kondenzátor a 220 ohm odpor, a naprosto brutálním způsobem mi to pomohlo ve filtrování signálu, který potřebuju detekovat (to je to dupání, které má jen nízké frekvence). Mám to tedy zapojené tak, že z výstupu na zvukovém modulu to jde na nepájivé pole, za tím pokračuje rezistor, pak to jde na analogový vstup arduina a ve stejné lince mám kondenzátor, který končí záporným pólem na zemi. A vypadá to, že to funguje naprosto spolehlivě. Zkusím si ještě sehnat různé kombinace odpor/kondenzátor, ať se dostanu kousek nad 100 Hz, víc asi nepotřebuju. Každopádně děkuju moc, toto byl pro mě zcela zásadní posun, jste borci! :) ;)
Teď jsem ještě zkusil pin A/R zapojit na zem a už to po intenzivním zvuku nemá ty prodlevy, takže další posun vpřed. Pomocí A/R se tedy reguluje „Attack and Release Ratio“, ne zesílení, to je na pinu Gain :)
Už mi teda chybí jen vyladit ten kód pro převod analogového výstupu na „hlasitost“. To bude asi ještě oříšek. Chtěl bych ty příkazy totiž i pochopit... :lol:

Kód: Vybrat vše

const int sampleWindow = 10;                              // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

int zvuk = A0;
int LED_G = 2;
int LED_Y = 4;
int LED_R = 6;
int bzucak = 12;


void setup() {
  // put your setup code here, to run once:

pinMode (zvuk, INPUT);
pinMode (LED_G, OUTPUT);
pinMode (LED_Y, OUTPUT);
pinMode (LED_R, OUTPUT);
pinMode (bzucak, OUTPUT);
digitalWrite (LED_G, LOW);
digitalWrite (LED_Y, LOW);
digitalWrite (LED_R, LOW);
digitalWrite (bzucak, LOW);
Serial.begin (115200);
}


void loop() {
  // put your main code here, to run repeatedly:


unsigned long startMillis= millis();                      // Start of sample window
   float peakToPeak = 0;                                  // peak-to-peak level
 
   unsigned int signalMax = 0;                            //minimum value
   unsigned int signalMin = 1024;                         //maximum value
 
                                                          // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(zvuk);                          //get reading from microphone
      if (sample < 1024)                                  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;                           // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;                           // save just the min levels
         }
      }
   }
 
   peakToPeak = signalMax - signalMin;                    // max - min = peak-peak amplitude
   int dB = map(peakToPeak,20,900,49.5,90);               //calibrate for deciBels
 

 Serial.print(48);
 Serial.print(" ");
 Serial.print(70);
 Serial.print(" ");
 Serial.println(dB);
  

  if (dB >= 55){
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_Y, HIGH);
    digitalWrite (LED_R, HIGH);
    digitalWrite (bzucak, HIGH);
    delay (100);
    digitalWrite (bzucak, LOW);
    delay (60);                                //počkat na ozvěnu
  }

  else if (dB < 55 && dB >= 53){
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_Y, HIGH);
    digitalWrite (LED_R, LOW);
  }

  else if (dB < 53 && dB > 50){
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_Y, LOW);
    digitalWrite (LED_R, LOW);
  }

  else{
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_Y, LOW);
    digitalWrite (LED_R, LOW);
  }

}

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Zvukový senzor MAX9814

Příspěvek od kiRRow » 28 úno 2023, 14:43

Kód: Vybrat vše

   unsigned long startMillis= millis();                      // zde si to uloží čas začátku samplování
   float peakToPeak = 0;                                 	 // proměnná do které se pak uloží rozdíl mezi maximem a minimem
 
   unsigned int signalMax = 0;                            //vyresetování maximální naměřené hodnoty 
   unsigned int signalMin = 1024;                         //vyresetování minimální naměřené hodnoty 
 
                                                          // samotné měření na analogovém pinu
   while (millis() - startMillis < sampleWindow)
   {									//cykluj dokud neuběhne čas sampleWindow
      sample = analogRead(zvuk);                          //přečti mikrofon
      if (sample < 1024)                                  // vyhodí maximální špičky
      {
         if (sample > signalMax)
         {
            signalMax = sample;                           // pokud je sample větší než prozatimní naměřené maximum, nastav nové maximum
         }
         else if (sample < signalMin)
         {
            signalMin = sample;                           // pokud je sample menší než prozatimní naměřené minimum, nastav nové minimum
         }
      }
   }
 
   peakToPeak = signalMax - signalMin;                    // vypočítá rozdíl mezi naměřeným maximem a minimem
   int dB = map(peakToPeak,20,900,49.5,90);               //tento rozdíl je pak přemapován na decibely
 

 Serial.print(48); // výpis do seriové linky
 Serial.print(" ");
 Serial.print(70);
 Serial.print(" ");
 Serial.println(dB);

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Zvukový senzor MAX9814

Příspěvek od kiRRow » 28 úno 2023, 19:22

Já osobně bych pokračoval směrem, že bych si nahrál do počítače zvuk dupnutí za dolno propust filtrem... a ne jenom jeden, ale desítky. Pak bych je začal porovnávat vůči sobě v čem se podobají. Pak bych si i nahrál přes filtr zvuky které jsou okolní a pozoroval v čem se odlišují od těch co se podobají dupnutí.

Budu střílet od boku neber ty čísla vážně, jde o princip :
Když dupnu, tak se mi odfiltrovaná část nejprve zvedne na nějakou hodnotu (nadává se tomu threshold - hranice) (dejme tomu bez jakéhokoliv přepočtu, holý analogRead dá 300) a od té doby chci udělat 64vzorků za dobu 32ms (zpracuje se potom) ... dupnutí trvá dejme tomu 20ms ...
Až odběhne oněch 32ms a já mám 64vzorků, tak (dejme tomu) všechna dupnutí mají za tu dobu přibližne 8-12 fakt velkých špiček (dejme tomu přes 900 holý analogRead), ale pokud je jich méně, nebo více (proto na 20ms dupnutí mám 32ms sbírku údajů), tak to třeba může znamenat že někdo tlesknul (není to tak bass zvuk, filtr odstraní zbytek dostanu jen 2špičky), nebo že někdo vrtá díru do zdi (to fakt někdy duní celý barák a špiček dostanu 16)
Není to nic těžkého, jen budeš muset pochopit a umět použít pole proměnných a cykly v programu. Seřadí ti to krásně měření po sobě a pak se v tom i můžeš pěkně prohrabat a zpracovat si to později v programu, nebo k datům přistupovat libovolně.

Hlídej si ale % obsazení paměti při kompilaci programu. Takové to pole je pak lepší deklarovat mimo loop a setup na začátku programu, proč to zjistíš později v mnohem složitějších projektech.

Mrkni na věci jako for, while a array.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 14 hostů