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
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?
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
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
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.
@ 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
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
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.