Forum: Digitale Signalverarbeitung / DSP / Machine Learning IIR Filter mit Matlab


von Alex (Gast)


Lesenswert?

Hallo,

ich uss ein IIR-Filter in C realisieren.
Also habe ich mir diesen mit MATLAn fdatool entworfen und die
Koeffizienten rausgeben lassen.

Numerator:
0,25
0,5
0,25
Denominator:
1
-1,88859..
0,894476..
Gain:
0,0058868..
Output gain:
1


Als nähstes muss die Gleichung aufstellen, nur weiss ich jetzt nicht
was ich mit Gain machen soll. Soll ich jeden ungefilterten Wert damit
multiplizieren? Oder kann ich gleich alle Numeratoren
durchmultiplizieren? Warum hat das Programm es von selber nicht
gemacht?

Gruss,
Alex

von Detlef A (Gast)


Lesenswert?

Das Filter hat ne Gleichspannungsverstärkung von 169.89(wenn Du immer
Einsen reinschiebts, kommt nach der Einschwingzeit des Filters immer
169.89 raus), der Kehrwert davon ist der angegebene gainwert. Wenn die
Gleichspannungsverstärkung 1 sein soll, muß Du die
Numeratorkoeffizienten mit der gain multiplizieren.

Cheers
Detlef

von Alex (Gast)


Lesenswert?

Das heisst wemm ich die Gleichspannungsverstärkung behalten will, muss
ich Gain nicht bei der berehnung berücksichtigen?

Die Gleichung währe:
[b0 + b1*z^(-1) + b2*z^(-2)] / [1 - a1*z^(-1) + a2*z^(-2)] =
gefilterter Wert

ist das richtig?

Gruss,
Alex

von Detlef A (Gast)


Lesenswert?

>Das heisst wemm ich die Gleichspannungsverstärkung behalten will, >muss
ich Gain nicht bei der berehnung berücksichtigen?

So ist es.

>Die Gleichung währe:
>[b0 + b1*z^(-1) + b2*z^(-2)] / [1 - a1*z^(-1) + a2*z^(-2)] =
> gefilterter

Nee, das ist die Übertragungsfunktion. Zur Filterberechnung in C siehe
meine Einlassungen in
http://www.mikrocontroller.net/forum/read-10-232270.html#232983

Cheers
Detlef

von Alex (Gast)


Lesenswert?

also bei mir ist es so, ich lese kontinuirlich werte ein und mein Filter
soll auch nach jedem eingelesenem Wert einen gefilterten Wert liefern.
Kann ich da bei der Berechnung die 2Direktform (oder auch die 2
Kanonische Form genannt) verwenden?
Irgendwie versehe ich dein C-Code nicht ganz.

Gruss,

von Detlef A (Gast)


Lesenswert?

So sieht das aus in der zweiten kanonischen Direktform:
z2, z1 sind die Zustandsgrößen Deines Filters, x kommt rein, y geht
raus, r ist ne Hilfsvariable, das Rumschieben der Zustrandsgrößen kann
man sich in ner unübersichtlicheren Implementation auch sparen.

z1=0;z2=0;
for(;;){
    r=a1*z1+a2*z2;
    y=b0*(x-r)+b1*z1+b2*z2;
    z2=z1;
    z1=x-r;
}

von Alex (Gast)


Lesenswert?

Hallo,

bist du sichet das es stimmt?

ich habe das ganze mit ein paar Werten nachgerechnet und für y kommen
gfalschen Zahlen raus.

Nachfolgend ist eine Tabelle dargestellt, die Werte x werden
nacheinander eingelesen:

x        r        y        z2        z1
45       0        11,25    0         45
49       -84,987  55,99    45        133,987
51       -212,8   88,19    133,987   263,8
45       217,24   ...      ...       ....
..

Gruss,
Alex

von Detlef A (Gast)


Lesenswert?

>bist du sichet das es stimmt?

"Woran arbeiten Sie?" wurde Herr K. gefragt. Herr K. antwortete:
"Ich habe viel Mühe, ich bereite meinen nächsten Irrtum vor."
(Bertolt Brecht)
Nein, natürlich war ich nicht sicher, aber diesmal hats gestimmt.

folgendes Matlab script liefert die Folge
y = 11.2500   55.9966  144.1918  271.2316

clear
fb=[0.25 0.5 0.25];
fa=[1 -1.88859 0.894476];
x=[45 49 51 45 ];
y=filter(fb,fa,x);
return

Das gleiche Ergebnis liefert folgendes C-Programm
#include <stdio.h>
void main()
{
double z1=0.0,z2=0.0,r,y;
double x[]={45., 49. ,51., 45.};
double b0=0.25,b1=0.5,b2=0.25;
double a1= -1.88859 , a2=0.894476;

int k;
z1=0;z2=0;
for(k=0;k<4;k++){
    r=a1*z1+a2*z2;
    y=b0*(x[k]-r)+b1*z1+b2*z2;
    z2=z1;
    z1=x[k]-r;
    printf("%f \n",y);
}
}

Bei Dir ist noch nen bug drin. Debuggen: Berechne Dir mit Matlab die
Impulsantwort, also eine 1 und dann für alle Zeiten Nullen, bei Deinem
C-Programm muß dasgleiche rauskommen.

Cheers
Detlef

von Alex (Gast)


Lesenswert?

Hallo Detlef,

was ich nicht verstehe,wenn ich immer die selben Zahlen z.B. 144
reinschiebe, dann soll doch am Ausgang auch 144 rauskommen. Sonst währe
es ja kein Filter.

Das mit Matlab :
fb=[0.25 0.5 0.25];
fa=[1 -1.88859 0.894476];
x=[144; 144; 144; 145; 148; 142; 150;...]
y=filter(fb,fa,x)*0,00889;

funktioniert gut. Es dauert nur bis der Filter sich einschwingt.
Aber beim C-Prog. steigen die Werte kontinuirlich weiter.

Was ist bei mir falsch???

Ich habe die Koeffizienten mit FDATOOL entworfen und mein Signal mit
100000 Werten dadurch durchlaufen lassen, es kommen auch richtige Werte
raus.

Gruss,
Alexander

von Alex (Gast)


Lesenswert?

Hallo Detlef,

Sorry, das C-Programm funktioniert auch! habe vergessen mal 0.008859 zu
nehmen.

Habe aber noch eine Frage, wie kann man es machen das der Filter sich
schneller einschwingt?

von Detlef A (Gast)


Lesenswert?

Hi,

Einschwingzeit und Frequenzverhalten hängen zusammen: Je steiler das
Filter ist, umso länger schwingt es ein. Wenn Du willst, daß es kürzer
einschwingt muß Du es weniger 'scharf' machen.

Cheers
Detlef

von Alex (Gast)


Lesenswert?

Alle klar!

Danke für deine Hilfe!!!!!!

Bist du öffters in diesem Forum? Falls ich noch Fragen finde. :))

Gruss,
Alex

von Michael Günther (Gast)


Lesenswert?

Hallo alle zusammen,

wo kann ich ein Tutorial finden, dass Gleichungen zur
Koeffizientenbestimmung von IIR-Filtern enthält. Mich interessiert die
mathematische Vorgehensweise bei der Berechnung.

Danke.

von Detlef A (Gast)


Lesenswert?

Zur Koeffizientenbestimmung von IIR-Filtern gibt es Gleichungen ohne
Ende, das ist ne weites Feld, heißt 'Filterentwurf', da denken Profs
und schwitzen Studis drüber. Es kommt drauf was Du willst. Googeln
sowieso und die Hilfe von Matlab ist auch ganz ok.

Cheers
Detlef

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.