Guten Tag,
ich habe soeben meine LED per PWM langsam aufdimmen lassen. Allerdings
geht mir das ganze noch etwas unflüssig. Anfangs flackert sie ein wenig
und dann ist sie schon fast voll da. Ich habe schon versucht, an den
Werten des Zählers rumzuspielen aber das Ergebnis ist immer das gleiche.
Außerdem würde ich gern, dass die LED, nachdem die komplett an ist,
wieder ausgeht und von neuem anfängt zu dimmen. Auch das gelingt mit
irgendwie nicht.
1
intmain(void)
2
{DDRE=(1<<PE4);//PB4 als Ausgang setzen
3
4
TCCR3A=(1<<COM3B1);//Clear OC3B Compare Match
5
6
TCCR3A|=(1<<WGM31)|(1<<WGM30);//Fast PWM, Top auf OCR3A
7
TCCR3B=(1<<WGM32)|(1<<WGM33);
8
9
TCCR3B|=(1<<CS32)|(1<<CS30);//Presclaer 1024, bei Zählen bis 80 --> etwa 195Hz
Heinz schrieb:> ich habe soeben meine LED per PWM langsam aufdimmen lassen. Allerdings> geht mir das ganze noch etwas unflüssig. Anfangs flackert sie ein wenig> und dann ist sie schon fast voll da. Ich habe schon versucht, an den> Werten des Zählers rumzuspielen aber das Ergebnis ist immer das gleiche.
Weil das ganze logarithmisch gehen muss, nicht linear.
> Außerdem würde ich gern, dass die LED, nachdem die komplett an ist,> wieder ausgeht und von neuem anfängt zu dimmen. Auch das gelingt mit> irgendwie nicht.
Eine Tabelle mit, sagen wir 64 logarithmischen Werten erstellen.
Eine signed Variable als Richtung definieren, Anfangswert 1.
Noch eine signed Variable als Pointer definieren, Anfangswert 0.
In main() mittels Pointer aus der Tabelle Wert für OCR einstellen.
Pointer und Richtung addieren.
Wenn größer 63, Richtungsvariable auf -1 setzen.
Wenn kleiner 0, Richtungsvariable wieder auf 1 setzen.
Das ist alles.
Natürlich kann deine Tabelle größer sein.
Heinz schrieb:> geht mir das ganze noch etwas unflüssig. Anfangs flackert sie ein wenig> und dann ist sie schon fast voll da. Ich habe schon versucht, an den> Werten des Zählers rumzuspielen aber das Ergebnis ist immer das gleiche.
Kein Wunder.
Das Problem liegt ganz woanders. Nämlich in deinem Auge bzw. in deinem
Gehirn und der Art und Weise wie dort Helligkeiten bewertet werden. Die
sind nicht linear, sondern exponentiell. Als Ausgleich müssen deine
Werte logarithmisch ansteigen.
> Außerdem würde ich gern, dass die LED, nachdem die komplett an ist,> wieder ausgeht und von neuem anfängt zu dimmen. Auch das gelingt mit> irgendwie nicht.
Weil du dich nicht an ein ehernes Prinzip gehalten hast.
Ein µC Programm sieht prinzipiell IMMER so aus
1
intmain()
2
{
3
Initialisierung
4
5
while(1){
6
7
Programmlogik
8
9
}
10
}
Beachte die Endlosschleife! Die ist immer da und die ist immer einen
Endlosschleife. Innerhalb dieser Endlosschleife machst du deine
Programmlogik. Und auch wenn diese Programmlogik aus einer (oder
mehreren) Schleifen besteht, so hast du trotzdem immer diese
Endlosschleife.
Was ist deine Programmlogik?
Du willst aufdimmen. Dazu reicht es, wenn du a entsprechend bis zum Wert
max hochzählst und den Wert ins OCR3A Register überträgst.
Dann mach das doch
1
....
2
3
while(1){
4
5
// von min bis max
6
a=min;
7
while(a<max){
8
a++;
9
OCR3A=a;
10
_delay_ms(100);
11
}
12
13
}
14
}
was soll deine Programmlogik noch machen?
Wenn das hochdimmen beendet ist, willst du wieder runter dimmen.
Gut. Dann mach das doch
Danke @Mark und Chris, ich habe den Artikel noch gar nicht gesehen und
werde mich dem mal annehmen.
> was soll deine Programmlogik noch machen?> Wenn das hochdimmen beendet ist, willst du wieder runter dimmen.> Gut. Dann mach das doch>> ....>> while( 1 ) {>> // von min bis max> a = min;> while( a < max ) {> a++;> OCR3A = a;> _delay_ms( 100 );> }>> // von max bis min> a = max;> while( a > min ) {> a--;> OCR3A = a;> _delay_ms( 100 );> }
Oh sorry das mit der Endlosschleife habe ich ganz verdrängt. Allerdings
gibt es jetzt mit dem Code nur ein einmales, kurzes Aufflackern. Ich
habe den Delay bereits hoch gesetzt, und auch den Max- Wert geändert.
Hat alles nichts geholfen.
Heinz schrieb:> Oh sorry das mit der Endlosschleife habe ich ganz verdrängt. Allerdings> gibt es jetzt mit dem Code nur ein einmales, kurzes Aufflackern. Ich
Mit Code von Karl Heinz ?
Glaube ich kaum.
Poste doch alles.
Heinz schrieb:> Also die LED leuchtet einmal auf und bleibt dann an.
Über welchen Zeitrum reden wir?
Dir ist hoffentlich schon klar, dass das vollständige hochdimmen bei 100
Millisekunden und 80 Schritten, ganze 8 Sekunden dauert?
Das hört sich nicht viel an, wenn man aber vor der LED sitzt und darauf
wartet, sind 8 Sekunden laaaang.
Und wenn dein _delay_ms nicht korrekt funktioniert, weil es da eine
Diskrepanz zwischen F_CPU und tatsächlicher Taktfrequenz des µC gibt,
dann kann sich diese Zeit schnell noch mal ordentlich verlängern.
TCCR3A|=(1<<WGM31)|(1<<WGM30);//Fast PWM, Top auf OCR3A
2
TCCR3B=(1<<WGM32)|(1<<WGM33);
nein das willst du nicht.
Wenn du OCR3A benutzen willst um damit den Tastgrad deiner LED
einzustellen, dann kannst du nicht den Modus benutzen, in dem OCR3A den
TOP Wert festlegt.
Eigentlich dachte ich, es geht hier um das DImmen einer LED. Da bin ich
schon davon ausgegangen, dass du erst mal deine PWM grundsätzlich
getestet hast, in dem du unterschiedliche fixe Werte in OCR3A
geschrieben hast und nachgesehen hast, ob die LED auch wirklich dann
auch unterschiedlich hell leuchtet.
Aber scheinbar darf man in letzter Zeit von wirklich gar nichts mehr
ausgehen und man muss alles bis ins kleinste Detail überprüfen.
Welcher Prozessor ist das überhaupt?
Mal sehen, was du da eigentlich wirklich eingestellt hast. Denn eines
hab ich im Laufe der Jahre auch gelernt: traue keinem Kommentar. Die
sind öfter falsch als richtig.
Karl Heinz schrieb:> An welchem Pin hängt deine LED?Heinz schrieb:> Die ist am PE4 zusammen mit dem OC3B (also Timer 3)!> { DDRE= (1<<PE4); //PB4 als Ausgang setzen
Wie man eindeutig aus dem Kommentar sehen kann.
Also:
Welcher Kontroller ?
Wie schnell ?
Was is'n nu?
Das kann doch nicht so schwer sein, die Typenbezeichnung des µC zu
nennen.
Oder denkst du, wir wissen alle auswendig, bei welchen µC der PE4 die
Zweitfunktion OCR3B hat?
Disclaimer:
Die AVR sind sich soweit alle eigentlich recht ähnlich, so dass man ins
Blaue hinein eine entsprechende PWM schreiben könnte. Aber mir gehts
hier auch ein bisschen ums Prinzip, dass man in einer Anfrage auch immer
den konkreten µc-Typ nennt.
Karl Heinz schrieb:> Die sind nicht linear, sondern exponentiell. Als Ausgleich müssen deine> Werte logarithmisch ansteigen.
Das Auge weiß natürlich nichts von höherer Mathematik, sondern sagt sich
nur, wenn es doppelt so hell sein soll, muss auch doppelt so viel Licht
ankommen und wenn die Helligkeit gleichmäßig ansteigen soll, muss der
Faktor zwischen zwei aufeinander folgenden Helligkeitsstufen konstant
sein.
Wenn man allerdings in Einerschritten hochzählt, steigt der Wert von 0
auf 1 auf 2 auf 3 auf 4 usw., d.h. im ersten Schritt geht das Licht
plötzlich an, dann verdoppelt sich die Helligkeit von 1 auf 2, von 2
auf 3 nimmt sie nur noch auf das 1.5-fache zu, von 3 auf 4 nur noch um
das 1.3-fache und bei z.B. hättest du zwischen zwei Stufen nur einen
Faktor 51/50=1.02, was nur noch sehr mühselig als Helligkeitsanstieg
wahrnehmbar ist.
>Das Problem liegt ganz woanders. Nämlich in deinem Auge bzw. in deinem>Gehirn und der Art und Weise wie dort Helligkeiten bewertet werden. Die>sind nicht linear, sondern exponentiell. Als Ausgleich müssen deine>Werte logarithmisch ansteigen.
Genaugenommen ist es andersrum: Das Auge-Gehirn-System logarithmiert bei
der Intensitätsbewertung und deshalb müssen die PWM-Einschaltdauern zum
Ausgleich exponentiell ansteigen (*), um einen linearen
Helligkeitseindruck zu erhalten.
(*) Beispielsweise bei einer 8-bit-PWM in der Folge
1
1/256 im zeitlichen Mittel eingeschaltet,
2
1/128 "
3
1/64 "
4
1/32 "
5
1/16 "
6
1/8 "
7
1/4 "
8
1/2 "
9
dauerhaft eingeschaltet.
Das ergibt eine als gleichmäßig abgestuft empfundene Hochdimmung.
Heinz schrieb:> Oh sorry das mit der Endlosschleife habe ich ganz verdrängt. Allerdings> gibt es jetzt mit dem Code nur ein einmales, kurzes Aufflackern.> Also die LED leuchtet einmal auf und bleibt dann an.
Was denn jetzt ?
Marc Vesely schrieb:> Heinz schrieb:>> Oh sorry das mit der Endlosschleife habe ich ganz verdrängt. Allerdings>> gibt es jetzt mit dem Code nur ein einmales, kurzes Aufflackern.>>> Also die LED leuchtet einmal auf und bleibt dann an.>> Was denn jetzt ?
nehm ich alles nicht mehr ernst, seit mir trotz aufwendiger
Ablenkungsaktion seinerseits klar geworden ist, dass er eigentlich am
TOP Wert rumspielt und nicht an der Pulsweite.
LostInMusic schrieb:> Ausgleich exponentiell ansteigen (*), um einen linearen> Helligkeitseindruck zu erhalten.>> (*) Beispielsweise bei einer 8-bit-PWM in der Folge> 1/256 im zeitlichen Mittel eingeschaltet,> 1/128 "> 1/64 "
Damit kannst du zwar dimmen, hast aber nur 7 Schritte bei 8 bit.
Mit n*1,2x kriegt man es (nicht ganz genau) aber ziemlich gut hin.