Forum: Mikrocontroller und Digitale Elektronik RGB-Farbe dimmen


von Alex (Gast)


Lesenswert?

Ich hab zur Zeit folgendes Problem:

ich will ein- oder mehrere RGB-Leds ansteuern, dafür halte ich die Rot-, 
Grün- und Blauwerte jeweils als 8-Bit Werte in der Software vor.
Das klappt alles.

Nun würde ich gerne die LED dimmen, abhängg von einem externen 
Helligkeitssensor (= Photodiode).
Desen ADC-Wert liegt mir ebenfalls als 8-Bit-Wert vor.
Dabei soll natürlich die "Farbe" erhalten bleiben.

Wie würde die dazu notwendige Berechnung ausschauen?
Kann ich direkt jeden der 3 Farbwerte (RGB) mit einem Faktor 
multiplizieren?
Oder muss ich den RGB Wert zunächst in HSV umrechnen, dort dimmen, und 
wieder zu RGB zurückrechnen?

Wie würde man die HSV-Farbe dimmen?

Gruß,
Alex

von Joachim B. (jar)


Lesenswert?

Alex schrieb:
> Oder muss ich den RGB Wert zunächst in HSV umrechnen,

davon gehe ich mal aus, wüsste aber nicht wie.

Kennst du den Artikel LED Fading?

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:

> Dabei soll natürlich die "Farbe" erhalten bleiben.

Das ist ein Problem.

> Wie würde die dazu notwendige Berechnung ausschauen?

Das kommt jetzt drauf an, was du dir unter 'Farbe erhalten' so 
vorstellst.

> Kann ich direkt jeden der 3 Farbwerte (RGB) mit einem Faktor
> multiplizieren?

Kannst du natürlich machen. Je nachdem wie pingelig du bist, wird das 
Ergebnis aber nicht unbedingt das sein, was du dir vorstellst.

> Oder muss ich den RGB Wert zunächst in HSV umrechnen, dort dimmen, und
> wieder zu RGB zurückrechnen?
>
> Wie würde man die HSV-Farbe dimmen?

H    Hue, grob gesagt der Farbton
S    Saturation, die Farbsättigung. An dem einen Ende der Skala steht zb 
Rot, am anderen Ende steht ein reiner Grauton.
V    Value, die Helligkeit


Dimmen bedeutet also: V variieren, wenn man von der Farbe in Richtung 
schwarz dimmen will.
Will man in Richtung weiß variieren, müsste man S auch noch mit dazu 
nehmen. Im HSL Farraum geht das einfacher. Da wird immer nur L variiert.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> nehmen. Im HSL Farraum geht das einfacher. Da wird immer nur L variiert.


Tschuldigung
HLS. Nicht HSL

von Karl H. (kbuchegg)


Lesenswert?

Aber ich würdsd ehrlich gesagt mal mit einem ganz simplen Faktor im RGB 
Raum probieren.
Zumal tatsächlich farbgetreues Dimmen eine Kunst für sich ist und von 
vielen Dingen abhängt.

Wenns dir nur darum geht, dass eine lila 'Lampe' bei Dunkelheit 
abgedunkelt ist und dabei immer noch 'lila' aussieht, dann reicht das 
ziemlich sicher völlig aus.

von Chefkoch (Gast)


Lesenswert?

Was ich bei diesem Themengebiet noch nicht verstanden habe:

Es gibt zwar diverse Farbräume, aber letztlich hat man eine RGB LED. Wo 
ist der Gewinn, wenn ein Farbraum definiert wird, der dann (so wie ich 
das sehe) ohnehin auf das physisch vorhandene RGB umgerechnet werden 
muss. Das eigentliche Problem der Auflösung bleibt doch?

von npn (Gast)


Lesenswert?

Karl Heinz schrieb:
> Tschuldigung
> HLS. Nicht HSL

Warum Entschuldigung? HSL war schon richtig (hue-saturation-lightness).

