Forum: Mikrocontroller und Digitale Elektronik IIR Filter in C Implementieren


von der neue Gast (Gast)


Lesenswert?

Hallo an alle Profis

ich möchte in der C-Sprache einen bei einem Mikrocontroller den IIR 
Filter Implementieren. Diese soll die Analog-Digital Wandler Werte über 
eine bestimmte lange Zeit(z.B. 10sekunden) zusammenfassen und Glätten.

Die Gleichung lautet

y[i] = 1/k * ( x[i] + ((k-1) * y[i-1])

z.B. mit k=32

Ich habe diese Funktion "unsigned long iirFilter(unsigned int newval)" 
benannt! Wie würdet ihr diese am besten Implementieren??

Gruss

von Karl H. (kbuchegg)


Lesenswert?

der neue Gast schrieb:
> Hallo an alle Profis
>
> ich möchte in der C-Sprache einen bei einem Mikrocontroller den IIR
> Filter Implementieren. Diese soll die Analog-Digital Wandler Werte über
> eine bestimmte lange Zeit(z.B. 10sekunden) zusammenfassen und Glätten.
>
> Die Gleichung lautet
>
> y[i] = 1/k * ( x[i] + ((k-1) * y[i-1])
>
> z.B. mit k=32
>
> Ich habe diese Funktion "unsigned long iirFilter(unsigned int newval)"
> benannt! Wie würdet ihr diese am besten Implementieren??

Im Grunde fast genau so, wie sie da als Formel steht (aber auf die 
Datentypen und möglicher Überläufe/Unterläufe der Zwischenergebnisse 
achten)

Nur eines noch:
i ist in deiner Formel ein 'Zeitparameter'. d.h. der Filter braucht
  * den neuen Messwert
  * den alten Mittelwert

und er liefert den neuen Mittelwert.
x[i]   ist der Messwert zum Zeitpunkt i
y[i]   ist der neue Mittelwert für diesen Zeitpunkt i
y[i-1] ist der vorhergehende Mittelwert vom Zeitpunkt (i-1)


(mit Arrays hat das ganze nichts zu tun)

Der Filter errechnet einen neuen Mittelwert, indem er 'alten Mittelwert' 
und 'neuen Messwert' miteinander verrechnet.

d.h. dein Funktion sieht so aus

unsigned long iirFilter(unsigned long oldMean, unsigned int newval)

(Wieso ist eigentlich der Returnwert ein unsigned long, wenn dein 
Messwert nur ein unsigned int ist? Der Mittelwert einer Folge von Zahlen 
kann ja sowieso nicht größer sein als die größte Zahl. Also

unsigned int iirFilter( unsigned int oldMean, unsigned int newVal )

von der neue Gast (Gast)


Lesenswert?

Hallo,

ich dachte, dass man dort einen Array Impelemtieren musste um die Werte 
zu speichern..

Das mit den Datentypen ist verstehe ich auch jetzt :)

Ich habe mal diesen Code Implementiert, diese würde aber denke ich mal 
nicht so ganz Funktionieren! Oder?

unsigned int iirFilter(unsigned int oldMean, unsigned int neuWert)
{
    unsigned int hilfe1;
    int i;
    unsigned int y;
    unsigned char k=32;

    for(i=0; i<k; i++)
    {
        hilfe1=(k-1) * y[i-1];
        y[i] = (1/k) * (neuWert + hilfe1);
    }
}

So würde es nicht Funktionieren!

von Bronco (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> (mit Arrays hat das ganze nichts zu tun)

der neue Gast schrieb:
>    unsigned int y;
>         hilfe1=(k-1) * y[i-1];

Na so eher nicht...

von Frank H. (Gast)


Lesenswert?

y[i] = 1/k * ( x[i] + ((k-1) * y[i-1]):


ylong+= x-y;
y = ylong / k; // bzw >>5

von der neue Gast (Gast)


Lesenswert?

Ich Frage mal so!

Wie würdet ihr die Funktion "unsigned int iirFilter(unsigned int 
oldMean, unsigned int neuWert)" am sinnvollsten ohne Schiebeoperatoren 
Implementieren??

von Ingo (Gast)


Lesenswert?

Es geht schon damit los, dass der Compiler aus 1/k Null machen wird. 
Somit ist der Rest schon falsch.


Ingo

von der neue Gast (Gast)


Lesenswert?

Keine weiteren Vorschläge ??

von Ale (Gast)


Lesenswert?

Werte mal 65536 skalieren :), dann 1/k wird 65536/k...

von der neue Gast (Gast)


Lesenswert?

Ale schrieb:
> Werte mal 65536 skalieren :), dann 1/k wird 65536/k...

Verstehe leider nicht so ganz was damit gemeint ist!!

von Karl H. (kbuchegg)


Lesenswert?

der neue Gast schrieb:
> Keine weiteren Vorschläge ??

Ich sagte doch: Mit Arrays hat das nichts zu tun!

Lies [i] als 'neu' und [i-1] als 'alt'.

also ist

  y[i] = 1/k * ( x[i] + ((k-1) * y[i-1])

in der 'Übersetzung'


  neues_MIttel = 1/k * (Messwert + (k-1) * altes_Mittel );


noch ein bischen umformen, damit 1/k nicht zu 0 wird und du hast es.


   1                 a
  --- * a   <==>   -----
   k                 k



Du wirst doch das wohl in C hinschreiben können! Steht doch eh schon 
alles mehr oder weniger fix/fertig da.

Es hilft auch, wenn man sich vergegenwärtigt, was man da konzeptionell 
eigentlich tut. Dann verstehst du plötzlich auch, wo das nächste Problem 
auf dich wartet.

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.