PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tiefpass



The Man
16.05.2009, 21:04
Hallo zusammen,

ich bin dabei mir einen Tiefpass für die standart µC zu überlegen. Standart in sofern, als das z.B. der gemeine Mega8 über keine Floating Point Unit verfügt. Softwaretiefpässe basieren ja darauf, das Delta zwischen dem letzten Ausgang und dem momentanen Eingang mit einem Faktor < 1 zu versehen und den Wert dann auf den Ausgang zu addieren. Das mit dem Faktor < 1 mache ich durch rechtsshift, wovor ich allerdings die entsprechenden Bits in eine Variable rette.

Wie macht ihr das mit dem Tiefpass?

Hier mal mein Code:


delta = (gyro_roh - tiefpass_out);
safe_rest += (delta & 0b00011111);
output_b(delta);
delta >>= 5;
tiefpass_out += delta;
output_b(tiefpass_out);


Ich überlege jetzt noch, wie ich mit dem Rest besser umgehen soll. Vll. werde ich ihn über einzelne Durchläufe zwischen den Aufrufen des Passes verteilen.

mfg,
The Man

Gock
17.05.2009, 14:20
Hi!
Ich hab noch kein solches Filter programmiert (es gibt da ja vielzählige), nur einfachere Mittelwertbilder. Ein Tiefpass 1. Ordnung besteht aber eigentlich aus der Summe der letzten 3 mit einem Faktor mulltiplizierten Messwerte. Egal...
Um die Fließkommaproblematik zu umgehen, kann man zB wie folgt vorgehen.

Aus einer 8Bit Berechnung
x1 = h * y1
mit h < 1
macht man die 16Bit Berechnung
(x1 << 8) = (h << 8) * y1
-> x1 = (h << 8 * y1) >> 8
X1 ist jetzt wieder 8Bit.
Das geht bis 32Bit mit den AVRs ganz gut, ab 64Bit "explodiert" der Code, zumindest, wenn die Berechnungen noch etwas komplizierter werden.
Gruß

The Man
27.05.2009, 05:39
So,

ich habe auch nochmal getüfftelt.

Mein Code sieht jetz so aus:




signed int16 acc_tief = 0;
signed int16 acc_roh = 0;
unsigned int16 acc_ort = 0;

acc_ort += ((acc_roh - acc_tief)*4);
//Faktor 4 dient zum Anpassen der Zeitkonstante

acc_tief = acc_ort >> 8;

Kern der Sache ist die unsigned 16 Bit Zahl acc_ort (Name soll hier mal egal sein). Auf die addiere ich die Differenz des momentanen Einganges minus den letzten Ausgang.
Auf den Ausgang wird aber nur das HIGH Byte gegeben.
Da im LOW Byte jede noch so kleine Differenz aufaddiert wird, geht mir auch keine Nachkommastelle verloren. Fürher oder später wird kommt auch eine Differenz von 1 durch das ewige addieren am Ausgang an.

Ich hab im DEV-C Compiler mal das Äquivalent dazu geschrieben und mir die Zahlenreihen in ein .txt drucken lassen und die dann wieder in Ecxel eingefügt. Sehen wir es uns doch mal an: