LED Farbe von FastLed stimmt nicht

ich nutze FastLed 303 und habe zum testen mal nur eine ws28121 led mit 2811 Controller angeschlossen. Ich verwende einen Arduino mini pro 5v

Aber wenn ich
leds[0] = CRGB::Red;
mache, dann leuchtet die LED grün. und bei
leds[0] = CRGB::Green;
leuchtet sie rot

Manche Farben wie Yellow gehen gar nicht.

Habe auch mal verschiedene LED Typen versucht (WS2812B, WS2812, WS2811) aber immer das gleiche.

Wie löse ich das Problem?

Hier das Programm, eins der Beispiele:

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 1

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5

// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() { 
      // Uncomment/edit one of the following lines for your leds arrangement.
      // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
       FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
 // 	  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
      
      // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);

      // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
      // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
}

void loop() { 
  // Turn the LED on, then pause
  leds[0] = CRGB::Green;
  FastLED.show();
  delay(1000);
  // Now turn the LED off, then pause
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(1000);
}

Läßt sich denn den Grundfarben (Red,Green...) eine eindeutige RGB Farbe zuordnen? Dann sind vielleicht nur die LED Beinchen irgendwo vertauscht.

Wie meinst du das? Wenn sie Rot leuchtet dann ist auch auch rot :slight_smile:
Beinchen sind keine umgebogen, geht auch schlecht bei der ws2812…

Habe nun mal folgendes verändert:
FastLED.addLeds<WS2812, LED_PIN,GRB>(leds, NUM_LEDS);
Anstatt RGB habe ich GRB eingegeben. So lassen sich nun Rot grün und Blau wie vorgesehen anzeigen:
leds[0] = CRGB::Red;

Aber farben wie Yellow und viele andere funktionieren überhaupt nicht. auch nicht über
leds[0] = CRGB(255,255,0);

Ich verstehe das nicht.

Die WS2812 LED im 5 oder 8mm Gehäuße haben eine andere Sequenz der Farbwerte beim übertragen der Werte gegenüber den WS2812 SMD oder WS2811.

Steuere sie Rot an und schaue welche Farbe sie haben und dann grün und blau.

Was bedeutet

Aber farben wie Yellow und viele andere funktionieren überhaupt nicht. auch nicht über

Grüße Uwe

Wie im letzten Beitrag erwähnt, werden die Grundfarben Rot, Grün und Blau jetzt zwar richtig angezeigt.

Nun habe ich verschiedene Farbwerte probiert.

Fuchsia geht nicht aber DeepPink geht. White geht nicht aber Gold geht. usw. usw. Die Werte habe ich von hier: http://fastled.io/docs/3.1/struct_c_r_g_b.html Vor allem Weiß wundert mich...

Alle so angesprochen: leds[0] = CRGB:: Gold;

Wenn Du die Farbreihenfolge Deines Strips innerhalb von FastLED.addLeds sortiert hast, dann teste mal

leds[0] = CRGB( 255, 0, 0);
leds[1] = CRGB( 0, 255, 0);
leds[2] = CRGB( 0, 0, 255);

Die ersten 3 LEDs sollten jetzt nacheinander rot, grün und blau zeigen. Falls nicht, dann die Initialisierung korrigieren. (Falls Du nur eine LED hast, dann nacheinander testen.)

Außerdem: Mit einem Pro Mini unbedingt den letzten Stable Branch verwenden - also Fastled 3.1.

Alle als Keywords vordefinierten Farben findest Du hier ab Zeile 463.

Gruß,

Helmuth

P.S. Falls das (wider erwarten) nicht helfen sollte, dann erkläre mal, was

Fuchsia geht nicht aber DeepPink geht. White geht nicht aber Gold geht. usw. usw.

konkret bedeutet. Compilererror? Oder Ergebnis nicht, wie erwartet? Welches Ergebnis? Was passiert?

P.P.S. Wie sieht Deine Spannungsversorgung des (der?) WS2812 aus? Kann es sein, dass Dir einfach die Spannung einbricht, wenn Du mehrere Farben mit voller Helligkeit fährst (z.B. Yellow (R+G) oder White (R+G+B))?

Danke für die vielen hilfreichen Informationen. Leider komme ich erst nächste woche dazu dies zu testen.

Geht nicht bedeutet, die Farbe wird einfach nicht angezeigt. Könnte vlt. tatsächlich an der Spannungsversorgung liegen, da ich volle helligkeit eingestellt habe. Das soll für eine einfache Lichtleitfaser um einen Tisch sein... ich gebe bescheid wenn ich es getestet habe.

Kennt jemand Möglichkeiten eine smd ws2812 mit Lichtleitfaser zu verbinden? (Mir ist klar, dafür gäbe es geeignetere LEDs). Habe mir da zwar was ausgedruckt, dass funktioniert auch aber noch nicht perfekt.

Kennt jemand Möglichkeiten eine smd ws2812 mit Lichtleitfaser zu verbinden?

Mit einem transparenten Kunstharz vergießen funktioniert ganz gut.

Könnte vlt. tatsächlich an der Spannungsversorgung liegen, da ich volle helligkeit eingestellt habe.

Wie versorgst Du die LEDs? Wieviele?

Es funktioniert leider immer noch nicht :frowning:

Dies habe ich getestet (umgeschreiben für eine LED), funktioniert einwandfrei.

leds[0] = CRGB( 255, 0, 0);
leds[1] = CRGB( 0, 255, 0);
leds[2] = CRGB( 0, 0, 255);

Außerdem habe ich FastLed3.1 benutzt, hilft aber auch nicht weiter. Und ich nutze nun ein 1A 5V stabilisiertes Netzteil was ausreichen sollte für eine LED.

Habe ein kleines Testprogramm genommen und einfach die LED auf weiß gestellt, dass hat einwandfrei funktioniert! Aber sobald ich vorher oder danach eine andere Farbe anzeige, funktioniert es wieder nicht. Heißt in diesem Beispiel Weiß wird nicht mehr dargestellt.
Ich verstehe es einfach nicht.

Hier der Code:

#include "FastLED.h"
#define NUM_LEDS 1
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
void setup() {
      delay(2000);
      FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
       delay(1000);
//      leds[0] = CRGB::Black;
      leds[0] = CRGB::White;      
      FastLED.show();      
      delay(1000);
//      leds[0] = CRGB::Black;
      leds[0] = CRGB::OrangeRed;      
      FastLED.show();      
      delay(1000);
}

Bei dieser Version blinkt die weiße LED ganz kurz und danach ist nur noch das Orange am Blinken und von weiß ist nichts mehr zu sehen. Auch wenn ich die auskommentierten Zeilen einfüge.

#include "FastLED.h"
#define NUM_LEDS 1
#define DATA_PIN 5
CRGB leds[NUM_LEDS];
void setup() {
      delay(2000);
      FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
//      leds[0] = CRGB::Black;
      leds[0] = CRGB::White;      
      FastLED.show();      
}

Diese Version funktioniert! Heißt also Weiß wird angezeigt. Allerdings ist es ganz leicht am Flackern. So als wäre ein delay von ein paar Ms drinn.

Was kann ich noch versuchen??
Sollte es wirklich am Arduino pro mini (5v/16Mhz) liegen? Aber warum?

Edit:
Es liegt wohl an den Delays, denn diese Version funktioniert.

void loop() {
//      leds[0] = CRGB::Black;
//      leds[0] = CRGB::Black;
      leds[0] = CRGB::White;      
      FastLED.show();      
      FastLED.delay(2000);

      leds[0] = CRGB::OrangeRed;      
      FastLED.show();      
      FastLED.delay(1000);

      leds[0] = CRGB::SkyBlue;      
      FastLED.show();      
      FastLED.delay(1000);
      
}

Aber das weiß flackert erkennbar. Und kann ich nun eine normalen Delays mehr nutzen im Code?

Für mein Programm mit der Lichtleitfaser nutze ich einen RotaryEncoder und eine Timer Routine. Scheinbar macht dies auch Probleme. Gibt es alternativen?

