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
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?
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
Karl Heinz schrieb: > nehmen. Im HSL Farraum geht das einfacher. Da wird immer nur L variiert. Tschuldigung HLS. Nicht HSL
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.
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?
Karl Heinz schrieb: > Tschuldigung > HLS. Nicht HSL Warum Entschuldigung? HSL war schon richtig (hue-saturation-lightness).
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.
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.
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
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.
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!
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.
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
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.
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?
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? ;->
H, S und V linear interpolieren. Oder V auf 0 dimmen, dann H und S ändern, dann V aufdimmen.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.