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.
Nein so funktionierts nicht. Aber es muss doch eine equivalente Formel für den Hochpass geben oder? Im Prinzip ist das ja ein IIR Filter 1. Ordnung.
Stichwort FIR-Filter. Die Koeffizienten kann man mit Scilab oder Matlab berechnen.
Ersetze in deiner Übertragungsfunktion einfach s durch 1/s (Stichwort Tiefpass-Hochpass-Transformation) Gruß Michael
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.
y0 = (x0 * k) - (x1 * k); x1 = x0 * k; wobei y0 und x0 die aktuiellen Werte sind und x1 der um einen Abatstschritt vergangene Wert ... Gruss
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.
> filter = neuer_messwert - filter + filter >> 4 > output = filter >>4 kleins bisschen schneller, da nur 1x shift: filter = neuer_messwert - filter + output output = filter >>4
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.
Mache einfach eine Transformation in superymmetrische Räume, damit klappts auf jeden Fall!
Gerd schrieb: > Mache einfach eine Transformation in superymmetrische Räume, damit > klappts auf jeden Fall! Kannst du das bitte genauer erklären?
Servus, was spricht den gegen eine einfache bilinear Transformation? H(s) = sT / (sT + 1) mit s = 2 fa (z - 1)/(z + 1) MfG Mathias
ryd11 schrieb: > Jetzt meine Frage: Wie sieht die Formel für den Hochpass aus? Zieh doch einfach vom Eingangssignal den gefilterten Wert ab. Gruß Anja
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]) ------------------------------------
>> 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. :-)
Hier also die equivalente Version zum Tiefpass im ersten Posting: r = y + x0 - x1 x1 = x0 y = r >> 4
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!
@Ralli: Du solltest noch sagen, 0 <= K <= 1, wobei ==0 und ==1 eher sinnfrei sind, aber ausserhalb dieses Intervalls wird's instabil ... Gruss
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 ...
uup's mit T1 verrutscht: out = Kd * (dxe/dt) - T1 * (dout/dt) nu passt's
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]) ------------------------------------
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.