Das von Dir beschriebene Verhalten ist ominös. Gnd vom LED Netzteil und vom Arduino hast Du verbunden, oder?!

Für mein Programm mit der Lichtleitfaser nutze ich einen RotaryEncoder und eine Timer Routine. Scheinbar macht dies auch Probleme. Gibt es alternativen?

Wenn Du den Encoder ohne Interruptbenutzung lesen kannst geht es, ansonsten nicht. Die WS2811 haben so geringe Timingtoleranzen, dass es für eine ISR nicht reicht. Und den Timer braucht FastLED auch...

Alternative: LED Controller mit Clockline.

Sollte es wirklich am Arduino pro mini (5v/16Mhz) liegen? Aber warum?

Nee, der passt.

Und kann ich nun eine normalen Delays mehr nutzen im Code?

Kein Problem, Du kannst normale delays benutzen. Der Unterschied von FastLED.delay und delay ist nur der, dass bei ersterem das Temporal Dithering weiterläuft.

Schreibe mal

FastLED.setDither( 0 );

in den Setup Part und berichte, ob weiß immer noch flackert.

Ich verstehe es einfach nicht.

Ich gebe zu: ich momentan auch nicht. Wie ich schon sagte: Das von Dir beschriebene Verhalten ist ominös.

Poste das Problem mit dem weiß/orange Wechsel mal bitte auf https://plus.google.com/communities/109127054924227823508, danke!

Ah, mir ist was eingefallen:

void loop() {
//      leds[0] = CRGB::Black;
      leds[0] = CRGB::White;     
      FastLED.show();     
}

Das flackert, weil Du eine LED mit >400 fps neu schreibst und da verschlucken die WS2811 sich, weil das schneller als ihre eigene PWM Frequenz ist!

Nimm da noch ein delay rein und das Flackern sollte weg sein.

Wenn FastLED.delay funktioniert und delay nicht (ominös ;-) dann nimm halt erstmal das FastLED.delay - ist ja für den Programmablauf egal.

Danke für die viele Hilfe!
Auf G+ kann ich nicht posten da ich kein G+ habe und das alles in Englisch schreiben, macht es nur noch komplizierter.

Leider ist mein gespeichertes Draft dieses Beitrages nicht auffindbar, wie bekommt man das wieder her?

GND ist alles verbunden.
Das kleine Testprogramm läuft einwandfrei:

#include "FastLED.h"
#define NUM_LEDS 1
#define DATA_PIN 5
#define serialRate 115200

CRGB leds[NUM_LEDS];
void setup() {
      delay(2000);
      FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);
      FastLED.setBrightness(255);         
      //FastLED.setDither( 0 );      
}

void loop() {
      leds[0] = CRGB::White;      
      FastLED.show();      
      FastLED.delay(5000);

      leds[0] = CRGB::Red;      
      FastLED.show();      
      FastLED.delay(5000);      
      
      leds[0] = CRGB::Green;      
      FastLED.show();      
      FastLED.delay(5000);      

      leds[0] = CRGB::Blue;      
      FastLED.show();      
      FastLED.delay(5000);      
      
}

Nun wollte ich das in meinen eigentlichen Code übernehmen aber das gibt schon wieder Probleme.
Habe nun extra keine library verwendet für den Decoder sondern eine einfach routine:

#include <FastLED.h>

#define LED_PIN     5
#define CHIPSET     WS2811
#define NUM_LEDS    1

#define BRIGHTNESS  63
#define FRAMES_PER_SECOND 60

#define DT 2
#define CLK 3
#define SW 4

CRGB leds[NUM_LEDS];

int sensorPin = 0;
int sensorValue = 0;


void setup() { 
  FastLED.delay(2000);
  Serial.begin(9600);
  FastLED.addLeds<WS2811, LED_PIN,GRB>(leds, NUM_LEDS);
  FastLED.setDither( 0 );
  //RotaryEncoder
  pinMode(DT, INPUT);   
  pinMode(CLK, INPUT); 
  pinMode(SW, INPUT); 
  digitalWrite(SW, HIGH);
}