von Karl H. (kbuchegg)


Lesenswert?

Chefkoch schrieb:

> Es gibt zwar diverse Farbräume, aber letztlich hat man eine RGB LED. Wo
> ist der Gewinn, wenn ein Farbraum definiert wird, der dann (so wie ich
> das sehe) ohnehin auf das physisch vorhandene RGB umgerechnet werden
> muss. Das eigentliche Problem der Auflösung bleibt doch?

Das eigentliche Problem mit RGB ist, dass es kein "Distanzmass" im RGB 
Würfel gibt, so dass du 2 Farben miteinander in Beziehung setzen 
könntest. Ist RGB(255,0,0) heller oder dunkler als (0,255,0)? Ist 
RGB(30,30,200) 'grüner' als RGB(40,40,200). Mit Hue, Saturation, 
Lightness hast du bessere Parameter, an denen du drehen kannst.

von npn (Gast)


Lesenswert?

Chefkoch schrieb:
> Was ich bei diesem Themengebiet noch nicht verstanden habe:
>
> Es gibt zwar diverse Farbräume, aber letztlich hat man eine RGB LED. Wo
> ist der Gewinn, wenn ein Farbraum definiert wird, der dann (so wie ich
> das sehe) ohnehin auf das physisch vorhandene RGB umgerechnet werden
> muss. Das eigentliche Problem der Auflösung bleibt doch?

Klar wird letzendes nur jede einzelne Farbe rot, grün und blau 
verändert. Aber du willst ja z.B. bei gleichbleibender Helligkeit den 
Farbton ändern, oder auch bei gleicher Farbe die Gesamthelligkeit (so 
wie hier gewünscht), oder bei gleicher Helligkeit und gleicher Farbe nur 
die Sättigung ändern. Und das geht eben, wenn man das entsprechende 
Farbmodell nimmt, dort den einen Parameter ändert, den man ändern möchte 
und dann nach RGB umrechnet, damit sich die entsprechenden Werte für die 
RGB-LED ergeben.

von FelixW (Gast)


Lesenswert?

Chefkoch schrieb:
> ohnehin auf das physisch vorhandene RGB umgerechnet werden

RGB ist nicht physisch, das kann keiner sehen, sind nur Faktoren.
Licht macht erst die (drei) LEDs, und die haben ein Spektrum, was sich 
überlagert.

Schau mal unter: 
http://de.wikipedia.org/wiki/RGB-Farbraum#.C3.9Cbliche_RGB-Farbr.C3.A4ume

2 Räume die du kennst: Frequenz- und Zeitbereich. Unter gewissen 
Annahmen kann ich Umwandeln und meine Aufgabe leichter lösen und wenn 
nötig wieder zurücktransformieren.

Grüße Felix

von Joachim B. (jar)


Lesenswert?

Chefkoch schrieb:
> Was ich bei diesem Themengebiet noch nicht verstanden habe:
>
> Es gibt zwar diverse Farbräume,

nehmen wir an max weiss, R=255 G=255 B=255

wie willst du das in Richtung rot verschieben wenn es dir zu "blau" ist?

mehr Rot als 255 geht nicht

oder Grün, sagen wir Rot=0 Blau=0

willst du den Grünton ändern kannst du nur Rot oder Blau hinzugeben was 
sofort die Helligkeit erhöht, du willst aber die Helligkeit beibehalten?

Dazu kommt noch die Kennlinie der Augen deswegen LED Fading.

von Alex (Gast)


Lesenswert?

Karl Heinz schrieb:
> Dimmen bedeutet also: V variieren, wenn man von der Farbe in Richtung
> schwarz dimmen will.
> Will man in Richtung weiß variieren, müsste man S auch noch mit dazu
> nehmen.

Das ist doch schon was.

Ich denke, in "Richtung weiß" dimmen, also die Lampe heller stellen, ist 
unnötig.

