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íčů
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
Zvukový senzor MAX9814
Re: Zvukový senzor MAX9814
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.
Re: Zvukový senzor MAX9814
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...
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...
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);
}
}
Re: Zvukový senzor MAX9814
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);
Re: Zvukový senzor MAX9814
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.
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.
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 4 hosti