Gast
#1840091
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