Ich stell mir das so vor dass ich eine Farbe einstelle (z.B. per 
Fernbedienung, aber das ist ne andere Baustelle).
Diese Einstellung ist natürlich im ungedimmten Modus.

Im laufenden Betrieb soll dann eben bei Dämmerlicht die Lampge dunkler 
werden ohne die Farbe großartig zu ändern.
D.h. es läuft wohl nur auf ein Absenken des V-Wertes hinaus (= 
verdunkeln).

Ok, das wäre schonmal das grobe vorgehen.
Nun wäre interessant wie die Rechnung dazu aussieht.

Gehen wir von einem 8-Bit V-Wert und einem 8-Bit ADC-Wert der Photodiode 
aus.
Dann bedeutet die 0 eben 0% und 255 bedeutet 100%.

100% ADC-Wert bedeuten, kein abdunkeln notwendig.
50% ADC-Wert (also 128) bedeutet: "schalte die Lampge nur noch halb so 
hell".

Wenn mein V-Wert bspw. 176 beträgt müsste ich einfach nur durch 2 teilen 
und erhalte 88 als neuen V-Wert. Danach eben die Rückwandlung nach RGB 
zur Ausgabe via PWM.
Ist das wirklich so einfach?


Danke euch!

von Alex (Gast)


Lesenswert?

Joachim B. schrieb:
> Dazu kommt noch die Kennlinie der Augen deswegen LED Fading.

Das wurde bereits berücksichtigt.
Ich habe 8-Bit RGB Werte, meine PWM hat aber 12 Bit Auflösung.
D.h. ich mappe meine RGB-Werte via logarithmischer LookUp Tabelle auf 
die eigentlichen PWM-Werte.

Deine anderen beiden Einwände gehen denke ich mal nicht gegen mich, denn 
ich will ja nur dimmen, nich aber ein grün grüner oder ein weiß roter 
machen.

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:

> Wenn mein V-Wert bspw. 176 beträgt müsste ich einfach nur durch 2 teilen
> und erhalte 88 als neuen V-Wert. Danach eben die Rückwandlung nach RGB
> zur Ausgabe via PWM.
> Ist das wirklich so einfach?

Im Prinzip: ja

Deine Beschreibung klingt jetzt allerdings nicht wirklich danach, als ob 
die wahnsinnig farbtreu bleiben muss oder als ob Helligkeitslevel auf 
Prozentpunkte genau einzuhalten sind. Im ersten ansatz würde ich einfach
1
struct rgb
2
{
3
  uint8_t red;
4
  uint8_t grn;
5
  uint8_t blu;
6
};
7
8
struct rgb rgbFull;
9
10
struct rgb dimmTo( struct rgb* color, uint8_t level )
11
{
12
  struct rgb dimmed;
13
14
  dimmed.red = color->red * level / 255;
15
  dimmed.grn = color->grn * level / 255;
16
  dimmed.blu = color->blu * level / 255;
17
18
  return dimmed;
19
}

gehen und mir ansehen, ob das konviniert.
Wenn nicht: Über HLS kann ich immer noch gehen. Ist ja nur Software.
Aber erst mal nachsehen, ob die einfachste Lösung nicht auch genügt.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Alex schrieb:
> Deine anderen beiden Einwände gehen denke ich mal nicht gegen mich, denn
> ich will ja nur dimmen, nich aber ein grün grüner oder ein weiß roter
> machen.

ne meine Einwände gehen gegen keinen, nur dimmen bedeutet für mich 
Helligkeitsänderung möglichst linear fürs Auge ohne Farbverschiebung.

von Alex (Gast)


Lesenswert?

Karl Heinz schrieb:
> Im ersten ansatz würde ich einfach...

Danke, das werd ich mal probieren, vielleicht reichts ja so wirklich, 
das kann ich grad nicht einschätzen.
Eine Gegenüberstellung beider Methoden wär interessant, inwieweit das 
Ergebnis abweicht. Vielleicht bastel ich mir da mal was.