void loop()
{
 int counter;
 byte DialPos;
 byte Last_DialPos;
 
 /* Reset the counter */
 counter = 0;
 
  /* Continiouously read the state of the encoder */
  while(1)
  {
    /* Read the status of the dial */
    DialPos = (digitalRead(CLK) << 1) | digitalRead(DT);
 
    /* Is the dial being turned anti-clockwise? */
    if (DialPos == 3 && Last_DialPos == 1)
    {
      counter--;
    }
 
    /* Is the dial being turned clockwise? */
    if (DialPos == 3 && Last_DialPos == 2)
    {
      counter++;
    }
 
    /* Output the counter to the serial port */
    Serial.println(counter);

    /* Is the switch pressed? */
    if(!digitalRead(SW)){
      Serial.println("Switch pressed!");
      counter = 0;
    }

// if (Last_DialPos !=DialPos)  {    
    
     if (counter == 0) {
      leds[0] = CRGB::Green; 
       FastLED.show();  
    }
    if (counter == 1) {
      leds[0] = CRGB::White; 
       FastLED.show();  
    }
    if (counter == 2) {
      leds[0] = CRGB::Red; 
       FastLED.show();  
    }
    if (counter == 3) {
      leds[0] = CRGB::Yellow; 
       FastLED.show();  
    }
// }    
    /* Save the state of the encoder */
    Last_DialPos = DialPos;
  }
}

