Farbgenauigkeit bei WS2812B stimmt nicht. ( Titel angepasst )

Da müsste man als erste Frage stellen: Ist der Monitor in der Farbdarstellung kalibriert?
Denn auch Monitore streuen in der Farbdarstellung erheblich, sogar im gleichen Modell.

Gruß Tommy

Um zu testen, ob tatsächlich "16,7 Millionen" Farben (24 bit) unterstützt werden (und nicht zB 16 bit mit 5+6+5 bit für RGB) musst du im dunkleren Bereich testen.
Am besten einen kleinen Unterschied (z.B. 0x403C00 und 0x3C4000) auf zwei Teile der Pixel verteilen und die Grenze wandern lassen. Wie sehr muss der 24bit Farbwert geändert werden, dass du überhaupt einen Unterschied und dessen Bewegung siehst?

Kann übrigens auch sein, dass du Unterschiede siehst wo gar keine sein sollten, nicht erst nach langem Hinsehen.

Dass du an RGB LED nicht so hohe Ansprüche wie bei deinem Monitor stellen solltest und auch Monitore ihre Grenzen haben, wurde ja schon erörtert.

SK 9822 LED Strips haben einen Controller, der per Takt (CI) und Daten (DI) vergleichbar SPI (ohne CS) angesteuert wird. Dadurch sind höhere Taktraten und damit schnellere Animationen möglich. Die Anzahl der darstellbaren Farben und der Farbraum ändern sich aber grundsätzlich nicht.

Das Weiß nehme ich Dir nicht ab, aber es ist nicht die gewünschte Farbe. Dann ist möglicherweise die Reihenfolge der Farben herstellerbedingt vertauscht.

Färbe das erste Pixel Rot, das zweite Grün und das dritte Blau. Stimmen die Farben? Wenn nicht ändere mal "RGB" in "GRB" oder eine andere Kombination, bis es stimmt. Dann siehst Du auch sowas wie LavenderBlush, wobei die Abweichungen zwischen Monitor und LEDs schon nicht so klein sind.

FastLED.addLeds<WS2812, PIN, RGB>

FastLED bietet auch noch Farbkorrekturen an

FastLED.addLeds<CHIPSET1, LED1_PIN, COLOR_ORDER1>(leds1, NUM_LEDS1).setCorrection(TypicalLEDStrip);

Warum nimmst Du mir das nicht ab?
Augenscheinlich wirkt diese Farbe wie Weiß.
Es wurde hier ja auch schon erwähnt, dass es eher nur Messbar ist, dass es sich um zwei Farben handelt.

Zum Thema RGB oder GRB muss ich sagen, dass passt schon. Die LEDs werden GRB angesteuert und liefern auch die richtigen Farben. Rot bei FF0000, Grün bei 00FF00 und Blau bei 0000FF.

BTW, ich nutze NeoPixel und nicht FastLED.
Ich hatte nur geschrieben, dass ich FastLED Farbdefinitionen gefunden habe, nicht das ich FastLED nutze.

Fertige Farbdaten haben ich gesucht um mir eine Klasse dafür zu schreiben.
Das ist in meiner IDE dann einfacher, die Farben mit color.red() zu nutzen als mit FF0000.

Einfacher im Sinne von Lesbarkeit.
farbe.rot ist aussagekräftiger als FF0000.
Und wenn ich dann Braun haben möchte, muss ich nicht erst den Farbcode suchen, sondern nur farbe.braun() eingeben.

Beispiel:

class Color {
uint32_t red() { return 0xFF0000 };
};

Color farbe;

strip.SetPixelColor(1, farbe.rot());

Die Farbcodes musst du halt selber abstimmen. Oft ist der Blauanteil zu hoch/zu intensiv.
Braun ist sowieso ein spezielles Thema.
Für Farben hätten es Konstanten oder eine (scoped) Enumeration vermutlich auch getan.

Die gängigen Bibliotheken können und versuchen über eine „Gammakorrektur“ die linearen Werte dem Menschlichen Auge anzupassen.

Natürlich hilft das nicht gegen Ungenauigkeiten in der Produktion.
Man könnte natürlich die Gammakorrektur in der Bibliothek anpassen. Das ist aber nicht so trivial.

Das nehme ich Dir sofort ab, ich wollte Dich nicht angreifen :slightly_smiling_face:

Es besteht nur ein Unterschied zwischen dem persönlichen Eindruck und der Realität, das wollte ich unterscheiden helfen. Siehst Du zwischen 0xFFF0F5 und 0xFFFFFF keinen Unterschied, liegt irgendwo ein Defekt vor, möglicherweise auch bei Deinem Auge. Wir sehen alle ein wenig unterschiedlich, da gibt es keine Objektivität, nur eine statistische Übereinstimmung.

Super, dann kann man die Farbreihenfolge als Fehlerquelle ausschließen.

Ein Unterschied zwischen Bildschirm- und LED-Farbe überrascht mich nicht, da mußt Du einen für Dich praktikablen Weg finden, fürchte ich.

Angegriffen fühle ich mich keineswegs.

Danke an Alle für die erneute Erleuchtung :blush:

Mach mal ein LED FFFFFF und das nächste FFF0F5 und dann machst Du ein Foto zB mit einem Händy. Da siehst Du dann einen Unterschied.
Grüße Uwe

oder lege einfach ein weisses Blatt papier auf die LEDs und betrachte die durchscheinende Farbe

Deine Klasse sieht irgendwie komisch für mich aus (abgesehen davon, dass du rot und red mischst), aber warum nicht eine Enum (class), bei der du die Werte selbst festlegst? Also wie folgt:

enum class Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};

Color color;
boolean done = false;

void setup() {
  Serial.begin(57600);
  delay(1000);
}

void loop() {
  if (!done) {
    color = Color::red;
    // line below not compiles because color is of type uint_32, which Serial.println does not accept
//    Serial.println(color);    
    // does compile, but makes no sense
    Serial.println((unsigned int) color);     // prints 0 due to cast
    color = Color::green;
    Serial.println((unsigned int) color);     // after cast: 0xFF00 = 65280
    color = Color::blue;
    Serial.println((unsigned int) color);     // after cast: 0x00FF = 255
    done = true;    
  }
}

In loop() wird natürlich wegen des casts für red Blödsinn ausgeben - ich habe das gemacht, um meinen Vorschlag testen zu können.

Hi,

das mit red und rot war nur ein Tippfehler.
Ob über enum class oder als class, finde ich, wenn es ums Ergebnis geht, gleichwertig.
Wobei ich die Lösung über enum class schöner finde.

color::red sieht auch besser aus als color.red().
Ist vielleicht auch von ungeschriebenen Coding-Gesetzen so vorgegeben :slight_smile:

Sie hat zudem den Vorteil, dass sich gleiche Aufzählungen verwenden lassen falls der Farbcode (0xnnnnnn) bei unterschiedlichen LEDs unterschiedlich ausfällt. Also, so was hier geht eben nicht:

enum WS2812Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};
enum SK6812Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};

Das gibt dann die Fehlermeldung:

Forum_ColorEnum:2:41: error: redeclaration of 'red'
enum SK6812Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};
                                         ^~~~~~~~

(Für green und blue natürlich äquivalent)

Wohingegen

enum class WS2812Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};
enum class SK6812Color : unsigned long {red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF};

anstandslos funktioniert.

Ist für deine Anwendung wohl eher theoretischer Natur, da der Versuch zwei verschiedene LED-Typen farblich identisch abzustimmen in der Praxis höchstwahrscheinlich kläglich scheitern wird.

... zumal WS2812Color::red eine andere Konstante als SK6812::red ist. Muss bei Bedarf neu übersetzt werden. Oder noch eine Schicht drumrum erfunden werden.

Ja, richtig; die Werte dürften verschieden sein. Der Code zur Ansteuerung kann aber dann immer der gleich bleiben, da es für beide LED-Typen jeweils, z.B., "red" heisst. Also nur einmal der Code an der Stelle angepasst werden muss, wo die Variable für die Farben deklariert wird: eben entweder vom Typ WKS2812Color oder eben SK6812Color.

Leider nein. Bei class enum heißt der Wert nicht red sondern WKS2812Color::red
Wenn das dein Ziel ist, bist du eventuell mit überladenen Methoden, die je nach Instanz und deren aktueller Klasse einen anderen Wert liefert, doch besser bedient.

Verdammt... ok, die von dir erwähnte Schicht müsste also noch irgendwie hergezaubert werden. Aber das wäre ja ohnehin mehr als der TO eigentlich möchte.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.