Noch eine weitere Frage mit ähnlicher Thematik:

Angenommen, ich habe zwei Farben, meinetwegen ein Lila und ein Gelb.

Nun möchte ich gerne einen weichen Wechsel zwischen diesen beiden Farben 
realisieren, anstatt "hart" umzuschalten.

Hier reicht es ja wohl nicht, nur an H zu drehen da ja die anderen 
Parameter auch unterschiedlich sein könnten. Wie würde man sowas 
realisieren?

von Chefkoch (Gast)


Lesenswert?

Das mit den tatsächlich zur Verfügung stehenden 12Bit ist natürlich eine 
wichtige Information.

Ich 'vermute' , dass du dich von der Idee "8Bit/Farbe + 4Bit Helligkeit" 
lösen musst. Ich glaube, du brauchst einen Algorithmus, der die 
Argumente des HSV in diese 12Bit RGB wandelt. Ein Argument währe dann 
der Wert des Helligkeitssensors.

Die Implementierung des Algos wird sicher von deinen 12Bit abhängen und 
den 8Bit des Sensors.

Es ist nicht zufällig so, dass du einen AVR auf 16Mhz laufen hast und 
12Bit Software PWM erzeugst? ;->

von Konrad S. (maybee)


Lesenswert?

H, S und V linear interpolieren.

Oder V auf 0 dimmen, dann H und S ändern, dann V aufdimmen.

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:

> Hier reicht es ja wohl nicht, nur an H zu drehen da ja die anderen
> Parameter auch unterschiedlich sein könnten. Wie würde man sowas
> realisieren?

In HLS ist auch das wieder einfach:
Von H_quelle nach H_Ziel interpoloeren.
GLeichzeitig von L_quelle nach L_Ziel interpolieren
Gleichzeitig von S_quelle nach S_Ziel interpolieren


Aber wenn an die Zwischenstufen nicht allzuhohe Ansprüche gestellt 
werden:
1
// blendFactor:  0 ... 128 (to avoid arithmetiv Overflow during arithmetic)
2
//
3
//     0      'source' color
4
//   128      'dest' color
5
//   values inbetween blend source to destination
6
//
7
struct rgb( struct rgb* source, struct rgb* dest, uint8_t blendFactor )
8
{
9
  struct rgb color;
10
11
  color.red = ( dest->red * blendFactor + source->red * ( 128 - blendFactor ) ) / 128;
12
  color.grn = ( dest->grn * blendFactor + source->grn * ( 128 - blendFactor ) ) / 128;
13
  color.blu = ( dest->blu * blendFactor + source->blu * ( 128 - blendFactor ) ) / 128;
14
15
  return color;
16
}


Schliesslich kann sowieso keiner exakt sagen, welche 'Farben' die 
Zwischenstufen sein sollten, wenn von braun nach magenta gefadet werden 
soll.

: Bearbeitet durch User
von Martin S. (led_martin)


Lesenswert?

Die ganze Farbraum-Trickserei bringt nichts, wenn die Farbveränderung 
durch Rundung auf die 8 Bit Werte, die letztendlich doch als RGB 
ausgegeben werden müssen, entsteht. Da ist ein einfacher Faktor nicht 
schlechter, aber auch nicht besser. Will man, in weiten Bereichen, 
dimmen, macht eine Erhöhung der Ausgabe-Bitbreite Sinn, z.B. 10 Bit PWM 
statt 8 Bit. Das ist eine Verbesserung, die man sofort sieht.

Mit freundlichen Grüßen - Martin

von Alex (Gast)


Lesenswert?

Ja, ich hab eh einen Denkfehler drinnen.

Ich hab ja eine 12 Bit PWM zur Verfügung (genauer, BCM).
D.h. ich könnte ja sowohl meine RGB als auch meine HSV/HLS Werte als 16 
Bit Wert (mit eben 12 genutzen Bit) abspeichern und auch so ausgeben.

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.