Forum: PC-Programmierung Exponentielle Steigung ausgeben


von Jay M. (blubb33)


Lesenswert?

Ich möchte einen 8-bit-Bereich (also von 1 bis 256) so ausgeben, dass es 
diesem Verlauf entspricht: 
http://infosys.beckhoff.de/index.php?content=../content/1031/tcplclibdali/html/tcplclibdaliv2_dimmingcurve.htm&id=

Dazu habe ich mir folgendes überlegt: In einer Schleife wird eine 
Variable einfach immer um eins erhöht. Anschließend erfolgt eine 
Verzögerung. Diese Verzögerung wird mit der Zeit immer kürzer, d.h. am 
Anfang zählt das Script langsam hoch und am Ende immer schneller.

Wie kann ich die Verzögerungszeiten aus der verlinkten Formel umrechnen?

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Man könnte es über die Ableitung berechnen. Je großer die Steigung, 
desto schneller muss die Variable hochgezählt werden.

Ich würde das Problem mit einer festen Verzögerungszeit und eine Lookup 
Tabelle machen. In etwas so
1
unsigned char tabelle[n]={...};
2
for(i=0;i<;i++)
3
{
4
   Ausgabe=tabelle[i];
5
   Delay(m);
6
}
Die LUT würde ich mit einem kurzem C-Programm auf dem PC berechnen.

: Bearbeitet durch User
von Simpel (Gast)


Lesenswert?

Du kannst auf 2 Weisen herangehen.

a)Entweder das Zeitintervall bei jedem Schritt um einen bestimmten 
Faktor verkleinern und dabei deinen Ausgabewert jeweils um 1 
inkrementieren. Da aber das Prescaler-Verhältnis der Timer nur 
2^n-Schrittweiten erlaubt hast du somit nur 8 Schritte.

b) Das Zeitintervall konstant halten und die Inkrementschritte um einen 
festen Faktor sukkzessive breiter machen. Aber 8-Bit lassen nicht gerade 
viel Raum für eine exponentielle Kurve mit Ganzzahlen.
Bei einem Faktor von 2 hast du dasselbe Verhalten wie oben 
(1-2-4-8-16-...)
also nur 8 Bit bzw. 8 exponentielle Stufen.

Es geht auch etwas feiner, aber abseits der Idealkurve.
Dazu müsstest du eine fortgesetzte Festkomma-Multiplikation mit einem 
festen Faktor >1 z.B. mit 1,3 durchführen und das Ergebnis auf eine 
Ganzzahl runden (nicht bloss abschneiden) und als 8-Bit-Integer 
ausgeben. Das würde 21 etwas holprige Integer-Schritte bis 247 ergeben, 
deren Gesamtverlauf angenähert exponentiell ist.


...oder eine Kombination aus beidem. Das bedeutet aber einiges an 
Rechnerei.

von Max H. (hartl192)


Lesenswert?

Willst du so etwas wie LED-Fading machen?

von Simpel (Gast)


Lesenswert?

Wie Max oben schrieb, ist eine Look-Up-Tabelle hier deutlich zeit- und 
platzsparender.

Mit einem einfachen Basic- oder Sonstwas-Programm kannst du die Punkte 
ausrechnen.

Prinzip:

P als 22-elementiges Integer-Array

For n=0 to 21 step=1
 P(n)=round(1,3^n)
Next n


Oder per Win-Rechner schrittweise manuell:
1,3 hoch 1...2...3...........21 und per Auge auf- oder abrunden.

Falls du mehr als 22 Punkte willst, einfach einen kleineren Wert als 1,3 
nehmen und n soweit vergrössern bis die Zahl nahe 255 ist. Aber 
"schöner" wird die Holper-Kurve dadurch nicht unbedingt. ;-)

von Max H. (hartl192)


Angehängte Dateien:

Lesenswert?

Ich habe mal die Werte für x(n) ausgerechnet (siehe Anhang).

Dabei ist mir eine Idee gekommen um den Speicherplatz für die Tabelle, 
ohne viel mehr Rechenaufwand für den µC, zu halbieren.

Man könnte die Tabelle so anlegen:

Tabelle[0]=0
Tabelle[1]=x(1)-x(0)
Tabelle[2]=x(2)-x(1)
Tabelle[3]=x(3)-x(2)
...
Tabelle[n]=x(n)-x(n-1)

und die Schleife dann so aufbauen
1
unsigned char tabelle[n]={...};
2
...
3
Ausgabe=0;
4
for(i=0;i<255;i++)
5
{  
6
   Delay(m);
7
   Ausgabe+=tabelle[i];
8
}

Tabelle[n] ist max. für n=255: Tabelle[255]=7;
Also hätte ein wert der Tabelle in einem Nibble platz. Somit könnte man 
eine unsigned char, für die Speicherung von 2 Werten verwenden. Einen 
Wert im High-, den anderen in Low-Nibble --> Halber Speicherverbrauch.
Die Schleife könnte dann so aussehen:
1
Ausgabe=0;
2
for(i=0;i<127;i++)
3
{
4
   Delay(m);
5
   Ausgabe+=tabelle[i]&0x0F;
6
   Delay(m);
7
   Ausgabe+=(tabelle[i]>>4)&0x0F;
8
}

: Bearbeitet durch User
von Jay M. (blubb33)


Lesenswert?

Vielleicht denke ich ja komplett falsch. Aber mein Ansatz war etwas 
trivialer (!=besser):

Im folgenden die Zeiten bis zum nächsten Bit:
1  60
2  30
4  15
8  7,5
16  3,75
32  1,875
64  0,9375
128  0,46875
256

D.h.: Von Bit 1 zu 2 60 Sekunden; von 2 zu 3 30 Sekunden; von 3 zu 4 
auch 30 Sekunden, von 4 zu 5 15 Sekunden usw...
Damit würde die ganze Schleife 8 Minuten (8x 60 Sekunden) dauern.

Wie kann ich rechnerisch nun diese Intervalle etwas "abrunden"? Also 
anstelle von Bit 4 zu 8 je 15 Sekunden Abstand wäre es "schöner" 20, 17, 
23, 10 zu haben. Entsprechend im nächsten Intervall nicht 8x 7,5 
Sekunden...

Und richtig perfekt wäre es, wenn ich das Ganze in irgendeine Formel 
packen könnte, so dass bei Bit 6 eben 17 herauskommt... Dann bräuchte 
ich keine Liste mit 256 Elementen.

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
Noch kein Account? Hier anmelden.