Hallo,
einen einfachen Tiefpass kann man programmieren:
filter += ((neuer_messwert - filter) >> 4))
bzw besser für die Implemeniterung mit Ganzzahlen
filter += neuer_messwert - filter >> 4
output = filter >> 4
Jetzt meine Frage: Wie sieht die Formel für den Hochpass aus?
mfg
ryd11
Das "filter += ..." zu "filter -= ...." tauschen sollte das Ganze zu
einem Hochpass machen. Teste es aber lieber noch mal nach. Ich habe
jetzt nur grob im Kopf überschlagen. Über z-Transformation und bisschen
probieren kommt man aber auch ganz schnell selbst drauf.
Also. Dann schreib ich mal auf, wie ich darauf kam:
Die Berechnungsvorschrift im Zeitbereich für deinen Tiefpass ist
folgende:
y(t) = (y(t-1) + x(t) - y(t-1)*a)*a
Wobei a = 2^-4 wegen des Rechtsshift um 4 beträgt. Der Rechtsshift am
Schluss ändert an der Filterwirkung an sich eigentlich nicht mehr viel.
Prinzipiell ist das ganze wegen der Shifts aber auch nicht mehr linear,
da es ja eine Integer Division ohne Nachkommastellen ist.
Um das Ganze systemtheoretisch als LTI-System zu betrachten, muss man
diese Nichtlinearitäten vernachlässigen und davon ausgehen, dass keine
Rundungsfehler auftreten. Eigentlich sollte das aber erst mal nicht viel
ausmachen.
So. Nun Transformiert man die Rechnungsvorschrift vom Zeitbereich in den
z-Bereich und erhält:
Y(z) = a*Y(z)*z^-1 + a*X(z) - a^2 * Y(z)*z^-1
Y(z) - a*Y(z)*z^-1 + a^2 * Y(Z)*z^-1 = a*X(z)
Y(Z) * (1 - a*z^-1 + a^2 * Z^-1) = a*X(z)
Y(z)/X(z) = H(z) = a/(1 - a*z^-1 + a^2 * Z^-1) = a/(1 + z^-1 *(-a +
a^2)) = a/(1+ b* z^-1)
mit b = -a + a^2
H(z) ist also die Übertragungsfunktion deines Tiefpasses. Der
Frequenzang ergibt sich aus dem Betrag von H(e^-j*w).
Mit eingesetzten werten für a und b also:
H(e^jw) = 2^(-4)/(1 + (-(2^-4) + (2^-4)^2) * e^-jw)
Also haben wir den Frequenzgang:
http://www.wolframalpha.com/input/?i=abs%28+2^%28-4%29%2F%281+%2B+%28-%282^-4%29+%2B+%282^-4%29^2%29+*+e^-iw%29%29+
Ich hoffe ich habe mich bis hierhin noch nicht vertan.
Nun zum Hochpass. Das erfahrene Auge tauscht nun einfach das Vorzeichen
im Nenner und erhält:
H(z) = a/(1 - b* z^-1)
http://www.wolframalpha.com/input/?i=abs%28+2^%28-4%29%2F%281+-+%28-%282^-4%29+%2B+%282^-4%29^2%29+*+e^-iw%29%29+
Sieht soweit gut aus.
Also zurück in den Zeitbereich:
Y(Z) * (1 - b* z^-1) = X(z) * a
Y(z) - b*Y(z)*z^-1 = X(z)*a
y(t) - b*y(t-1) = x(t)*a
y(t) = x(t)*a + b*y(t-1)
Mit b = -a + a^2 --->
y(t) = x(t)*a - a*y(t-1) + a^2 *y(t-1) = a*(x(t) - y(t-1) + a*y(t-1))
Das wiederrum ist ist in deiner Schreibweise nichts anderes als:
filter = neuer_messwert - filter + filter >> 4
output = filter >>4
Ich hatte also gestern Nacht einen Denkfehler.
Was genau du mit deinen shits bezwecken willst, weiß ich zwar nicht.
Aber so müsste es funktionieren.
Würde mich freuen, wenn du Rückmeldung gibst obs geklappt hat.
sorry, ein k zuviel ;-)
y0 = (x0 * k) - x1;
x1 = x0 * k;
wobei y0 und x0 die aktuiellen Werte sind und x1 der um einen
Abatstschritt vergangene Wert ...
Gruss
@ Antworter
Vielen Dank für deine Mühe.
Antworter schrieb:> filter = neuer_messwert - filter + filter >> 4> output = filter >>4
scheint zu funtionieren wenn ich output = filter setze, zumindest ändert
sich die Amplitude meines Sinus Arrays in meinen Testprog das ich
schnell geschrieben habe.
Die Shifts deswegen weil sie auf einer kleinen MCU halt ziemlich schnell
sind.
ryd11 schrieb:> scheint zu funtionieren wenn ich output = filter setze, zumindest ändert> sich die Amplitude meines Sinus Arrays in meinen Testprog das ich> schnell geschrieben habe.
Naja. Die Amplitude ändert sich bei diesem Filter in jedem Fall relativ
stark, egal welche Frequenz du reinsteckst. Die Filterwirkung an sich
ist prinzipiell auch nicht soooo super, was einfach an den seltsamen
Filterkoeffizienten durch die shifts liegt.
Ich gehe mal davon aus, dass du das für deine Anwendung so haben willst,
aber wenn du wirklich effektiv filtern willst, geht das auf jeden Fall
auch mit wenig Aufwand besser.
>> Jetzt meine Frage: Wie sieht die Formel für den Hochpass aus?>Zieh doch einfach vom Eingangssignal den gefilterten Wert ab.
So hab ichs damals auf dem Atari mal ausprobiert. Hat geklappt. :-)
Wollte ja nur noch mal kurz beim "mikrocontroller.net"
vorbeischauen. - Echt lustig, was hier für Transformationen
und superymmetrische Räume für simple Kinkerlitzchen bemüht
werden.
Die Wirkungsweise des ganz einfachen Tiefpasses ist im Klartext:
Der Ausgabewert wird nur allmählich an den Eingangswert angepasst.
(Wozu braucht man da -prinzipiell- eine Zwischenvariable?)
Tiefpass (in C):
input = new_value(); // Neuen Wert holen
output += (input - out_old) * K; // Ausgabe berechnen
out_old = output; // Wieder bereit!
Je größer "K", desto tiefer die Grenzfrequenz.
--------------------------------------------------------------------
Die Wirkungsweise eines ganz einfachen Hochpasses ist im Klartext:
Neue Eingangswerte erscheinen sofort am Ausgang, alte Ausgabewerte
verschwinden allmählich.
Hochpass (in C):
input = new_value(); // Neuen Wert holen
output = (input - in_old) + (output * K); // Ausgabe berechnen
in_old = input; // Wieder bereit!
Je größer "K", desto tiefer die Grenzfrequenz.
--------------------------------------------------------------------
Bei Tief- und Hochpass gilt:
Für definierte Grenzfrequenzen muss "K" entsprechend der
Abtastfrequenz gewählt werden...
Gute Nacht allerseits!
Hochpass ist nix anderes als ein DT1-Glied. Dafür gilt die
Differenzengleichung im Zeitbereich:
out = Kd * (dxe/dt)/T1 - T1 * (dout/dt)/T1
Die Divisionen durch T1 kann man sich sparen, wenn man hier die
Abtastzeit setzt. Somit ergibt sich das gewünschte Verhalten, sich
ändernde Eingangswerte werden nahezu direkt übernommen und alte Werte
klingen langsam ab ...
na, die simpelste Lösung für einen Hochpass (DT1-Glied mit Verstärkung
1, wobei streng genommen der Hochpass nur ein D-Glied mit Verstärkung
ist), die auch nur eine Speicherstelle braucht ist:
yneu = (xneu - yalt) * K + yalt; // Tiefpass (PT1), K zwischen 0 und 1
out = (xneu - yneu) * Kd; // Differenz zum PT1 ist Hochpassausgang (Kd =
1)
Mit Kd kann man die Verstärkung des DT1-Gliedes ändern ...
Gruss
@ Frank
Da hast du natürlich recht, es war aber schon spät...
Fein, dass es hier auch Leute gibt, die einfache Fragen
gern korrekt, aber (so weit es geht) verständlich und
praktisch nutzbar beantwortet sehen!
Schaun wir mal, ob es noch mehr davon gibt:
-------------------------------------------
Gibts hier jemanden, der uns die Berechnung von K
zeigen kann, wenn F_abtast und F_grenz gegeben sind?
> Gibts hier jemanden, der uns die Berechnung von K> zeigen kann, wenn F_abtast und F_grenz gegeben sind?
Ich wiederhole mich.
Wie wärs denn damit.
http://en.wikipedia.org/wiki/High-pass_filter
fg = Hochpass-Grenzfrequenz, fs Abtastfrequenz
0 < a < 1
a = 1/(1+2*pi*fg/fs)
y[i] := α * (y[i-1] + x[i] - x[i-1])
------------------------------------