[Gelöst] FASTLED: Geänderte LEDs ws2812b stripes langsam ein und ausschalten

Hallo zusammen. Ich scheitere grad ziemlich hart an FastLED und könnte da ein wenig hilfe gebrauchen.

Kontext: mein projekt soll mit nem ws2812b Streifen die Zeit anzeigen. Das klappt eigentlich auch ganz gut.

Ich versuch hier mal meinen Istzustand zu skizzieren mit ein wenig pseudo code. das Git repo poste ich am Ende, wen es genauer interessiert/bereit ist, da mal reinzutauchen.

loop {
   timetostripe()
   // durch das delay wird implizit FastLED.show() mit aufgerufen
   // => bei jedem loop wird der LED Streifen refreshed
   FastLED.delay(50)
}
void timetostripe(){
  // setzt alle LEDs auf schwarz/aus
  wipeAllLEDs();
  
  // hier wird jetzt anhaengig von der uhrzeit einzelne LEDs auf eine fixe farbe gesetzt
  // led 1-3
  if(hour=1) { wordtostripe(1,4) }
  // led 120-124
  if(minute=25) { wordtostripe(120,5) }
}
void wordtostripe(int anfang, int lenght) {
  for (int letter = 0; letter < lenght; letter++)
  {
      this->leds[word[letter]] = CRGB::red;
  }
}

soweit der "IST stand".

Das funktioniert schon erstmal ganz gut. Jetzt sind die übergänge aber hart. Jedes mal wenn sich eine Stunde/minute ändert, wird ja der complette Stripe neu aufgebaut und per FastLED.delay() einfach eingeschaltet => von einem moment auf den anderen ist da ein neues wort da bzw ein nicht mehr aktives weg. und diese übergnänge würde ich gerne "smooth" gestalten.

Kann mir da wer (gerne auch auf pseudocode ebene) weiterhelfen?

Und hier wie gesagt wer mal tiefer reinschauen mag (da ist noch deutlich mehr code fuer diverse andere funktionen wie OTA, ntp, telnet etc pp vorhanden), hier der link fuer GITHUB. Und mir ist klar dass da noch deutlich andere baustellen offen sind :wink: (bau das ganze grad von statischen funktionen in einen Objektorientierten ansatz um etc)

Mach mal ein paar Versuche mit setBrightness.

Gruß Tommy

Hallo ihr beiden.

setBrightness() dimmt das komplett array herunter. das hilft mir also nicht weiter, da ja nur die geänderten Worte ein/ausgeblenet werden sollen.
Da fehlt mir also die entsprechende FastLED technik, um das fuer definierte Elemente des Arrays zu machen.

noiasca:
dimme das alte Wort in Stufen runter
dimme das neue Wort in Stufen hoch
Lege fest, in wie vielen Stufen dies geschehen soll.

Ja, das ist genau das was ich erreichen will :smiley: Ich zerlege mein problem also konkreter in 2 Probleme:

  1. wie einzelne LEDs hoch/runter dimmen
  2. wie kriegt die Methode wordtostripeeigentlich mit, was alt und was neu ist? aktuell wird ja einfach alles resettet und dann ist alles neu. So werde ich das also nicht mehr machen können?

