Go Down

Topic: formel gesucht (linearer Wert zwischen zwei anderen) (Read 1 time) previous topic - next topic

Hier meine Aufgabenstellung (ist für einen Belichtungsrechner für meine Camera):

tStart        = gewünschter Anfangswert
tEnd           = gewünschter Endwert
now          = das "Jetzt" seit starten des Programmes
runStart      = hier wurde das Programm gestartet
tDuration       = gewünschte Dauer des Programmes
Momentanwert   = ?

alle Werte sind in ms.

Beispiel:

tStart    = 1
tEnd       = 1000
now       = 5000
runStart   = 4000
tDuration    = 2000

Hier ist der Momentanwert 499,5, denn ich befinde mich in der Mitte der Zeit (now - runStart = tDuration / 2) und somit habe ich die Hälfte zwischen tEnd und tStart ((tEnd-tStart)/2)

Gewünscht ist zu jedem beliebigen JETZT (now) den aktuellen Wert zwischen tStart und tEnd abfragen zu können, abhängig natürlich von der Dauer der linearen Änderung von "tStart" zu "tEnd" über die Dauer "tDuration".

Udo Klein

#1
Jul 30, 2011, 04:02 pm Last Edit: Jul 30, 2011, 06:12 pm by Udo Klein Reason: 1
Ich glaube Du solltest Deine Variablen besser benennen. Dann klappt es auch mit der  Rechnerei:

t0:= Startzeit
t1:= Zielzeit
t := aktuelle Zeit

s0:= Startwert
s1:= Zielwert
s := aktueller Wert

Wenn der Zusammenhang linear soll, dann also:

(t-t0)/(t1-t0) = (s-s0)/(s1-s0)

oder eben:

t = (t1-t0)/(s1-s0) * (s-s0) + t0
s = (s1-s0)/(t1-t0) * (t-t0) + s0
Check out my experiments http://blog.blinkenlight.net

MaFu

ergebnis = (now - runStart) * (tEnd - tStart) / tDuration + tStart;
_______
Manfred

Hallo MaFu,
das funktioniert super!
Du hast nicht zufällig noch die passende Formel (mit den gleichen werten) für exponentielle Wertänderung in deinem Mathematikerkopf?

Da würde ich glatt Freibier springen lassen ;-)

Udo Klein

(exp(t)-exp(t0))/(exp(t1)-(exp(t0)) = (s-s0)/(s1-s0)

oder

s = (s1-s0)/(exp(t1)-exp(t0)) * (exp(t)-exp(t0)) + s0
Check out my experiments http://blog.blinkenlight.net

TelosNox

Für so lineare Sachen kann man einfach die Funktion MAP nehmen

momentanwert = map(now, runStart, runEnd, tStart, tEnd)

du müsstest halt zunächst aus runStart + runDuration dein runEnd ausrechnen.

Hallo Udo,

leider klappt das nicht. Gibt mir immer "0" aus. :-(

Ich komme auch ganz gut klar mit meinen Bezeichnungen, vor allem weil ich immer weiß was es ist (das geht mir mit S0 leider nicht so). Ich halte hier immer eine art Namenskonvention ein, die Variablennamen sind halt relativ lang...

@TelosNox: Da habe ich auch schon dran gedacht, das werde ich mal testen - allerdings glaube ich nicht das die lineare Rampe funktionieren kann...

Udo Klein

Dann poste mal Deinen Code. Nimmst Du floats oder ints?
Check out my experiments http://blog.blinkenlight.net

Ich werde das mal ausdünnen und posten, im Moment ist der Code noch recht konfus...

Für die Zeitangaben verwende ich "unsigned long".

Udo Klein

Das ist das Problem. Sobald Du mit Exponentialfunktionen arbeitest wird es mit Integers schwierig. Ich will nicht sagen, daß es überhaupt nicht gehen kann, aber dazu muß man dann sehr genau verstehen wie die Formeln funktionieren und auch genau auf die Wertebereiche aufpassen. Deshalb wäre es vermutlich besser wenn Du dazu auf floats umstellst.
Check out my experiments http://blog.blinkenlight.net

Ich habe keine floats genommen, weil ich da immer Probleme bekomme mit der Wandlung in Strings. Ich habe ein Display dran hängen und gebe hier einen String aus. Teilweise sind das dann auch Werte aus den Berechnungen. Bei "long" geht das ohne Probleme, bei float sträubt sich das Arduino erfolgreich.

df6ih

#include<stdlib.h>
dtostrf(FLOAT,WIDTH,PRECSISION,BUFFER);


Gibt es hier : (weiter unten )

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1205038401

Ja, die Funktion habe ich auch ausprobiert. Wenn ich allerdings da nicht-floats durchjage, gibt's lustige Zeichen auf meinem LCD.

MaFu


(exp(t)-exp(t0))/(exp(t1)-(exp(t0)) = (s-s0)/(s1-s0)

oder

s = (s1-s0)/(exp(t1)-exp(t0)) * (exp(t)-exp(t0)) + s0
Hast Du das mal selber auf dem Arduino ausprobiert?
Ich denke, dass bei den Zahlen von derHerrKohler viel zu große Werte rauskommen. Die können auf dem Arduino nicht mehr verarbeitet werden.


Für so lineare Sachen kann man einfach die Funktion MAP nehmen

momentanwert = map(now, runStart, runEnd, tStart, tEnd)

du müsstest halt zunächst aus runStart + runDuration dein runEnd ausrechnen.
Meine obige Formel entspricht weitestgehend der map Funktion. Nur werden da zwei Rechenschritte gespart (runEnd berechnen welches map anschließend wieder für das errechnen der differenz verwendet) und es funktioniert so auch mit float (map ist nur für int definiert).
_______
Manfred

Udo Klein

#14
Jul 31, 2011, 02:26 pm Last Edit: Jul 31, 2011, 02:30 pm by Udo Klein Reason: 1
Wozu ausprobieren? Solange er nicht sagt wie die Wertebereiche sind ist unklar ob das Probleme geben wird oder nicht. Man kann auch andere Exponentielle Formeln nehmen. Genaugenommen ist ein Freiheitsgrad zuviel da. Wie gesagt: solange er das nicht sagt ist es ziemlich nutzlos das auszuprobieren.

Ich für meinen Teil würde keine exponentielle Funktion nehmen sondern Splines.

Und ich würde auch mal schauen was hier: http://openmoco.org/ so getan wird.
Check out my experiments http://blog.blinkenlight.net

Go Up