Forum: Mikrocontroller und Digitale Elektronik RGB-LED Farbmischung - Farbverlaufsteuerung


von H. G. (ledi)


Lesenswert?

Hallo!

Ich möchte eine RGB-LED mit einer automatischen Farbverlaufssteuerung 
ansteuern und bin auf der Suche nach einer optimalen Routine in C.

Ich verwende hier die PWM-Kanäle des AT90PWM316.
Derzeit vermische ich die Farben mit if-else-Abfragen.
Die RGB-Werte habe ich in einem Array (valuetable) gespeichert.
1
const unsigned int valuetable[256]=  // = logarithmische Werte
2
{           
3
  0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,
4
  2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,
5
  3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,
6
  5,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,
7
  8,8,9,9,9,9,10,10,10,11,11,12,12,12,13,13,
8
  14,14,15,15,15,16,17,17,18,18,19,19,20,21,21,22,
9
  23,24,24,25,26,27,28,29,30,31,32,33,34,35,36,37,
10
  39,40,41,43,44,45,47,48,50,52,53,55,57,59,61,63,
11
  65,67,69,72,74,77,79,82,84,87,90,93,96,99,103,106,
12
  110,113,117,121,125,129,133,138,142,147,152,157,162,168,173,179,
13
  185,191,197,204,210,217,225,232,240,248,256,264,273,282,292,301,
14
  311,322,332,343,355,366,379,391,404,417,431,446,460,476,491,508,
15
  525,542,560,579,598,618,638,659,681,704,727,751,776,802,828,856,
16
  884,913,944,975,1007,1041,1075,1111,1148,1186,1225,1266,1308,1351,1396,1442,
17
  1490,1539,1590,1643,1697,1754,1812,1872,1934,1998,2064,2133,2203,2277,2352,2430,
18
  2511,2594,2680,2769,2860,2955,3053,3154,3259,3367,3479,3594,3713,3836,3964,4095
19
};

Hier ein Beispiel meine Farbverlaufssteuerung:
1
if( Taste == 5 && Zaehler == 4 ) 
2
    {
3
        OCR1SB = valuetable[ 0 ];
4
           OCR1SA = valuetable[ B + actEntry_B ];
5
         OCR0SA = valuetable[ R + actEntry_R ];
6
7
      if ( Increasing_B == 1)
8
      {     
9
            if( actEntry_B == 255) 
10
        {
11
          if( actEntry_R == 255)
12
          {
13
            Increasing_B = 0;
14
            Increasing_R = 0;
15
          }
16
          else
17
                  actEntry_R++;
18
            }
19
            else
20
                actEntry_B++;
21
       }
22
      
23
        else 
24
      {
25
            if( actEntry_B == 0 ) 
26
        {
27
                 Increasing_B = 1;
28
                 actEntry_B = 1;
29
            }
30
            else 
31
        {
32
                 actEntry_B--;
33
          _delay_ms(30);
34
          if ( actEntry_B == 0 )
35
            Increasing_B = 1;
36
        }      
37
       }
38
      for (i=0; i<time; ++i)
39
      {
40
        _delay_ms(1);
41
      }
42
    }

Hat jemand einen Vorschlag, wie ich das besser machen kann?

Danke für Eure Hilfe!

von Frager (Gast)


Lesenswert?

Heimo G. schrieb:
> optimalen Routine in C

Optimal bezüglich was?
Rechenzeit, Codelänge, Farbverlauf, Helligkeitsverlauf ...

von H. G. (ledi)


Lesenswert?

Frager schrieb:
> Optimal bezüglich was?
>
> Rechenzeit, Codelänge, Farbverlauf, Helligkeitsverlauf ...


Farbverlauf!

von Frager (Gast)


Lesenswert?

Eine exakte Umsetzung von Spektralfarben in RGB gibt es nicht, da LEDs 
nicht den vollen Farbraum aufspannen.

Verschiedene Approximationen mit Algorithmen gibt es z.B. hier
http://mintaka.sdsu.edu/GF/explain/optics/rendering.html

von Eneloop (Gast)


Lesenswert?

HSV->RGB umwandlung gibts z.B. hier:

Beitrag "Re: HSV RGB Led Dimmer, C Code & Video & Doku"

Für deinen Farbverlauf änderst du nur den H-Wert.

von Karl H. (kbuchegg)


Lesenswert?

Heimo G. schrieb:
> Frager schrieb:
>> Optimal bezüglich was?
>>
>> Rechenzeit, Codelänge, Farbverlauf, Helligkeitsverlauf ...
>
>
> Farbverlauf!

Und das muss man sich jetzt wie vorstellen?
Ich hab jetzt dein Verfahren nicht analysiert. Was ist falsch daran?

HSV-RGB Umwandlung ist natürlich eine Möglichkeit. Eine andere ist 
folgende:

Du beginnst im Grundzustand Rot. Also RGB = (1,0,0)
Danach beginnt ein Sweep, indem Grün dazu kommt. Von 0 auf 1 in 
Schritten hochfahren. Damit ist man im Zustand RGB = (1,1,0)
Danach wird Rot weggenommen und man landet bei RGB = (0,1,0)
Jetzt kommt Blau dazu um bei RGB= (0,1,1) zu landen.
Grün weg, führt zu RGB = (0,0,1)
Rot dazu -> RGB = (1,0,1)
Und Blau wegnehmen RGB = (1,0,0)

Damit ist man wieder im Grundzustand und das Spielchen beginnt wieder 
von vorne.

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Karl Heinz Buchegger schrieb:

> Damit ist man wieder im Grundzustand und das Spielchen beginnt wieder
> von vorne.


So wie im Diagramm würden dann die einzelnen Farben anzusteuern sein.
Man sieht:
* Das ganze läuft in 6 Stufen ab
* Im Prinzip durchlaufen alle Kanäle die gleiche Kurve und sind
  nur gegeneinander phasenverschoben.

Die Implementierung dazu ist eher simpel und für praktische Zwecke zur 
Wohnraumverschönerung mehr als ausreichend.

von Vlad T. (vlad_tepesch)


Lesenswert?

das ist ja HSV->RGB
mit S und V = 1
also eigentlich Hue -> RBG

von Frager (Gast)


Lesenswert?

Da die LEDs im CIE Farbdiagramm allerdings irgendwo mitten drin liegen, 
lassen sich viele Bereiche, insbesondere reine Spektralfarben (tiefes 
Rot und Blau-Grüntöne) prinzipiell nicht erreichen. Wenn es nur 
irgendwie bunt sein soll, geht es natürlich.

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.