Ist hier vielleicht 2 array nötig, in dem ich VOR dem reset (wipeAllLEDs():wink: das leds array und nachdem alle einzelnen worte wieder in das array gepushed wurden, ich schaue, wo ist jetzt black statt irgendeiner farbe drin (= ausgeschaltet) bzw wo ist jetzt ne farbe statt black (= eingeschaltet) und die dann schrittweise mit nem anderen brightnesswert (siehe problem 1 :smiley: ) versehe?
Oder geht das einfacher?

Du weißt ja welche Zeit Du als letzes ausgegeben hast und damit die Einzelworte.
Bei der neuen Zeit schaust Du dann, welche Worte sich geändert haben und deren LEDs bearbeitest Du.

setBrightness setzt den internen Wert m_scale. Da nusst Du dann schauen, was bei show damit gemacht wird und Dir daraus dann eine eigene Funktion schreiben, die das für eine einzelne LED macht.
Mit der kannst Du dann die betroffenen LEDs dimmen.

Gruß Tommy

noiasca:
da arbeitest vermutlich irgend ein array durch. Ich tu mir da dein Monster nicht an.

grinst versteh ich

und bisher hab ich da 0 smartness drin:
einfach alles ausschalten und nur die relevanten wieder neu einschalten durch ein

this->leds[lednumber] = "0xFF0000";

Was ich aber deiner Antwort schonmal entnehmen kann: bei den farben mit hexwerten arbeiten ist ggf ungeschickt, wenn brightness ins spiel kommt?

Und noch ne inspiration, wie man dieses reset und einfach neu ins array schreiben etwas schlauer gestalten könnte?

Edit: @Tommy56 hmm jo sowas in die richtung hab ich schon befürchtet. mal sehn ob ich das irgendwie halbwegs effizient hin bekomme :wink:

@dakky: Einen Hinweis noch - Fastled hat im Array den originalen Farbwert und nimmt m_scale nur zum Ansteuern der LEDs bei show. Du wirst Dir also auch den Originalwert merken müssen.

Gruß Tommy

hmmm tricky irgendwie ... hilft da vielleicht das konzept der paletten bei FASTLed weiter? wenn ich mir die examples so anschaue, sind die ja doch eher recht einfach, aber in der wirkung viel eindrucksvoller :smiley:

Nicht dass ich hier mit meinem manuellen gefummel auf dem holzweg bin?

Was ich da auf GiHub sehe, kann ich nicht probieren, da ich keinen ESP8266 habe und die Fragmente in #0 sind nicht aussagekräftig genug. Ein kleines, kompilierfähiges Testprogramm könnte eventuell Hilfe wahrscheinlicher machen :slight_smile:

agmue:
Was ich da auf GiHub sehe, kann ich nicht probieren, da ich keinen ESP8266 habe und die Fragmente in #0 sind nicht aussagekräftig genug. Ein kleines, kompilierfähiges Testprogramm könnte eventuell Hilfe wahrscheinlicher machen :slight_smile:

Da hast du wohl recht. Es ist halt manchmal schwierig, das szenario soweit einzustampfen, dass es noch "wie im orginal falsch" geht :smiley: die basic samples klappen ja meist.

Aber zum Thema: ich habs hinbekommen: der Weg mit den Brightness direkt setzen war in die falsche Richtung gedacht.
FastLED kann auch dimmen von farbe zu farbe. Ich dimme jetzt einfach von farbe => schwarz und umgekehrt.

Zur smartness: ich hab das jetzt so gelöst:
1 LED Array mit den "wunschLEDs", die leuchten sollen (target)
1 LED Array mit dem IST zustand, die jetzt bereits leuchten (live)

wenn die arrays unterschiedlich sind (stichwort memcmp) dann iteriere ich über das target array und wenn das jeweilig pixel sich unterscheidet, dann subtrahiere (dunkler) bzw addiere (heller) ich jeweils einen fixen Wert von den 3 RGB values und setze den wert im live array. So nähert sich das live array mit jedem loop den target array näher an, bis sie irgendwann gleich sind => dimmen abgeschlossen.

bin recht zufrieden mit dem erbgebnis. Ist warscheinlich speicher und speedtechnisch nicht das optimum. aber ein ESP sollte dafuer genug power haben.

Danke euch

Wer zu spät kommt ...

Die Bibliothek hat tatsächlich eine große Anzahl Möglichkeiten, da ist es nicht so einfach, den optimalen Weg zu finden. Ohne diesen Anspruch bin ich auf eine Lösung gestoßen, die den Helligkeitswert aus ColorFromPalette verwendet. Dazu passen dann die mathematischen Funktionen wie dim8_lin.

Möglicherweise kann es ja irgendjemand verwenden:

#include<FastLED.h>

#define LED_TYPE    APA102
#define COLOR_ORDER BGR
#define NUM_LEDS    122

CRGB leds[NUM_LEDS];                                   // Initialize our LED array.

// Palette definitions
CRGBPalette16 currentPalette  = CRGBPalette16(CRGB::White);

void setup() {
  LEDS.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS);
} // setup()

void loop() {
  static byte schritt = 0;
  EVERY_N_MILLISECONDS(1) {
    switch (schritt) {
      case 0:
        if (ein(5, 10)) schritt++;
        break;
      case 1:
        delay(500);
        schritt++;
        break;
      case 2:
        if (aus(5, 10)) schritt++;
        break;
      default:
        delay(500);
        schritt=0;
        break;
    }
    FastLED.show();
  }
} // loop()



bool ein(uint16_t startLed, uint16_t anzahl) {
  static byte fader = 0;
  for (uint16_t i = 0; i < anzahl; i++) {
    leds[startLed + i] = ColorFromPalette(currentPalette, 0, dim8_lin(fader));
  }
  if (fader < 255) {
    fader++;
    return false;
  } else {
    fader = 0;
    return true;
  }
} // fadein()

bool aus(uint16_t startLed, uint16_t anzahl) {
  static byte fader = 255;
  for (uint16_t i = 0; i < anzahl; i++) {
    leds[startLed + i] = ColorFromPalette(currentPalette, 0, dim8_lin(fader));
  }
  if (fader > 0) {
    fader--;
    return false;
  } else {
    fader = 255;
    return true;
  }
} // fadein()

uhhh das ist auch ne schöne methode ..... mal überdenken :smiley:

Man kann auch den HSV-Farbraum "mißbrauchen", das bietet die Bibliothek ja auch an. Der Farbwert geht dann bis 255 anstelle 360°, was in diesem Fall aber nicht wichtig ist.

Netter Nebeneffekt bei HSV - der Farbverlauf zwischen den zwei Farbpunkter (Linie im Farbraum) ist ein sanfter Übergang zwischen den zwei Farbpunkten.