Forum: Compiler & IDEs RGB-Led Fading


von Bernd (Gast)


Lesenswert?

Ich habe ein paar Probleme beim Fading,es soll erst Hochgedimmt werden 
und dann wieder auf Null.

Es wird zwar hochgedimmt aber nicht mehr runter.
Wenn ich die Farbe Weiss zuerst aufrufe S_Dimm (  255 ,255,255);
und danach die Farbe Rot S_Dimm (  255 ,0,0); dann bleibt Weiss

Vielleicht kann mir wer weiterhelfen
mfg
1
//Aufruf
2
S_Dimm (  255 ,255,255); //Weiss 
3
4
5
//Helligkeit Dimmen
6
void S_Dimm (  uint8_t R,uint8_t G,uint8_t B)
7
{
8
   if ( Flag == 1) 
9
  {
10
           if( OCR1AL < R )
11
               OCR1AL++;
12
         
13
           if( OCR1BL < G )
14
               OCR1BL++;         
15
         
16
           if( OCR2 < B )
17
               OCR2++;               
18
         
19
     
20
     if (OCR1AL == R && OCR1BL == G && OCR2 == B ) 
21
     {
22
      Flag = 2;
23
     }
24
       }
25
    
26
        if ( Flag == 2) 
27
  {
28
           if( OCR1AL < 1 )
29
               OCR1AL--;
30
         
31
           if( OCR1BL < 1 )
32
               OCR1BL--;         
33
         
34
           if( OCR2 < 1 )
35
               OCR2--;        
36
      
37
     if (OCR1AL == 1 && OCR1BL == 1 && OCR2 == 1  ) 
38
     {
39
      Flag = 1;
40
     }
41
       }
42
43
}

von Stefan E. (sternst)


Lesenswert?

Überdenke die “< 1“.

von Bernd (Gast)


Lesenswert?

Bei S_Dimm (  255 ,255,255); //Weiss  wird Auf und Abgedimmt wird danach 
Zb. S_Dimm (  255 ,0,0); //Rot Aufgerufen geht das nicht immer und bei
S_Dimm (  0,255 ,0); //Grün gehts dann garnicht mehr.
mfg

