Forum: Digitale Signalverarbeitung / DSP / Machine Learning IIR-Filterkoeffizienten


von Hans (Gast)


Lesenswert?

Hallo Leute,

ich will mir mit meinem ATMega128 drei digitale Filter basteln.

Einen Notch-Filter(50Hz), einen Tiefpass(ca.150Hz) und einen 
Hochpass(ca. 1Hz).

Den Notch-Filter habe ich bereits implementiert und er funktioniert.
Die Koeffizienten habe ich in MATLAB berechnet. Das Eingangssignal hat 
eine Samplerate von 500Hz und ist ein signed long 32-Bit Wert.

Folgende Filterform habe ich verwendet:

Die Gleichungen für ein IIR-Filter Direct-Form II, SOS
w[n] = Gin*x[n] + a1*w[n-1] + a2*w[n-2]
y[n] = Gout*(b0*w[n] + b1*w[n-1] + b2*w[n-2])

Filterkoeffizienten:
//Zähler
b[0] =  1
b[1] = -1.6180339887498947
b[2] =  0.99999999999999989
//Nenner
a[0] =  1.6077528939666013
a[1] = -0.98729186796473045

Um mit Festkommazahlen rechnen zu können müssen die Koeffizienten ja 
skaliert werden.

Da die Koeffizienten nicht im Bereich -1...+1 liegen habe ich sie 
zunächst durch 2 geteilt und dann mit 2^(31) multipliziert um sie im Q31 
Format abzuspeichern.

Das ist der C-Code meines Filters.
1
signed long iir_notch(signed long new_sample, signed long *w)
2
{  
3
  signed long b[3], a[2], y;
4
  
5
  signed long mult_q31(signed long factor1, signed long factor2)
6
  {
7
    return (signed long) (((signed long long)factor1 * (signed long long)factor2) >> 31);
8
  }  
9
//Scaled Coefficients(x/2 * 2^(31)) --> Q31
10
  b[0] = 1073741824;
11
  b[1] = -1737350766;
12
  b[2] = 1073741824;
13
  a[0] = 1726311525;
14
  a[1] = -1060096571;
15
16
  w[0] = (new_sample + mult_q31(a[0],w[1]) + mult_q31(a[1],w[2]));
17
18
  y = (mult_q31(b[0],w[0]) + mult_q31(b[1],w[1]) + mult_q31(b[2],w[2]));
19
20
  w[2] = w[1];
21
  w[1] = w[0];
22
23
  return y;
24
}

Hat jemand noch eine Idee wie man die Koeffizienten vielleicht noch 
besser skalieren könnte um das Ergebnis möglicherweise noch zu 
verbessern??

von Peder (Gast)


Lesenswert?

Wenn ich den Wert sehe:

0.99999999999999989

dann riecht das schon nach Fehler. !

Du musst, wenn der Filter stimmen sollte auf mindestens 1/n genau 
rechnen, mit n=Zahl der Iterationen / Schritte. Damit brauchst du jeden 
Koeefizienten mit dieser Genauigkeit, sagen wir 1/1000.

Der da oben sind 1-0,..........11, da sehe ich wenigstens 20 
Dezimalstellen!

-> 64 Bit!

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.