Seid gegrüßt, ich rechne nun schon seit Stunden herum, komme aber auf keine funktionierende Lösung. Ich versuche ein Fading für eine LED (über PWM) hinzubekommen... int16_t nFadeCount = 0; // Zähler für das Überblenden(Fading) int16_t nFadingTime = 200; int16_t nSavedPWM = 100; // Variable zur Speicherung des letzten Helligkeitswertes nFadeCount++; if(nFadeCount <= nFadingTime) OCR1A += nSavedPWM/nFadingTime; ... steh aber irgendwie auf dem Schlauch. Der hier gezeigte Ansatz geht zwar 'irgendwie', aber nur, solang nSavedPWM>nFadingTime ist. Wichtig: OCR1A kann nur int-Werte annehmen und das Fading soll relativ gleichmäßig gehen Wenn also z.B. nFadingTime=1000 und nSavedPWM=100 wäre, sollte OCR1A in jedem 10sten Schritt um 1 erhöht werden. Wie kann man das umsetzen? Würde mich über jeden Ansatz freuen. Viele Grüße
Newbie schrieb: > Wenn also z.B. nFadingTime=1000 und nSavedPWM=100 wäre, sollte OCR1A in > jedem 10sten Schritt um 1 erhöht werden. Das ist der falsche Ansatz. Wenn das Fading gleichmäßig gehen soll, muß die LED logarithmisch angesteuert werden (-> Weber-Fechner-Gesetz)
Newbie schrieb: Abgesehen von der logarithmischen Verteilung von der Matthias gesprochen hat. > Wenn also z.B. nFadingTime=1000 und nSavedPWM=100 wäre, sollte OCR1A in > jedem 10sten Schritt um 1 erhöht werden. > Wie kann man das umsetzen? Was hindert dich daran, auszurechnen, wieviele Schritte notwendig sind, ehe OCR1A wieder um 1 erhöht werden soll? Wenn ein Computer etwas ganz gut kann, dann ist das Berechnungen ausführen.
Hi Matthias, ich glaub, du beziehst dich auf die LED-Kennlinie. Ähm... jepp, ich hab mich da wohl falsch ausgedrückt. Ich meinte eigentlich 'gleichmäßiges Abarbeiten des nSavedPWM-Wertes'. (Für die Ansteuerung der LED-Helligkeit werd' ich mir später eine Tabelle anlegen.) LG
Newbie schrieb: > ich glaub, du beziehst dich auf die LED-Kennlinie. Nein, auf die Helligkeitswahrnehmung. Bei PWM spielt die Kennlinie keine Rolle, weil immer der volle Strom fließt.
Hallo Karl, bei z.B. nFadingTime=1000 und nSavedPWM=100 ist das leicht. Da hab ich int-Werte und vielfache von einander. Was ist aber bei z.B. nFadingTime=133 und nSavedPWM=633? Dann müßte bei jedem 133/633sten Schritt weitergezählt werden. Und dann WIE den Faktor einbauen - es kann ja nur in int-Werten weitergezählt werden? Von Mathe versteh ich schon was, aber ich verzweifle langsam echt an der Umsetzung.:( Viele Grüße
> es kann ja nur in int-Werten weitergezählt werden?
Nö - auch mit Festkommazahlen.
int32_t nSavedPWM_32 = (int32_t)nSavedPWM << 16;
OCR1A += (nSavedPWM_32/nFadingTime) >> 16;
Einfach mal drüber schlafen. Morgen löst sich der Knoten von alleine
auf.
-- Grüße.
Alles zurück. Natürlich muss OCR1A eine Festkommazahl sein. int32_t nSavedPWM_32 = (int32_t)nSavedPWM << 16; int32_t OCR1A_32 = (int32_t)OCR1A << 16; OCR1A_32 += (nSavedPWM_32/nFadingTime); OCR1A = OCR1A_32 >> 16;
Hi, ich bekomme für die erste Zeile eine Fehlermeldung: initializer element is not constant ? Viele Grüße
Newbie schrieb: > Hi, > > ich bekomme für die erste Zeile eine Fehlermeldung: > initializer element is not constant > > ? Na, ja. Was ist dein ein 'Initializer'? Das womit eine Variable initialisiert wird. Und der muss an bestimmten Stellen (zb globale Variablen) konstant sein. Bei dir ist er das nicht. Mach halt eine normale Zuweisung draus, und dann passt es wieder anstelle
1 | int32_t nSavedPWM_32 = (int32_t)nSavedPWM << 16; |
dann eben
1 | int32_t nSavedPWM_32; |
2 | |
3 | |
4 | int main() |
5 | {
|
6 | nSavedPWM = ....; |
7 | nSavedPWM_32 = (int32_t)nSavedPWM << 16; |
8 | }
|
oder wie es dann eben bei dir passt. Im übrigen ist es doch einfach. Was tust du denn, wenn du in Euros rechnen sollst, aber keine Kommazahlen haben darfst. Du sollstz 2.80 Euro + 3.40 Euro rechnen, ohne Kommazahlen. Dann rechnest du eben in Cent! 280 Cent + 340 Cent. Und schon kannst du das rechnen, ohne Kommazahlen benutzen zu müssen. So auch hier Wenn du 133/633 rechnen musst, dir aber nur das Ganzzahlige Ergebnis zu wenig ist (weil 0), dann rechnest du eben 1330/633, das macht 2. Du merkst dir einfach, dass die 2 (oder allgemeiner: die Einer deines Ergebnisses) eigentlich schon die erste Kommastelle sind. Und wenn die 1 Kommastelle nicht reicht, dann rechnest du eben 13300/633, das mach 21 und du merkst dir, dass die Zehner und die Einer die ersten beiden Kommastellen sind. Wenn du ans OCR zuweist, musst du die beiden Stellen loswerden, das sollte aber einfach sein: dividieren durch 100 reicht. Addierst du also 21 21 21 21 21 21 ---- 126 dann hast du laut deiner Systematik eigentlich 5 * 0.21 = 1.26 errechnet. Bei dir dann eben 126 / 100 -> 1, die ins OCR kommt. Und schon hast du mit 2 Nachkommastellen gerechnet ohne Kommazahlen benutzen zu müssen. In einem Computerprogramm wird man natürlich sinnvollerweise nicht Vielfache von 10 nehmen (so wie bei den Cent) sondern Vielfache von 2, weil man die dann wieder leicht loswerden kann (anstelle von Dividieren verschiebt man einfach die Bits), aber das Prinzip ist völlig identisch.
Hallo Karl, sooooooooooooooooooooo, jetzt raucht mir der Kopf.;-))) Ich glaube, diese etwas längere Übung mit der 0,21... hab' ich nicht so wirklich verstanden - auch nach zwei Stunden Brainstorming!:( ABER... nachdem ich mir nochmal ganz intensiv eure zwei Beiträge (u.a. mein C-Buch zu Operatoren) durchlas, und zudem sah, dass mein ATMega88 bei Verwendung einer einzigen float-Variable gleich 400% meiner ursprünglichen Speicherkapazität verbraucht (65% Speicherauslastung bei etwa 200 Zeilen Programmcode^^), hab ich endlich die Shiftoperation kappiert - da ich auch scheinbar gar nicht mehr daran vorbei komme. Jippiiieieee, Schweinebacke;-) DANKE!^^ Gott, ich hab's mir ja vorher so unglaublich schwer mit dem Basteln einer passenden Gleichung gemacht. So sieht das jetzt schon mal aus: OCR1A = nFadeCount*((nSavedPWM<<2)/(nFadingTime<<2)); Nun hab' ich nur noch ein ganz ein kleines Problem. Der nSavedPWM-Maximalwert wird so niemals erreicht, da mit dieser Zeile ja stets zumindest ein ganz ein kleines Stückerl abgeschnitten wird. Mal guggn, wie lang ich brauche, um draufzukommen. ODER ein "Wissender" schaut vl. mal kurz drüber und gibt mir einen 'Wink'.;-)) Liebe Grüße
EDIT: ... nehm alles zurück......... groooooooooooooooßer Denkfehler drin:( LG
Ok, jetzt scheint's zu gehen. Wie "Kein Name" schon aufzeigte: int32_t nSavedPWM_32 = (int32_t)nSavedPWM << 16; int32_t OCR1A_32 = (int32_t)OCR1A << 16; OCR1A_32 = nFadeCount*(nSavedPWM_32/nFadingTime); OCR1A = OCR1A_32 >> 16; Ich muß die Bitmanipulation wohl doch noch mal gründlich studieren.;-))) Danke! LG
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.