Stránka 2 z 3

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 13:45
od kiRRow
Ano něco by to tvořit mohlo, ale bude to reagovat na všechny frekvence ... takže i na dupnutí i na hvízdnutí. A bude ti furt jedna ledka svítit, nemáš tam stav kdy je zhasneš všechny.

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 14:37
od pokornja
Jojo, to mi teď nevadí, zase jsem se posunul o kus dál :) Nastavil jsem to tedy tak, aby se zelená LEDka zapínala až nad 52 dB.
S tím diodovým usměrňovacím můstkem je to super nápad. Ale chápu to správně, že ten kód to vlastně "usměrní" i bez můstku? Moc se v tom nemůžu zorientovat, který příkaz to tam přesně udělá, ale jestli se nepletu, tak to teď obrací tu zápornou část nahoru, ne?

Kód: Vybrat vše

const int sampleWindow = 20;                              // 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;


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) ;
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(80);
 Serial.print(" ");
 Serial.println(dB);
  

  if (dB >= 60){
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_Y, HIGH);
    digitalWrite (LED_R, HIGH);
  }

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

  else if (dB < 55 && dB > 52){
    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);
  }


}
Kreslí mi to teď něco takového, tzn. přijde mi, že to opravdu funguje jako hlukoměr.

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 14:51
od pokornja
Mám teď akorát jeden zásadní problém. Jak vyřešit to, že když k mému setupu přidám bzučák, aby to nebralo samo sebe. Teď mi to totiž vazbí i když dám na konec kódu nějakou pauzu... :?

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 15:27
od gilhad
Já bych to udělal tak, že bych si prostě nějak vyhodnotil, jestli mám bzučet, a pokud ano, tak bych chvíli bzučel a nesnímal a potom přestal bzučet a počkal podle velikosti místnosti a rychlosti zvuku, až pominou odrazy a pak teprve zase začal poslouchat.

Rychlost zvuku je asi 330 m/s, takže v místnosti o rozměrech třeba 6x4m je úhlopříčka asi sqr(6^2+4^2)=sqr(36+16)=sqr(52)=7.2m, takže nejdelší odraz je asi tak 14.4 m / (330 m/s) = 0.044 s = 44 ms
Řekněme, že se nám to neodrazí víc než dvakrát tam a zpět, takže 88ms by mohlo stačit ( zvuk uletí asi 29m a nejmíň 3x se odrazí).

Takže prostě na konec loop dát naprosto pitomé

Kód: Vybrat vše

 if (dB >= 60){ // nebo libovolná jiná hranice
   digitalWrite (Bzucak, HIGH); // zapnout bzučák
   delay(500); // půl sekundy bzučet
   digitalWrite (Bzucak, LOW); // vypnout bzučák
   delay(88); // počkat na ozvěnu
 }; // a můžeme do dalšího průběhu loop, kde se poslouchá
Je to sice naprosto blbé a blokuje to celou dobu (a počítá to s nějakým dosud nedefinovaným bzučákem), ale pro názornost by to mohlo stačit a pokud to bude furt vazbit, tak se prostě zvedne ta závěrečná pauza, až to vazbit přestane.

A pak to můžeš přepsat nějak líp.

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 15:53
od pokornja
Bomba, díky moc za výpočet :)
Přestalo mi to vazbit, když jsem to udělal takhle, ale nevím, jestli dát ten delay až na konec loop, nebo jen do té podmínky, kde to má bzučet. Tam mi to myslím vazbilo. Takhle se to tváří OK.

Kód: Vybrat vše

const int sampleWindow = 20;                              // 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) ;
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(80);
 Serial.print(" ");
 Serial.println(dB);
  

  if (dB >= 60){
    digitalWrite (LED_G, HIGH);
    digitalWrite (LED_Y, HIGH);
    digitalWrite (LED_R, HIGH);
    digitalWrite (bzucak, HIGH);
    delay (150);
    digitalWrite (bzucak, LOW);
  
  }

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

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

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

delay(5);
}

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 16:12
od pokornja
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

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 17:31
od gilhad
Tam je podstatné dát ten

Kód: Vybrat vše

delay(88); // počkat na ozvěnu
za vypnutí bzučáku, aby měl zvuk ok bzučáku čas doletět ke zdi, odrazit se, vrátit se, (třeba se ještě někde odrazit) a ty jsi to pořád ještě neměřil (v dalším průchodu loop, který přichází prakticky okamžitě po ukončení průchodu předchozího).

Co tam máš teď ten delay(5), tak to tě chrání jen před odrazy délky 0.005 x 330 = 1.65 m, čili odrazy od zdí (a jiných předmětů, včetně nerovností podlahy, lustrů a pod) bližších, než 82.5 cm - odraz od čehokoli vzdálenějšího už nejspíš změříš (i když o to nestojíš, a "zavazbíš se").

Ten delay musí následovat po tom bzučáku, takže stačí do té podmínky. A taky nemusíš vypínat ten bzučák tam, kde ho nezapínáš. (A já bych osobně vypnul ten bzučák, i všechny LED i v setupu, jakmile nastavíš pinMode, abych věděl, že tam není nic nedefinovaného - teda, ono normálně není, ale mám lepší pocit, když si počáteční podmínky definuju a vynutím sám (a je to v programu jasně dané, jaké jsou), než když se spolehnu, že to něco někde nějak nastaví samo a ponechá nastavené, ačkoli to nikde není výslovně zaručené a jen to tak "náhodou" vyjde.)

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 17:42
od gilhad
Ano, ten odpor mezi snímač a pin arduina a kondenzátor mezi ten pin a zem ti tam udělají dolní propust.
Ta propust ti 7kHz utlumí asi na 1/10 (= -3dB), 6kHz utlumí míň, 8kHz utlumí víc.

(Neuřízne to nic, jenom ztlumí, samozřejmě čím víc přez těch 7kHz, tím víc to ztlumí, takže výrazně víc ti prakticky neprojde. A naopak nižší než 7kHz to bude tlumit taky, akorát ne tolik. Ale v prvním přiblížení se to tak říct dá.)

Re: Zvukový senzor MAX9814

Napsal: 26 úno 2023, 18:41
od pokornja
Ano ano, rozumím, kvůli tomu vloženému rezistoru se celý signál trochu utlumí a vysoké frekvence to ořeže. Dívám se teď na zvukový záznam dupání a pod tím mám dole barevně frekvenční charakteristiku. Takže ideálně cca nad 100 Hz uřezat přes propust?

Re: Zvukový senzor MAX9814

Napsal: 27 úno 2023, 12:25
od pokornja
Chápu prosím správně, že si pinem AR můžu měnit „zpětný náběh citlivosti“ (nevím jak to nazvat)? Cituji z manuálu:
„Trilevel Attack and Release Ratio Select. Controls the ratio of attack time to release time for the AGC circuit.
A/R = GND: Attack/Release Ratio is 1:500
A/R = VDD: Attack/Release Ratio is 1:2000
A/R = Unconnected: Attack/Release Ratio is 1:4000“
Z mého pozorování jsem zjistil, že se mikrofon chová po detekci silného zvuku tak, že ihned po něm jakoby sníží svou citlivost, takže další hlasitý zvuk bezprostředně po předchozím ve výchozím nastavení nedetekuje (=AR pin nezapojen), je tam taková prodleva, než to naběhne zpět. Jestli jsem to tedy správně pochopil, tak zapojením toho pinu AR na zem se mi tady ta prodleva zkrátí. Nebo ne?