Hallo! Ich benutze folgende "Tiefpass" - Formel: value=(COEFF*value+(100-COEFF)* previous_value)/100; previous_value=value; Diese Formel "begrenzt" die max. Änderung je nach COEFF (z.B. COEFF=1 => 1%) Hat man einen Sprung von z.B. 0 auf 1000 so läuf das Signal erst schnell und dann immer langsamer dem Endwert zu. Mein Problem sind nun die Rundungsfehler, die bei meinem 8bit µController auftauchen. (bei diesem Beispiel von 0 auf 1000 komme ich gerade mal auf 95,1% des Endwertes) - da die Änderungen nahe dem Endwert natürlich so klein sind, dass sie ständig abgeschnitten werden. Hat mir jemand eine Lösung?? Ich habs schon versucht in dem oberen Bereich dann zu linearisieren, jedoch habe ich Werte, die von 0 bis 18000 sein können (Endwert= z.B. 100) und der COEFF kann auch zwischen 0 und 100 sein. Vielen Dank schon mal! Gruß Roland
Hallo nop(); Ich rechne schon mit 16bit integer Zahlen. Nur durch die prozentuale Annäherung an den Endwert (=> irgendwann sollte ich dann bei 99,9999% sein) wird die Änderung so klein, dass mein Controller die "Komma-Stellen" abschneidet. Ich würde gerne ab z.B. einem Endwert von 95% einen linearen Anstieg programmieren, jedoch ist der Fehler bei einem kleineren Endwert viel viel größer und dort müsste ich schon bei 50% linearisieren. Leider kennt mein Controller keine float Zahlen! Gibt es sonst noch eine Möglichkeit? Gruß Roland
Wenn der Controller kein Float "hat", dann kümmert sich halt der Compiler drum, wie üblich. Oder ist dein Controller so langsam, dass sich emuliertes Float bemerkbar macht?
>>Gibt es sonst noch eine Möglichkeit?
Ja, die gibt es. Du muß Deine Dynamik besser nutzen.
Deine Formel lautet ein wenig konventioneller hingeschrieben:
previous_value(k+1)=a*value+(1-a)*previous_value(k) mit a=Coeff/100
Für den 'steady state' ist previous_value = value, also value so
vorskalieren, daß er gut in den Zahlentyp paßt, hängt vom Wertebereich
von value ab. Für a ne Zweirepotenz in den Nenner nehmen, also z.B.
1/128, teilen durch 128 ist einfach 7 Stellen nach rechts schieben.
(1-a) ist dann 127/128, d.h. Du multiplizierst previous_value(k) mit 127
und shiftest dann 7 Stellen rechts. Bei 16 Bit darf previous_value(k)
dann höchstens 16-7-1=8Bit groß sein, 1000 für value geht gar nicht
mehr. Das ist aber sicher mit ner 16*16->32Bit Multiplikation und
Shifterei zu schaffen.
Cheers
Detlef
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.