Fast LED Animationen (for Schleifen) und Webserver

Hallo zusammen,

ich bin dabei, mir einen Webserver zur Steuerung eines LED Streifens zu basteln. So weit so gut.

Ich bin jetzt nur vor dem Problem, dass mir for-Schleifen die ich für die Effekte nutze, mir den Webserver logischer Weise blockieren und dieser nicht wirklich brauchbar ist.

Könnt ihr mir auf die Sprünge helfen, wie ich das in den Griff bekomme.

Geplant sind Farbwechsel, Helligkeitsänderung und Animationsänderungen über das Webinterface im laufenden Betrieb.

Vielen Dank für eure Hilfe!

Gruß

Welche Led-Stripes ?
Welcher Controller ?
Welche Libraries ?

Meist lässt sich das Problem nicht mit einem einzigen Controller lösen.

Der Led Streifen ist ein WS2812B.
Der Controller ist ein ESP8266.

Folgende Libraries habe ich in Verwendung:

<ESP8266WiFi.h>
<WebSocketsServer.h>
<ESP8266WebServer.h>
<ESP8266mDNS.h>
<ArduinoOTA.h>
<FastLED.h>

HotSystems:
Meist lässt sich das Problem nicht mit einem einzigen Controller lösen.

Wie muss ich das verstehen?

Doctor236:
Wie muss ich das verstehen?

Das bedingt durch die Verwendung der Leds und Library eine Änderung der Animation meist nur nach deren Ende möglich ist.
Die Library FastLed schaltet die Interrups aus, womit es sehr schwer wird, die Animation vorzeitig zu unterbrechen.

Ich würde dann einen Controller für die Leds und einen weiteren für die Steuerung verwenden.

Deine Vermutung ist glaube ich falsch, oder wir schreiben aneinander vorbei.
Wenn man die Animationen mit den ColorPallets macht, läuft Webserver und Animationen gut nebeneinander. ich habe es jetzt auf die Schnelle probiert: Webserver mit Websocket gibt serial die RGB Daten aus und gleichzeitig laufen die Animationen.
Ich glaube nicht dass das ein Problem von den Interupts ist, sondern einfach von den for-Schleifen.

Wenn ich jetzt einen Controller nehm für die Animationen ist es doch das gleiche wie jetzt? Die For-Scheife wird alles blockieren und ich bekomme keine Kommunikation zwischen Webserver(ESP) und bspw. einem Micro zustande?!

Ich glaube ich habe meine Frage selber beantwortet: For-Schleifen sind hier einfach nicht angebracht. Oder?

Wie bekomme ich aber ohne for-Schleife z.B. ein Lauflicht zustande?

Ok, evtl. liege ich in meiner Vermutung falsch.
Dann solltest du auch deinen Sketch posten, da sieht man dann mehr.

Eine for-Schleife kannst du auch verlassen, wenn du in dieser mittels einer if-Abfrage rausspringst.

Das mit der If Abfrage ist soweit ja nicht interessant, da dann ja auch meine Animation aufhört.

Mein Code vereinfacht:

void loop()
{
    webSocket.loop();      // liefert die RGB Werte
    server.handleClient();  //Beide zuständig für den Webserver
    animation();
}

void animation()
{
   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
      leds[whiteLed]setRGB( r, g, b);
      FastLED.show();
      delay(100);
      leds[whiteLed] = CRGB::Black;
   }
}

Den delay() denken wir uns da mal noch bitte weg. Ich weis, dass ich den noch durch millis() etc. entfernen muss.

Mir geht es jetzt hier erst mal ums Prinzip...

webSocket.loop() und server.handleClient() werden erst wieder aufgerufen, wenn die for Schleife beendet ist. Dann ändert sich die Farbe bis zum nächsten durchlauf der Schleife. Zwischendrin ist logoscherweise keine Änderung vornehmbar.

Wie bekomme ich das aber trotzdem hin?

Hallo,

wenn Du nicht 1000 LED´s ansteuern willst hängt das sicher davon ab was Du machen willst. eine for schleife um 100 LED einzustellen wird eventuell noch schnell genug gehen, FastLED.show() ist das eigendliche Problem. (100 LED *30us=3ms)
ich hab mal was mit 10 LED´s gemacht das läuft eigendlich. Allerdings sind da nicht die schnellsten Animationen verwendet und ich hab konsequent millis() verwendet.

