[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