[elektro] Egyszerű digitális szűrő algoritmus

Nya'ri Viktor office at flexelec.hu
Wed Feb 25 17:40:15 CET 2009


 >> Ha van mondjuk egy t mintavételi idővel digitalizált hullámforma (kb.
 >> annyira szabálytalan a hullámforma, mintha beszédhang lenne, de nem
 >> az),
 >> és x darab mintavételi adat szépen be van töltve egy adat[x] tömbbe,
 >> akkor mi az a legegyszerübb szűrő algoritmus, amivel ebből ki tudnám
 >> nyerni(szűrni) mondjuk a (10 x t) periódus idejű szinuszt?
 >
 >
 > s_prev = 0
 > s_prev2 = 0
 > coeff = 2 * cos(2 * PI * requested_frequency / sample_frequency);
 > for n 0 to 100
 > s = x[n] + coeff * s_prev - s_prev2;
 > s_prev2 = s_prev;
 > s_prev = s;
 > end
 > power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev2 * s_prev;
 >
 > De ha csak jelenlét kell nem kell az utolsó sor, fölösleges számítás.
 >
 >> Egy kis elmélet hozzá:
 >> http://en.wikipedia.org/wiki/Goertzel_algorithm

Hello!

Köszi mindenkinek.

Na, kipróbáltam; excel-ben csináltam egy táblázatot és grafikont. Jó el 
lehet vele játszani :-)

http://www.pyrograph.hu/sinus.xls

A táblázat, amit tud:

Beállítom a mintavételi frekit (f_minta).
Beállítok két frekvenciát (f_1 és f_2), amiből kiszámolja, hogy egy 
hullámra hány mintavételi ciklus jut (minta/hullám). Ennek megfelelően 
generálok két szinusz hullámformát. Ezeket az adatokat tartalmazza az 
adat1[1..200] és adat2[1..200] oszlop.
A [201..300] mezők fel vannak töltve nullákkal, hogy lecsengést is 
lehessen nézni.
Az összeg oszlopban a két hullám összege.

Megadok egy kiszűrendő frekvenciát (f_sz), amiből szintén kiszámolja a 
minta/hullám adatot. Ezt a hullámot az összegzett adat1[x]+adat2[x] 
hullámformából fogja szűrni.
Erre a szűrendő frekvenciára kiszámolja a
coeff = 2 * cos(2 * PI * minta/periódus)
értéket, és ezt felhasználva, a Goertzel alg.-al létrehozza az 
adat_szűrt[1..300] adathalmazt.

Több ilyen szűrőt "egymás után kapcsoltam"; ezek kimeneti adatait az 
adat_szűrt2[] - adat_szűrt5[] oszlopokba teszi (mindegyik szűrő az 
előtte lévő szűrő kimenetéből dolgozik).

Mindegyik adat_szűrt[] képletébe betettem még egy szorzófaktort is 
(állítható adat_szorzó, de 0,5-re véve az értéke; gyakorlatilag 
"illesztés").

Utána grafikon (2. munkalapon van).
- ábrázolva van a két bemeneti hullám (zöldek)
- a két hullám összege (kék)
- és a kimenetek közül az elsőfokú adat_szűrt[] és az ötödfokú 
adat_szűrt5[] van csak ábrázolva (piros és barna)

--------------------

Példa (a piros adatok állíthatóak):
f_minta:      1MHz
f_1:          50kHz    (n_1: 20)
f_2:          50kHz    (n_2: 20)
f_sz:         50kHz    (t_sz: 20)
adat szorzó:  0,5

A 200. mintánál megszünik a gerjesztés, és szépen le is cseng a kimenet.
Eddig még nagyjából értem a viselkedését.

Kérdés:
- Jól gondolom, hogy szükséges a "csillapítás" (ez a 0,5-ös adat szorzó) 
a rendszerbe, hogy valódi szűrőt modelezzen, mert különben agyament 
amplitúdók jönnek ki?

----------------
Egy példa:
f_1:          50kHz    (n_1: 20)
f_2:          50kHz    (n_2: 20)
f_sz:         <50kHz    (t_sz: >20)

f_sz-nek akármilyen értéket állítok be 50kHz alatt, a kimeneten mindig 
amplitúdó maximumot mutat, sőt még kicsit nő is az ötödfokú kimenet; 
vagyis olyan, mintha ezek a szűrők nem sávszűrők, hanem aluláteresztő 
szűrők lennének.

Ha f_sz-nek viszont 50kHz-nél nagyobb értékeket állítok be, akkor 
viszont szépen csökken a kimeneti amplitúdó, úgy ahogy várható is lenne. 
Egészen az 1MHz környékéig, ahol újra nő a szint, mert gondolom az 
f_minta-t is kiszűri, sőt f_minta minden harmonikusánál is amplitúdó 
maximumot mutat. Vagy rosszul gondolom, hogy ezért van?


Kérdés:
- Miért mutat ilyen aluláteresztő jelleget? A Goertzel algoritmus 
tényleg aluláteresztő szűrőt valósít meg?
- Mit kellene ezzel csinálni, hogy kellene átírni az algoritmust, hogy 
lefelé is vágjon (azaz sávszűrőt valósítson meg)?
- Van jobb módszer a vágási meredekség növelésére, mint hogy simán 
"sorbakötni" több ilyen szűrőfokozatot?




More information about the Elektro mailing list