Forum: Mikrocontroller und Digitale Elektronik IIR Filter - CMSIS DSP Library vs. MATLAB


von Vincent H. (vinci)


Lesenswert?

Grüß euch

Ich hab momentan ein kleines Problem mit der Implementierung eines 
IIR-Filters in der aktuellen Version der CMSIS Library für einen 
STM32F4. Später sollen mit dem Filter einmal Soundfiles bearbeitet 
werden, vorab wollte ich aber nur die Geschwindigkeit erproben und mich 
ein wenig in die Libs einarbeiten.

Zum Design des Filters und dessen Koeffizienten hab ich MATLAB 
herangezogen. Dort funktioniert das Filter auch bereits wunderbar und 
ich kann mir vom Frequenz-/Amplitudengang bis zum Spektrum des 
gefilterten Signals alles ansehen...

MATLAB liefert auch gleich die passenden Filterkoeffizienten, die direkt 
in den Code gefüttert werden können.

Seitens der CMSIS DSP Library hab ich mich für die float64 Variante des 
Biquads in der Form "Direct Form II Transposed" entschieden. Laut meiner 
Information sei diese die für Gleitkomma-Darstellung stabilste Form. 
Details zur Implementierung findet man direkt bei ARM:
http://www.keil.com/pack/doc/CMSIS/DSP/html/group___biquad_cascade_d_f2_t.html


In Code sieht das ganze nun so aus

1
float64_t testInput_f64[320] = { * wollt ich euch ersparen... * };
2
float64_t testOutput_f64[320] = {0};
3
const float64_t coeffs[5] = {   0.0168191501070571,
4
                                0.0336383002141143,
5
                                0.0168191501070571,
6
                                -1.60109239418362,
7
                                0.668368994611848};
8
 
9
static float64_t biquadStateBandF64[4];    // one stage -> 4x state variables   {x[n-1], x[n-2], y[n-1], y[n-2]}
10
11
12
int main(void)
13
{
14
    /* Variables for df2T */
15
    arm_biquad_cascade_df2T_instance_f64 S1;
16
    float64_t  *inputF64, *outputF64;
17
18
19
    /* Link */
20
    inputF64 = &testInput_f64[0];
21
    outputF64 = &testOutput_f64[0];
22
23
24
    /* Initialize biquad f64 */
25
    arm_biquad_cascade_df2T_init_f64 (&S1, 1, (float64_t *) &coeffs[0], &biquadStateBandF64[0]);
26
27
    /* Run biquad */
28
    arm_biquad_cascade_df2T_f64(&S1, inputF64, outputF64, 320);
29
30
}


Soweit sogut. Zwar rechnet mir der M4 das Filter brav durch, nur leider 
stimmen die Werte im Ausgangsbuffer überhaupt nicht mit den gefilterten 
Werten von MATLAB überein. Noch dazu scheint das Filter nicht einmal 
stabil zu sein, da die Werte recht schnell absurd steigen und auch 
alternieren...

Hat jemand eine Idee woran das liegen kann?
Ich hab mich ursprünglich absichtlich für float64 entschieden, da diese 
Darstellung numerisch ident (oder zumindest fast ident) mit der 
Standard-Darstellung in MATLAB sein sollte? Wo passiert hier also der 
Fehler?


lg
Vinci

von Pandur S. (jetztnicht)


Lesenswert?

Was spricht gegen Debuggen. zB beginnen mit einfachen operationen. Zb, 
nur einen koeffizienten einbeziehen ?

von Vincent H. (vinci)


Lesenswert?

Ja, im Prinzip eh gar nichts.
Nur sind die CMSIS Libraries halt schon hart optimiert und ein IIR 
Filter wird
- durch dutzende Iterationen
- und in einem 4x parallel
System abgearbeitet.

Das is schon recht viel Aufwand, daher hoffte ich, dass ev. schon wer 
ähnliche Probleme hatte.

von Pandur S. (jetztnicht)


Lesenswert?

Dann rechne doch mal einen Tiefpass erster Ordnung, mit einem 
Koeffizienten von zB 1/256 und verifiziere den.

Du musst erst mal den Unterschied deines Mathlab zur Library, sowie die 
Library zum Erwartungswert herausfinden

Moeglicherweise ist es nur eine Verstaendnissache, eine andere 
Definition, Notation.

von Jim M. (turboj)


Lesenswert?

Vincent H. schrieb:
> Hat jemand eine Idee woran das liegen kann?

Schau Dir mal genau die Formeln in Matlab und die Formel in der ARM 
Doku an. Man musste bei Biquad immer das Vorzeichen bei ein paar der 
Koeffizienten umdrehen IIRC.

Vincent H. schrieb:
> Ich hab mich ursprünglich absichtlich für float64

Da float64 (aka double) bei STM32F4 nur in Software gerechnet wird, ist 
das deutlich langsamer als float32.

von Vincent H. (vinci)


Lesenswert?

Jetzt N. schrieb:
> Dann rechne doch mal einen Tiefpass erster Ordnung, mit einem
> Koeffizienten von zB 1/256 und verifiziere den.
>
> Du musst erst mal den Unterschied deines Mathlab zur Library, sowie die
> Library zum Erwartungswert herausfinden
>
> Moeglicherweise ist es nur eine Verstaendnissache, eine andere
> Definition, Notation.


Tatsächlich sind die Koeffizienten des Nenners negiert... :)
Dabei dachte ich eigentlich, ich hab das bereits geprüft...

Danke!

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.