Das obige funktioniert einwandfrei. Die LED Flackert aber das ist klar es wird ständig neu aufgerufen.
Also wollte ich folgende Zeile (Ist oben im code auskommentiert zu sehen) einbauen damit nur neu aufgerufen wird wenn sich die stellung des encoders ändert: if (Last_DialPos !=DialPos) {

Aber dann besteht wieder das alte Problem. Einige Farben werden nicht angezeigt, die LED bleibt dunkel :frowning:
Hätte nicht gedacht das so etwas einfaches wie eine LED anzusteuern so kompliziert werden kann :frowning:

Woran liegt es denn nun?

ich habe es mal auf g+ versucht. das erst mal in meinem Leben einen google account :o
Vielleicht versteht jemand mein versuchtes englisch :slight_smile:

Aber vielleicht findet sich auch hier noch jemand.
Ich denke, es liegt an etwas grundsätzlichem was ich übersehe…
Eigentlich will ich doch nur bei einer ws2812 LED mit einem Rotary encoder ky-040 die Farbe wechseln. Das war es auch schon…

Ich verstehe folgendes nicht:
Eigentlich gehe ich davon aus, wenn ich
leds[0] = CRGB::White;
FastLED.show();
schreibe, dass die LED dann leuchtet auch wenn diese 2 zeilen nicht mehr aufgerufen werden. Siehe folgendes Beispiel:

#include <FastLED.h>

#define LED_PIN     5
#define CHIPSET     WS2811
#define NUM_LEDS    1

#define BRIGHTNESS  63


CRGB leds[NUM_LEDS];
int counter;
 
void setup() { 
  FastLED.delay(2000);
  Serial.begin(9600);
  FastLED.addLeds<WS2811, LED_PIN,GRB>(leds, NUM_LEDS);
  FastLED.setDither( 0 );
 /* Reset the counter */
 counter = 0;  
}

void loop()
{
  if (counter == 0) {
    leds[0] = CRGB::White; 
    FastLED.show(); 
    counter = 1;
  }  
}

Aber anstatt dauerhaft zu leuchten, blitzt die LED nur kurz auf und bleibt dann dunkel.
Warum muss FastLED.show(); im loop ständig wieder ausgeführt werden damit die led leuchtet?

Warum muss FastLED.show(); im loop ständig wieder ausgeführt werden damit die led leuchtet?

Das ist nur bei Dir so...

Nach FastLED.show leuchten die LEDs normalerweise genau so weiter, wie es im leds CRGB zuletzt drin stand.

Eigentlich gehe ich davon aus, wenn ich leds[0] = CRGB::White; FastLED.show(); schreibe, dass die LED dann leuchtet auch wenn diese 2 zeilen nicht mehr aufgerufen werden.

Diese Annahme ist korrekt.

Aber warum ist das bei mir so? Ich habe doch nun eine einfache primitive Routine versucht. Also am Code kann es nicht liegen.

Sicher das es nur bei mir so ist? denn bei den FastLED Basics steht folgender Code:

    void loop() { 
        leds[0] = CRGB::Red; 
        FastLED.show(); 
        delay(30); 
    }

Auch hier wird show im loop ständig wieder aufgerufen. Warum sollte das sein wenn die LED weiter leuchtet?

Auch hier wird show im loop ständig wieder aufgerufen. Warum sollte das sein wenn die LED weiter leuchtet?

Das Thema hatten wir doch schon: Weil der Loop u.U. so schnell durchlaufen wird, dass mistige Chipsets wie z.B. WS2811/12 die LEDs unkontrolliert flackern lassen, weil die Updatefrequenz höher ist, als die PWM Frequenz, wenn man keine Bremse einbaut.

P.S. Die LEDs behalten immer den letzten Zustand - selbst, wenn man die Arduinoverbindung trennt.

das hast du falsch verstanden…
Ich schrieb:

Warum muss FastLED.show(); im loop ständig wieder ausgeführt werden damit die led leuchtet?

Deine Antwort darauf war:

Helmuth:
Das ist nur bei Dir so…

Nach FastLED.show leuchten die LEDs normalerweise genau so weiter, wie es im leds CRGB zuletzt drin stand.

Diese Annahme ist korrekt.

Mein letzter Beitrag war dann die Frage warum sogar bei dem Basics Beispiel von fastled das show im Loop drinn ist. Siehe hier:

   void loop() {
        leds[0] = CRGB::Red;
        FastLED.show();
        delay(30);
    }

Nehme ich das show aus dem loop heraus funktioniert es nicht mehr.
Und genau wegen diesem irrtum (show muss nicht im loop sein) gab es am Ende noch probleme bei mir. Erst als ich es wieder in den loop setzte funktioniert nun alles :slight_smile:

Also irgendwie aneinander vorbeigeredet…

Nur um es zu verstehen… Warum muss das show denn nun doch im loop sein, wenn die LED doch eigentlich den letzten Zustand beibehält? Eigentlich müsste das doch nur einmal ausgeführt werden und fertig…

Jedenfalls, vielen Dank für deine Hilfe und Geduld!!! Jetzt funktioniert alles wie es soll.

Da ist vorher noch was anderes.

Edit: Hmm, wenn du das letzte Beispielprogramm von dir meinst, sollte es doch so klappen.

Na fein, dass es jetzt klappt!

Also nochmal Schritt für Schritt: Es gibt ein Array in welchem die Farbwerte für jede LED drinstehen.

Die stehen da erstmal nur drin, mehr nicht.

Mit FastLED.show wird dieses Array an die LEDs gesendet.

Haben die LEDs die Daten erhalten, zeigen sie sofort die entsprechenden Farben an. Solange, bis sie neue Daten bekommen. Wenn sie keine neuen Daten bekommen, leuchten sie in der letzten Farbe weiter.

Wenn Du etwas statisches anzeigen möchtest, reicht ein einziges FastLED.show. (z.B. im Setup Teil)

Wenn Du etwas dynamisches anzeigen möchtest, schreibst Du die neuen Farben zuerst ins Array und DANACH schickst Du die Daten mit FastLED.show zu den LEDs.

Und wie gesagt - mit lahmen Chipsets und wenigen LEDs die fps im Auge behalten.

Ist das jetzt komplett verständlich?

Geduldige Grüße,

Helmuth

P.S. Funktionieren jetzt alle Farben, wie erwartet? Wo lag der Fehler?

P.P.S.

Nur um es zu verstehen.... Warum muss das show denn nun doch im loop sein, wenn die LED doch eigentlich den letzten Zustand beibehält? Eigentlich müsste das doch nur einmal ausgeführt werden und fertig...

Ja, Du kannst z.B.

leds[0] = CRGB::Red;
FastLED.show();

in den Setupteil schreiben und den Loop komplett leerlassen.

Wird genau einmal abgearbeitet und die LED leuchtet danach rot.

1 Like