Hallo Forum, ich zerbreche mir gerade den Kopf über einen Algorithmus zum Dimmen einer LED anhand 2 Parametern, an/aus und Geschwindigkeit. Gegeben ist eine 16Bit Hardware-PWM mit angenommen positiver Logik, 1=an. Die empfundene Helligkeit ist ja logarithmisch abhängig vom PWM-Wert. Wenn man jetzt eine LED langsam an-dimmen möchte, fängt man erstmal an zyklisch die Werte zu erhöhen, als Beispiel: 1,1,2,3,5,8,12, ... (logarithmisch mit Faktor x). Die Geschwindigkeit des Dimmens legt man dann über die Zykluszeit fest. Soweit so gut, aber jetzt zum praktische Problem: Die Differenzen oder Stufen zwischen zwei Werten werden zum Ende hin immer größer. Beim schnellen Dimmen kein Problem, aber besonderes wenn man langsam dimmt, fallen die Helligkeitsstufen dann besonderes auf. Die Hardware könnte es ja besser, es gibt ja genügend PWM-Stufen dazwischen. Als Lösung kann man einfach den Faktor ändern und die Zykluszeit verkürzen, z.B. 1,1,1,1,1,2,2,2,3,3,4,5,6,8... . Aber dann ist schnelles Dimmen nicht möglich, weil es einfach zu viele Stufen zwischen an und aus gibt. Die theoretische Lösung wäre Timer verlangsamen, wenn > 1ms zwischen den Stufen, Stufen überspringen wenn < 1ms. Da das ganze aber diskret läuft (also z.b. von 1 ms bis 2 ms gibt es keine Zwischenstufen) geht die logarithmische Funktion verloren. Das habe ich ausprobiert und es sieht mies aus. Ich suche also einen Algorithmus, der in 32 Bit Integer folgendes ausspuckt: nächste PWM-Stufen , Timer = Algo(aktueller PWM-Wert, Up/Down, Geschwindigkeit) Unter den Bedingungen: - Timer > 1ms in 1ms Schritten - PWM-Wert 0..1024 bis zu 0..4095 - Geschwindigkeit min 1 Sek bis 10min für einen kompletten Zyklus von an bis aus oder aus bis an. - freier Speicher mir Flash ca. 2..4 kB (große Tabellen fallen aus) Irgendwelche Ideen?
Ist nicht so ganz klar, deine Problematik. Vielleicht solltest du dir selbst mal eine grosse Excel Datei erstellen, da kann man viel machen.
Klaus F. schrieb: > Vielleicht solltest du dir selbst mal eine grosse Excel Datei erstellen Hab ich schon gemacht und komme nicht weiter. Harry L. schrieb: > https://de.wikipedia.org/wiki/Gammakorrektur Das hilft leider nicht weiter. Meines Erachtens nach liegen die Probleme hier in der praktischen Umsetzung. Mit Kommazahlen und unendlich feinem Timer ist die Aufgabe fast schon trivial.
Ich hab mal viel zum kompliziert gedacht. Problem gelöst, der Timer muss einfach nur konstant laufen, z.b. 1 ms. Dann läuft einfach ein Zähler mit, der die ms zählt. Davon bilde ich einfach das Quadrat und teile das ganze durch eine Faktor, der 1/Geschwindigkeit entspricht. Der Timer wird beendet, wenn zb. 4096 erreicht ist. Erledigt.
Rangi J. schrieb: > Davon bilde ich einfach das Quadrat und teile das ganze durch eine > Faktor, der 1/Geschwindigkeit entspricht. Vor du da mit dem Kehrwert der Geschwindigkeit herummachst, dann kannst du es stattdessen gleich mit einem Faktor multiplizieren, der der Geschwindigkeit entspricht.
Lothar M. schrieb: > einem Faktor multiplizieren korrekt in einer Gleitkomma-Welt. In der Interger-Welt funktioniert die Multiplikation nicht so gut, da immer ein Wert > 0 rauskommt.
Rangi J. schrieb: > Ich suche also einen Algorithmus In JEDEM PWM Zyklus (also z.B. Timer-Overflow Interrupt) rechnest du den duty cycle der PWM neu aus und schreibst sie ins Timerregister. Dabei weisst du, wie viel Zeit deiner Dimmkurve vergangen ist, weil der gesamte Dimmvorgang z.B. 10000 Timerdurchläufe benötigt und du erst im 42. Timerdurchlauf (mitzählen) bist. duty=gamma(durchlauf/gesamtdurchläufe)
Rangi J. schrieb: > In der Interger-Welt funktioniert die Multiplikation nicht so gut Oh doch, dafür wurde die Festpunktarithmetik erfunden: - https://de.wikipedia.org/wiki/Festkommazahl
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.