1
//Helligkeit Dimmen
2
void S_Dimm (  uint8_t R,uint8_t G,uint8_t B)
3
4
{
5
   if ( Flag == 1) 
6
  {
7
           if( OCR1AL < R )
8
               OCR1AL++;
9
         
10
           if( OCR1BL < G )
11
               OCR1BL++;         
12
         
13
           if( OCR2 < B )
14
               OCR2++;               
15
         
16
     
17
     if (OCR1AL == R && OCR1BL == G && OCR2 == B ) 
18
     {
19
      Flag = 2;
20
     }
21
   }
22
    
23
   if ( Flag == 2) 
24
   {
25
           if( OCR1AL > 1 )
26
               OCR1AL--;
27
         
28
           if( OCR1BL > 1 )
29
               OCR1BL--;         
30
         
31
           if( OCR2 > 1 )
32
               OCR2--;        
33
      
34
      if (OCR1AL == 1 && OCR1BL == 1 && OCR2 == 1  ) 
35
      {
36
       Flag = 1;
37
      }
38
   }
39
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich habe mir nicht die Mühe gemacht, die Logik bis zu Ende zu
verstehen, aber meiner Meinung nach sollte das
1
if ( Flag == 2)

ein
1
else if ( Flag == 2)

sein, damit ein am Ende der ersten if-Anweisung bereits auf 2
gesetztes "Flag" nicht sofort danach die zweite if-Anweisung wahr
werden lässt.

von Bernd (Gast)


Lesenswert?

Ich wollte die Farben auf und ab Dimmen lassen aber Funktionieren tut 
das nur mit der Farbe Weiss.

Das geht einwandfrei
S_Dimm (  255 ,255,255); //Weiss

Das geht nicht,
es wird zuerst auf Weiss hogedimmt dann auf Rot und wieder auf weiss
S_Dimm (  255 ,0,0); //Weiss

Das geht auch nicht
S_Dimm (  255 ,255,0);
S_Dimm (  255 ,0,255);

von Stefan E. (sternst)


Lesenswert?

Du lässt die Werte beim Runterdimmen bei 1 enden. Wenn die Funktion dann 
mit Nullen als Argumente aufgerufen wird, wie soll dann je das "== R" 
(oder G oder B) erfüllt werden? Ergo wird dann Flag nie 2.

von Michael (Gast)


Lesenswert?

Bernd schrieb:
> Vielleicht kann mir wer weiterhelfen

Warum verfolgst du den Ablauf nicht im Simulator deiner 
Entwicklungsumgebung?
Dann könntest du genau zusehen, an welcher Stelle sich das Programm 
nicht so verhält, wie du es möchtest.

von Bernd (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Du lässt die Werte beim Runterdimmen bei 1 enden. Wenn die Funktion dann
> mit Nullen als Argumente aufgerufen wird, wie soll dann je das "== R"
> (oder G oder B) erfüllt werden? Ergo wird dann Flag nie 2.

Aber wie macht mann das richtig.
Vielleicht kann mir noch einer weiterhelfen
mfg

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:
> Stefan Ernst schrieb:
>> Du lässt die Werte beim Runterdimmen bei 1 enden. Wenn die Funktion dann
>> mit Nullen als Argumente aufgerufen wird, wie soll dann je das "== R"
>> (oder G oder B) erfüllt werden? Ergo wird dann Flag nie 2.
>
> Aber wie macht mann das richtig.
> Vielleicht kann mir noch einer weiterhelfen


Warum lässt du hier
>      if (OCR1AL == 1 && OCR1BL == 1 && OCR2 == 1  )

bei 1 umdrehen?
Der kleinste Wert, der möglich ist, ist immer noch 0. Und zwar in allen 
3 Farben.


Aber im Grunde hilft dir auch das nicht.
Was du brauchst ist eine Hilfsvariable, die von 0.0 bis 1.0 läuft und 
angibt welcher Bruchteil der vorgegebenen Farbe zur Zeit gerade 
angezeigt werden soll.

Nennen wir sie einfach mal t.
Deine Vorgabefarbe sei zb ein helles Gelb, mit R = 255, G = 255 und B = 
99

Wenn t gleich 0 ist, dann ist die auszugebende Farbe

  R_angezeigt = R * t = 255 * 0.0 = 0.0
  G_angezeigt = G * t = 255 * 0.0 = 0.0
  B_angezeigt = B * t =  99 * 0.0 = 0.0

also wird bei t gleich 0 an den LED eine Farbe 0.0\0.0\0.0 realisiert. 
Ein Schwarz. Und genau das ist ja auch ein helles Gelb, wenn es 
vollständig abgedimmt ist.
Ist auf der anderen Seite das t bei 0.5 angelangt (also halbe Dimmung), 
dann hast du

  R_angezeigt = R * t = 255 * 0.5 = 127.5
  G_angezeigt = G * t = 255 * 0.5 = 127.5
  B_angezeigt = B * t =  99 * 0.5 =  45.5

als wird bei t gleich 0.5 an den LED eine Farbe 127\127\45 realisiert. 
Ungefähr die hälfte der RGB Werte der Farbe, die du vorgegeben hast.

Und bei t gleich 1.0 kommt dann eben raus

  R_angezeigt = R * t = 255 * 1.0 = 255
  G_angezeigt = G * t = 255 * 1.0 = 255
  B_angezeigt = B * t =  99 * 1.0 =  99

also genau die Farbe, die du vorgegeben hast.

Und bei anderen Wert von t (zb 0.3 oder 0.7 oder 0.4 oder ...) dann eben 
der entsprechende Bruchteil deiner Vorgabefarbe.

Ergo: Durch Variation von t im Bereich 0 bis 1 und multiplizieren mit 
den R\G\B Werten, kriegst du die R\G\B Werte, die du an die LED geben 
willst, wobei das t angibt, wie 'stark die angegebene Farbe zu 
realisieren ist'. Bei t gleich 0 kommt immer schwarz raus, bei t gleich 
1 kommt immer die angegebene Farbe raus. Und bei Werten von t dazwischen 
ergibt sich dann ein unterschiedlicher "Grad der Helligkeit der Farbe". 
Die stimmt zwar im Sinne eines HLS oder HSV Farbmodells nicht ganz, aber 
da auch RGB-LED nicht so ganz genau in der Farbe steuerbar sind, kann 
man ruhig den Papst in Rom lassen und die Sache erst mal auf die 
einfache Tour machen.

Du kennst das ganze unter dem Namen Prozentrechnung. Denn t ist nichts 
anderes als die Prozent der zu realisierenden Farbe. Du lässt die 
Prozentzahl variiieren und rechnest dir aus, wieviele Prozent der 
'vollen Farbe' du zu jedem Zeitpunkt haben willst.



Natürlich nimmst du im µC keine Flieskommazahlen, sondern versucht alles 
als ganze Zahlen zu rechnen. Ist ja auch kein Problem. Anstatt t von 0.0 
bis 1.0 laufen zu lassen, kannst du t ja auch von 0 bis 255 laufen 
lassen und dafür dann eben hinterher noch mal durch 255 (oder 256, ist 
für den µC einfacher zu rechnen und der Unterschied ist kaum merkbar) 
dividieren. Kommt bei der notwendigen Genauigkeit aufs selbe raus.

(Und nenn deine Variablen ein wenig besser. Die Variable Flag hat eine 
Aufgabe. Nenn die Variablen nach ihrer Aufgabe!)

1
uint8_t t;
2
3
void Dimm_S( uint8_t R, uint8_t G, uint8_t B )
4
{ 
5
  if( DimmUp )
6
  {
7
    if( t < 255 )
8
      t++;
9
    else
10
      DimmUp = FALSE;
11
  }
12
  else {
13
    if( t > 0 )
14
      t--;
15
    else
16
      DimmUp = TRUE;
17
  }
18
19
  OCR1AL = R * t / 255;
20
  OCR1BL = G * t / 255;
21
  OCR2   = B * t / 255;
22
}

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
Noch kein Account? Hier anmelden.