Wenn ich jetzt mal annehme das Du alle 100ms den Strip aktualisieren willst darf hat nur alle 100 ms ein FastLED.schow() kommen. Wenn der bei 100 LEDs 3ms dauert ?? mit 10 LED geht es.

hier was zum lesen.

github.com/FastLED/FastLED/wiki/Interrupt-problems

Heinz

Hallo,

in Deinem Schnipsel ist Delay das Problem das kannst Du auch mit millis machen.

Statt for loops lieber die Animation mit millis() verknüpfen:

void loop(){
led = millis()/100 % NUM_LEDS;
leds[led] = CHSV(millis()/50, 255, 255);
FastLed.show();
}

Die Geschwindigkeit wird dadurch durch den Teiler von millis() bestimmt.

Doctor236:
Ich glaube nicht dass das ein Problem von den Interupts ist, sondern einfach von den for-Schleifen.

Die WS2812B müssen blockierend bei abgeschalteten Interrupts angesteuert werden, was den µC taub macht. Abhilfe:

  • anderer LED-Typ wie APA102
  • parallele Prozesse durch zwei µCs oder anderweitig selbständige Hardware

Angenommen ich nehme dann einen ESP als Webserver, der alles per Serial an einen Micro (als Controller für den Streifen) weitergibt, würde das funktionieren?

Wenn der Micro in einer Animationspause die Informationen vom ESP abruft, sollte es funktionieren. Konjunktiv, weil ich es bislang nur mit I2C probiert habe.

Da ist dann aber wieder der Knackpunkt die Animationspause. ich will es ja während einer laufenden Animation ändern können. Das geht damit doch dann nicht?

Du hast in loop() schon eine Schleife. for-Schleifen kann man daher durch if-Abfragen in loop() ersetzen und zwischen den Schritten andere Dinge tun. Wie weit man ist muss man dann per Hand mitzählen

Doctor236:
Da ist dann aber wieder der Knackpunkt die Animationspause. ich will es ja während einer laufenden Animation ändern können. Das geht damit doch dann nicht?

Vermutlich verwenden wir das Wort "Animationspause" unterschiedlich. Ich meine eine Pause zwischen FastLED.show(), also

  • FastLED.show();
  • Animationspause mit Datenkommunikation und Reaktion darauf
  • FastLED.show();

Bei meiner LED-Uhr habe ich den Typ APA102 verwendet, der bei geeignetem µC wie dem ESP8266 - in der Bar verwende ich Teensy 3.2 - ungefähr zehnmal schneller animiert werden kann. Eine Unterbrechung mit Interrupt - bei meiner Uhr ist das die IR-Fernbedienung - ist kein Problem. Mein Rat ist daher ein Typwechsel!

Solltest Du ein geschwätziges Webinterface haben, so könnte die Datenkommunikation die Animation merklich stören, da wäre eine vorherige Filterung sinnvoll. Das kann ich aber mangels weiterer Informationen nicht einschätzen.

Blockadearmes Programmieren setze ich bei meinen Überlegungen voraus, siehe #14.

Nachdem ich den ws2812 Streifen schon habe, find ich die Lösung von Serenifly die Beste. Das beweist eigentlich auch, dass zumindest einfache Animationen mit Webinterface (RGB Werte, Helligkeit und Geschwindigkeit) auch mit so einem Streifen möglich ist, bei dem es auf das exakte Timing drauf ankommt

.
Die loop() Schleife verwende ich jetzt so wie Serenifly vorgeschlagen hat.

Serenifly:
Du hast in loop() schon eine Schleife. for-Schleifen kann man daher durch if-Abfragen in loop() ersetzen und zwischen den Schritten andere Dinge tun. Wie weit man ist muss man dann per Hand mitzählen

In einer Variablen zähle ich dann manuell hoch bzw. runter. Delay ist ersetzt durch millis() (BlinkWithoutDelay).

Vom Webinterface lassen sich die Werte in Echtzeit ohne Verzögerung ändern.
Eine Modiänderung (also Animationsänderung) ist über HTML Buttons ebenfalls möglich.

Jetzt mal schauen wie es bei etwas komplizierteren Animationen aussieht. Ich gehe aber davon aus, dass das auch machbar ist.

Doctor236:
Jetzt mal schauen wie es bei etwas komplizierteren Animationen aussieht.

These: Das wird nicht zufriedenstellend funktionieren.

Ich freue mich auf den Gegenbeweis! Ich bin hier, um was zu lernen.