mikrocontroller.net

Forum: Projekte & Code Erweiterung zum Artikel LED Fading


Autor: Guido (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe eine Alternative zur Tabelle die man für die log. Ansteuerung der 
Fading-PWM braucht. Warum nicht eine nette kleine Formel benutzen? Vor 
einiger Zeit hatte ich das Problem eine Werteingabe über einen
Schieberegler zu steuern wobei der untere Wertebereich zu grob 
einstellbar war. Also musste ein exponentielles Verhalten des Potis her 
wie man es auch im RC-Bereich von den Servos her kennt. Ich habe im 
Internet nach lägerer Suche folgende Formel gefunden. Bitte keinen 
Schreck kriegen, alles wird sich in Wohlgefallen auflösen:

Expo-Poti-Formel:
-----------------

 y = max / (efunc (expo) - 1) * (efunc (expo * x / max) - 1)

 wobei x der lineare Potiwert zw. 0 und 100 ist und
 expo der Exponentialwert (Hängebauchwert) zw. 1 und 100 ist (0 ist
 linear).
 efunc () ist die e-Funktion (keine Angst wir rechnen nicht real
 sondern int).
 Y ist der Exponential-Wert (wird x linear vergrössert bewegt sich Y
 am Anfang sehr langsam und hinkt hinterher um am Ende x wieder 
einzuholen)

 Wir formen um:
 Nach Taylor gilt:
 exp (x) = 1 + x/1! + x*x/2! [ + x*x*x/3! + ... ] wir brechen nach
 der 3. Iteration ab (Abbruch nach der 2. reicht nicht !).

 Setzen wir nun 1 + x + x*x/2 für efunc () ein und vereinfachen die
 Gleichung (vereinfachen ist garnicht so einfach, habe mich ca. 10 mal
 verrechnet, jetzt kann ichs wieder) so kommt folgende wunderschöne
 Formel raus:

 y = (2*max*x + expo*x*x) / (max * (expo + 2))

 Das lässt sich mit Integern berrechnen !
 Will man nun eine LED dimmen so muss man eine Umkehrung dieser Funktion
 bilden. Man schiebt also das Poti von hinten nach vorne also von max 
nach
 0 und dreht Y genauso um und erhält eine log. Charakteristik.

#define LEDAn     PORTB |= (1<<PB3)  // muss an Hadware angepasst werden
#define LEDAus    PORTB &= ~(1<<PB3)

void LedDimmen (void) // dimmt die LED einmal hoch, qick and dirty
{
  uint8_t cnt = 0,
          comp = 0,
          acomp = 255;
  int32_t max = 255,
          b = 90,        // Expowert
    x, vcomp;
  while (comp < 255)
  {
    _delay_us (80);
    if (cnt == 254)
    {
      cnt = 0;
      LEDAus;
      comp++;
      x = max - 255 + comp; // dimmt hoch
      // x = max - comp;    // dimmt runter
      vcomp = (2*max*x + b*x*x) / (max * (b + 2)); // Expoformel
      acomp = max - vcomp;
    }
    if (cnt == acomp)
      LEDAn;
    cnt++;
  }
  LEDAn;
}

Probiert es mal aus. Bei mir sieht es richtig gut aus. Eure Meinung 
interssiert mich. Viel Spass.
  Guido

Autor: Lupin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant wäre es vielleicht eine Funktion zu haben, die einen 
linearen PWM Wert entgegen nimmt und dann den exponentiellen Wert zurück 
gibt.

Woher weiss ich, welchen Expowert ich wählen muss?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lupin (Gast)

>Woher weiss ich, welchen Expowert ich wählen muss?

Na dann schau mal in die Exceltabelle im Artikel . . .

http://www.mikrocontroller.net/wikifiles/e/e4/Pwm_table.zip

Die Berechnung in den AVR zu legen ist nicht sonderlich sinnvoll. Die 
paar Bytes Programmspeicher für die Tabelle sind kleiner und deutlich 
schneller als die Berechnung.

MFG
Falk

Autor: Guido (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
der Expowert ist frei wählbar (die Variable b im Code) und sollte zw.
1 und 100 liegen, bei größeren Werten sollte man darauf achten einen 
Integer-Overflow zu vermeiden.


>> Die Berechnung in den AVR zu legen ist nicht sonderlich sinnvoll. Die
>> paar Bytes Programmspeicher für die Tabelle sind kleiner und deutlich
>> schneller als die Berechnung.

Das kann man so sehen, aber:
Der Code braucht weniger Speicherplatz als eine vernünftige Tabelle, bei
kleinen Controllern sehr nützlich.
Die Dimm-Kurve ist einstellbar mit dem Faktor b, hier wären mehrere 
Tabellen
notwendig.
Die Geschwindigkeit ist zwar langsamer aber spielt hinsichtlich einer f.
LEDs typischen PWM-Frequent von ca. 100 Hz keine bedeutende Rolle.

Diese Alternative soll nur zeigen dass es eben auch andere Möglichkeiten 
gibt
LEDs zu dimmen, ich finde sie mathematisch interessant.

noch was:
Die Codezeile:      x = max - 255 + comp; // dimmt hoch
kann vereinfacht werden, da max = 255 ist, also reicht:  x = comp;

Gruss
  Guido

Autor: Alex R. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich muss schon sagen, dass es oft einfacher geht eine Formel selbst 
aufzustellen, als eine ewig im Internet zu suchen. im Anhang ist ein 
Bild mit der Erklaerung wie ich zu mein Formel komme. Noch dazu ist sie 
bedeutend einfacher als die bereits vorgeschlagene. Andererseits dauert 
die berechnung im µC viel laenger.

Mein Ergebnis für eine lineare Helligkeitssteigerung ist:

exponentialwert=e^(linearwert/k)
wobei k=Helligkeitsmaximum/ln(Helligkeitsmaximum)  ist.

e = Eulersche Zahl = 2,71828
ln() ist der natürliche Logarithmus.

mfg
Alex R.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Guido (Gast)

>Der Code braucht weniger Speicherplatz als eine vernünftige Tabelle, bei
>kleinen Controllern sehr nützlich.

Beweis?

>Die Dimm-Kurve ist einstellbar mit dem Faktor b, hier wären mehrere
>Tabellen notwendig.

Wer braucht diese Einstellung?

MfG
Falk

Autor: Guido (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
die werte in Fliesskommaarithmetik zu berechnen kostet viel Code wenn
nicht sowieso Fliesskommazahlen benutzt werden und ist sehr langsam.

Der code f. die formal ist weniger als 100 Byte während eine vernünftige
Tabelle ca. 255 Byte braucht.
Wer die dimmkurve anpassen möchte kann dies tun, kostet keinen 
zusätzlichen
Aufwand.
Gruss
  Guido

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.