Für ein paar Versuche bin ich auf der Suche nach einer einfachen
Implementierung für ein Tiefpassfilter in C.
Ich messe mit einem ATmega168 256 Werte (8Bit) eines Signals mit etwa
500Hz Grenzfrequenz, die Abtastrate ist 10KHz.
Die Filterkoeffizienten habe ich bereits mit Matlab berechnet und dort
auch ausprobiert (natürlich Integer...)
Ich möchte nun also das Array mit den 512 Werten Filtern und dann an den
PC schicken. Mein Problem ist die Filterimplementierung.
Hat jemand ein einfaches Beispiel?
Dominik schrieb:> Wie kann ich ein Filter höherer (z.B. 6. Ordnung) implementieren und auf> ein Array anwenden?
In dem du es in Teilfilter 2. Ordnung aufsplitest .
Du dimensonierst erst mal ein Analoges Filter mit dem gewünschten
Frequenzgang. Die werden meistens in Teilfilter 2.Ordnung dimensoniert.
Die dann berechneten Parameter werden dann mittels Bilineare
Transformation in den z-Bereich transformiert. Un dschon hast du deine
Koeffizenten der IIR-Teilfilter. Deine Daten werden dann durch die 3
Teilfilter hintereinander gefiltert.
@Helmut Lenzen:
Wer lesen kann (meinen ersten Post...), ist klar im Vorteil:
"Die Filterkoeffizienten habe ich bereits mit Matlab berechnet und dort
auch ausprobiert (natürlich Integer...)"
Kennt also bitte jemand der sich die Foreneinträge auch wirklich
durchliest und nicht nur seinen Mist dazuschreibt, auch wenn er keinen
Sinn ergibt, eine einfache IMPLEMENTIERUNG eines Tiefpassfilters höherer
Ordnung wenn man die Koeffizienten schon hat?
Dominik schrieb:> Kennt also bitte jemand der sich die Foreneinträge auch wirklich> durchliest und nicht nur seinen Mist dazuschreibt, auch wenn er keinen> Sinn ergibt, eine einfache IMPLEMENTIERUNG eines Tiefpassfilters höherer> Ordnung wenn man die Koeffizienten schon hat?
So wie ich das gelernt habe können analoge Filter (ich nehm mal an du
hast ein analoges Filter designt. Genauere Informationen haben wir ja
nicht) nicht so einfach wie du dir das vorstellst in diskrete Filter
umgemüntzt werden. Du solltest dein System also im q-Bereich (Stichwort:
Tustin-Transformation) nach den selben Prinzipien wie im s-Bereich neu
designen und daraus dann durch Überführung in den z-Bereich die
Implementierung als digitales Filter berechnen.
PS: Ich kann überhaupt nicht verstehen wiso du dich über die Posts von
"helmil" so aufregst. Man versucht dir ja nur zu helfen!
Dominik schrieb:> Wer lesen kann (meinen ersten Post...), ist klar im Vorteil:> "Die Filterkoeffizienten habe ich bereits mit Matlab berechnet und dort> auch ausprobiert (natürlich Integer...)"
Du hattes mich nach dem allgemeinen Vorgehen bei der Dimensionierung von
Digitalen Filtern gefragt. Und ich habe dir das Verfahren erklaert wie
es in der Literatur beschrieben ist um von einem Analogen Filter zu
einem gleichwertigen Digitalen Filter zu kommen. Und da wird zuerst ein
Analoges Filter designt. (Damit mein ich jetzt nicht die Widerstaende
und Kondensatoren zu berechnen sondern die allgemeine
Uebertragungsfunktion)
Und diese Analogen Koeffizenten werden dann mittels Bilinearer
Transformation in den z-Bereich uebersetzt. Diese Transformation ist
auch wie Michael auch sagte als Tustin-Transformation bekannt. Aus
dieser Digitalen Uebertragungsfunktion wird dann mittels
z-Transformation die Differenzengleichung erzeugt. Man zerlegt Filter
hoehere Ordnung vorteilsweise in Teilfilter 2. Ordnung um keine zu hohe
Spreizung der Koeffizenten zu bekommen was zu Rechenungenaugikeiten
fuehrt.
Dasselbe gilt ja in aenlicher Form fuer Analoge Filter.
Die allgemeine Formel lautet:
B0 + B1*z + B2*z^2
H(z) = ------------------
A0 + A1*z + A2*z^2
Dabei sind dann A0,A1,A2,B0,B1.B2 deine aus der Bilineraren
Transformation erzeugten Koeffizenten.
Beispiel:
Filter 2.Ordnung , Samplerate 8Khz,Butterworth, Grenzfrequenz 200Hz
Fliesskommaformat
Analoge Form:
1
H(s) = -------------------
1 + 1.414 * s + s^2
Daraus ergeben sich mit hilfe der BT:
A0 = 0.05542
A1 = 0.011085
A2 = 0.05542
B0 = 1
B1 = -1.778634
B2 = 0.800804
Die werden dann entsprechend in ein Q Format umgerechnet:
in Q30 Format z.B. mit 1073741824L multipliziert.
Der 'C' code zum Filter:
long Q30Lowpass(long Q30Val)
{
Q30X2 = Q30X1;
Q30X1 = Q30X0;
Q30X0 = Q30Val;
Q30Y2 = Q30Y1;
Q30Y1 = Q30Y0;
Q30Y0 = Q30Mult(Q30X0,Q30LA0);
Q30Y0 += Q30Mult(Q30X1,Q30LA1);
Q30Y0 += Q30Mult(Q30X2,Q30LA2);
Q30Y0 -= Q30Mult(Q30Y1,Q30LB1);
Q30Y0 -= Q30Mult(Q30Y2,Q30LB2);
return(Q30Y0);
}
Q30Mult ist eine Fixkommamultiplizierungsroutine.
Und fertig ist dein Digitales Filter. Und Dominik auch so hinbekommen?
Dominik schrieb:> Kennt also bitte jemand der sich die Foreneinträge auch wirklich> durchliest und nicht nur seinen Mist dazuschreibt, auch wenn er keinen> Sinn ergibt,
Ob das Sinn ergibt oder Mist ist, was ich schreibe kannst du als
nichtwissender in Sachen Digitaler Filter nicht beurteilen. Denn nach
diesem Verfahren habe ich schon sehr viele Digitale Filter
dimmensioniert.
Ich bin (theoretisch) nicht unwissend. Wie bereits geschrieben habe ich
die Koeffizienten (natürlich für Digitalfilter, darum gehts ja...)
bereits erfolgreich berechnet, skaliert und auch getestet. Mit möglichst
minimaler Koeffizientenspreizung etc. Ja, das ist nicht so schwer und
geht auch ohne Z-Transformation wenn man matlab bedienen kann...
Was mir fehlt ist eine ordentliche Implementierung in C damit ich die
Koeffizienten auch auf meine Messwerte auf dem Mikrocontroller anwenden
kann.
Und in diesem Fall ist es wirklich Mist, wenn jemand eine bereits
geklärte Frage neu zu beantworten versucht und nicht auf das Problem
eingeht.
Dominik schrieb:> Für ein paar Versuche bin ich auf der Suche nach einer einfachen> Implementierung für ein Tiefpassfilter in C.
Hast Du Dich denn schon für einen Filtertyp entschieden?
(Butterworth, Chebyshev, Bessel, Gauss und noch einige andere)
Bevor man sich mit der Implementierung von mehrstufigen Filtern
befasst, muss man schon einige Grundlagen der Filtertechnik
kennen. Zum Glüch gibts da viele passende Seiten im INet.
Ein Einstig ist, wie fast immer Wikipedia...
Gruss
Harald
Dominik schrieb:> Und in diesem Fall ist es wirklich Mist, wenn jemand eine bereits> geklärte Frage neu zu beantworten versucht und nicht auf das Problem> eingeht.
Von Mist zu schreiben und dann eine solche Frage zu stellen
Dominik schrieb:> Wie kann ich ein Filter höherer (z.B. 6. Ordnung) implementieren und auf> ein Array anwenden?
laesst nicht gerade Durchblick erkennen und in dem Fall muss man weiter
ausholen.
Und in Matlab wird es doch wohl eine Funktion geben die dir das Filter
in Teilfilter 2. Ordnung zerlegt. Der Rest ist dann 10 Zeilen 'C' Code.
Und warum das so gemacht wird habe ich dir ja versucht zu erklaeren und
der Code steht oben. Einfach 3 x hintereinander aufrufen (mit anderen
Koffs.) und schon steht das Filter 6. Ordnung.
Und darum halt ich es jetzt wie der alte Fritz hier „Macht Euch Euren
Dregg alleene!“
Wie bereits geschrieben: Der Filter ist berechnet und in matlab
getestet, ich habe also bereits alle Koeffizienten für mein digitales
Butterworth-Tiefpassfilter ich suche "nur" nach einer brauchbaren
Funktion in C mit der ich den Filter auf meine Rohdaten anwenden kann.
Jaja, die Matlab Cracks.
Da du ja ohne Z-Transformation an deine Koeffizienten gekommen bist,
verwendest du aller Wahrscheinlichkeit nach den Filter Designer (FDA
Tool).
Ich nehme auch an, dass du dir schon Gedanken über Quantisierungseffekte
(Grenzzyklen, Rundungsrauschen) gemacht hast. Speziell IIR Filter
reagieren da mitunter sehr intolerant - die Schlingel.
Wie oben schon erwähnt wurde, könntest du dein resultierendes Filter in
Sektionen 2ter Ordnung aufteilen (Second Order Sections). Dies wird
sogar in der Praxis so gemacht! Hier hast du noch die Qual der Wahl
zwischen diversen Strukturen (Direktstruktur I/II, transponierte, etc)
welche dir Vor- und Nachteile bescheren.
Da du Matlab nach eigenen Angaben bedienen kannst wirst du auch die
Koeffizienten der Biquads berechnen können und es resultiert eine
einfache Funktion filter(...) in C. Die gewählte Struktur bestimmt dir
dann die Implementation.
Klingt alles sehr interessant. Die grundlegende Frage bleibt aber: Ich
habe Koeffizienten und möchte die auf meine Messwerte im Array anwenden,
sodass ich am Ende ein Array mit tiefpassgefilterten Messwerten habe.
Dominik schrieb:> ich suche "nur" nach einer brauchbaren> Funktion in C
Vielleicht hift Dir das hier ja:
http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
Dort kann man ein paar Eckdaten eingeben und erhält dann ein Stückchen
Quelltext, das den entsprechenden Filter implementiert.
Christian
Also als Jemand der weniger Vorwissen hat und über die Google Suche an
diesen Forumsbeitrag gerät, kommt zunächst beim Lesen der eigentlichen
Fragestellung Freude auf, eine nützliche Quelle gefunden zu haben. Je
mehr man ließt, desto weniger informativ wird alles. Kann es sein, dass
es nicht darum geht, jemandem die Frage nach einer einfachen
Implementierung zu beantworten, sondern nur zu zeigen was für ein toller
Hecht man ist? Ihr seid alle die Größten! Ich verteile Fleißmärkchen an
euch alle! Manchmal schäme ich mich Ingenieur geworden zu sein...
@ Martin (Gast)
Es ist hier alles gesagt worden wie man ein Filter implementiert. Wenn
Dominik aber lernresistent ist und alle Antworten ignoriert und meint es
trotzdem besser zu wissen ist ihm nicht zu helfen.
Hätte er sich meinen Post
Beitrag "Re: Einfaches Tiefpassfilter"
mal genauer angeschauen hätte er festellen müssen das dort schon Code in
C vorhanden ist für ein Tiefpassfilter 2. Ordnung. Diesen Programmteil
hätte lediglich 3 mal aufrufen müssen mit anderen Koffs. und schon hätte
er seinen Tiefpass 6. Ordnung. Stattdessen wurde ich von ihm beschimpft
als ob ich nicht lesen könnte.
Martin schrieb:> Kann es sein, dass> es nicht darum geht, jemandem die Frage nach einer einfachen> Implementierung zu beantworten, sondern nur zu zeigen was für ein toller> Hecht man ist?
Ganz im Gegenteil aber lesen muss er schon selbst. Und ganz trivial ist
das Thema digitale Filter nun auch nicht. Das haben ausser mir ihm
andere auch gesagt. Mit nur Matlab bedienen zu können kann man keine
digitalen Filter verstehen. Dazu gehört immer noch ein gutes Buch.
Martin schrieb:> Ihr seid alle die Größten! Ich verteile Fleißmärkchen an> euch alle! Manchmal schäme ich mich Ingenieur geworden zu sein...
Und wenn du schon solche Sprüche abläst dann bitte kannst du ja mal eine
erklärung über digitale Filter für Dummys hier schreiben.