Fastled Lauflicht Geschwindigkeit

Hallo,

ich brauche mal einen Denkanstoß im Umgang mit Fastled.
Wie bekommt man es hin, daß ab einem bestimmten Pixel (z.B. i=14), der weitere Lauflicht Effekt, per vorgegebenen Interval langsamer oder schneller weiter läuft.
Ist das Ende erreicht, gehts wieder vom ersten Pixel los.

Also, es fängt langsam an und wird zum Ende (max. LED) immer schneller.

Danke im voraus...

#include <FastLED.h>
#define NUM_LEDS 32
#define DATA_PIN 4
CRGB leds[NUM_LEDS];

unsigned long letzteMillis1 = 0;
unsigned long letzteMillis2 = 0;
const long interval1 = 700;
const long interval2 = 100;
int i1 = 0;
int i2 = 0;

void setup(){
   	delay(2000);
    FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);}

void loop() {
  unsigned long jetztMillis1 = millis();
  unsigned long jetztMillis2 = millis();
  
  
  if (jetztMillis1 - letzteMillis1 >= interval1)
     {
      letzteMillis1 = jetztMillis1;
      leds[i1] = CRGB::White;
      FastLED.show();  
      i1 ++;
      leds[i1-1] = CRGB::Black;
     }
}

Hi,

ich bastel gerade mit NeoPixel rum. In einigen Funktionen nutze ich gerne den Shift-Operator. Der ist easy und perfomant.
Du könntest jetzt also einfach den Startintervall auf 4096 ms (long intervall = 4096) setzen und bei jeder Iteration machst du dann (intervall >> 1), damit wird es um 1 Bit nach rechts geshiftet, also durch 2 geteilt. In dem Fall geht das von 4096 (2^12) bis 1 (2^1), also 11 Schritte.

Edit: Setz dein interval1 nicht als const. Dann kannst du interval1 auch ändern.

if (i1 > 13)
   interval1 >> 1;

Edit2: Aktuell nutze ich auch noch viel das delay() Kommando, statt mit millis() hin und her zu rechnen. Außerdem können millis() überlaufen - das musst du abfangen

tispokes:
Aktuell nutze ich auch noch viel das delay() Kommando, statt mit millis() hin und her zu rechnen. Außerdem können millis() überlaufen - das musst du abfangen

Falsch! Du musst nur die richtigen Datentypen nutzen und die Abfrage richtig schreiben. Dann "fängt" sich das von selbst.

Gruß Tommy

Delay wollte ich überhaupt nicht nutzen.
Es müssen noch andere Dinge zur selben Zeit getätigt werden.
Ein sogenannter millis Überlauf würde höchstwahrscheinlich nicht in Frage kommen.
Der Arduino wird, wenn das Projekt mal fertig ist, jeden Tag neu gestartet.

Hat vielleicht jemand ein paar Code Schnipsel, die man für mein Vorhaben anwenden könnte?

thx

Hallo,

@ TO: ganz einfach :slight_smile:

Schreib dir eine nicht blockierende Funktion mit millis(), die aller x [ms] ein bool true zurückgibt.
Den Intervallwert übergibste als Parameter.

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

Desweiteren stehen die Eckpunkte fest. Ab Led 14 verändert sich das Intervall.
Bei der letzten LED wird das Intervall wieder auf seinen ursprünglichen Wert gesetzt.
Klare einfache Sache.

Ansonsten wird immer wenn der Rückgabewert true ist eine neue Led eingeschalten und die vorletzte ausgeschalten.
Kannste in einer separaten Funktion unterbringen die nur bei 'true' aufgerufen wird.

Und nutze bitte für Pinnummern const byte statt define, kann man im dümmsten Fall weniger Unsinn machen.

That's it. :wink:

Tommy56:
Falsch! Du musst nur die richtigen Datentypen nutzen und die Abfrage richtig schreiben. Dann "fängt" sich das von selbst.

Gruß Tommy

Nein, ist schon richtig! Welcher Datentyp läuft denn nicht über?
Ich denke du spielst an auf unsigned und signed, es laufen aber beide über.

Klar, wenn man es richtig abfängt - kein Problem. Deswegen das Wörtchen kann.
Dass delay() aber nicht gerade sinnvoll ist bei sowas, hab ich jetzt auch gelernt :wink:

Hallo,

stiftest du gerade Verwirrung für andere und dich selbst?

millis läuft nach 49 Tagen über. Dagegen kann man absolut nichts machen.
Der Rückgabewert ist vom Datentyp unsigned long.
Der Trick liegt in der Subtraktion neu-alt und Vergleich zur gewünschten Differenz.
Damit kann millis überlaufen wie es lustig ist.
Der Datentyp der "alt" Variable muss vom gleichen Datentyp wie millis sein.
Der Datentyp der "intervall" Variable muss unsigned sein und so groß das der gewünschte Wert reinpasst.
Der Einfachheit auch unsigned long.

Am Ende bedeutet das "nur", dass das größtmögliche Intervall auf 49 Tage begrenzt ist.
Nicht mehr und nicht weniger.

0815rudi:
Delay wollte ich überhaupt nicht nutzen.
Es müssen noch andere Dinge zur selben Zeit getätigt werden.

Dann habe ich eine schlechte Nachricht, denn FastLED.show(); ist für den LED-Typ WS2812 blockierend. Ich verwende daher wenn möglich APA102, braucht zwar einen Pin mehr, die Ausgabe kann aber unterbrochen werden.

0815rudi:
Hat vielleicht jemand ein paar Code Schnipsel, die man für mein Vorhaben anwenden könnte?

if (i1 > 13) interval1 += 10;
...
if (i1 < NUM_LEDS) {
  i1++;
} else {
  i1 = 0;
  interval1 = 700;
}

(ungetestet)

Doc_Arduino:
stiftest du gerade Verwirrung für andere und dich selbst?

Hey,

dann hab ich wohl einen Knoten im Kopf gehabt.

Beispiel 1: Bei der Subtraktion neu-alt
1000 - 200 = 800, okay klar.

Beispiel 2: (Nahe dem Überlauf)
Fix: unsigned long hat einen Max-Wert von 2^32-1
(alt) 2^32-100 - (neu) 200 = 2^32-300

Okay, klar. Wenn ich jetzt einen Intervall von >= 700 haben wollte, ist natürlich 2^32-300 größer als 700.

Danke fürs Entknoten @Doc_Arduino

Hallo,

wenn es bei dir kein Tippfehler ist. Die Subtraktion darf nicht vertauscht werden. Es bleibt bei der Formel neu - alt. Nicht alt - neu. Vorsichtshalber nochmal erwähnt.

Doc_Arduino:
Am Ende bedeutet das "nur", dass das größtmögliche Intervall auf 49 Tage begrenzt ist.
Nicht mehr und nicht weniger.

Mit einigen Kniffen läßt sich das auch umgehen und Zeitintervalle bis 35 Jahre verwenden.
https://www.faludi.com/2007/12/18/arduino-millis-rollover-handling/

Grüße Uwe

Wobei der Autor an einer Stelle auch Unsinn schreibt:

On the Arduino microcontroller, the millis() function counts the number of milliseconds since the program started running. Unfortunately, this count resets to zero after approximately 9 hours and 32 minutes.

Gruß Tommy

Hallo,

ist bekannt. :wink: Das Spiel kann man bis ins Unendliche treiben. Man muss nur soviele Überlaufzähler anlegen/"kaskadieren" wie man für sein Intervall benötigt. Dann wartet das Ur-Ur-Ur-Ur Enkel noch auf ein Ereignis. :slight_smile:

Wegen dem Autor. Ich hatte mal gelesen das millis erst später "erweitert" wurde. 2007 mag das noch so limitiert gewesen sein. So meine Erinnerung. Es gibt nichts schlimmeres wie alte Beiträge im Internet.

Hi

Wollte auch schon sagen, daß man den Roll-Zähler, wenn man Den nicht als int nimmt, auch durchaus länger zählen kann.
Zur Not geht Das auch händisch mit einzelnen Speicherstellen ... so viel Backup-Batterien werden wir nicht zusammen bekommen, daß der Käfer so lange lebt, bis Das dann überläuft.

MfG

postmaster-ino:
... so viel Backup-Batterien werden wir nicht zusammen bekommen, daß der Käfer so lange lebt, bis Das dann überläuft.

Die uns Menschen angeblich nachfolgenden Kopffüßler werden sich fragen, was das wohl soll, genauso wie diejenigen, die das Ergebnis "42" erblickten.

In alter Elektronik sterben nicht selten die Kondensatoren zuerst bzw. sie ändern ihren Wert und werden dadurch unbrauchbar.

Mein Vorschlag aus #7 getestet mit APA102:

#include <FastLED.h>
FASTLED_USING_NAMESPACE
//#define DATA_PIN    4      // MOSI Pin11
//#define CLK_PIN     5      // ACK  Pin13
#define LED_TYPE    APA102
#define COLOR_ORDER BGR
#define BRIGHTNESS  64
#define NUM_LEDS    32

CRGB leds[NUM_LEDS];

uint32_t letzteMillis1 = 0;
uint32_t interval1 = 50;
uint16_t i1 = 0;

void setup() {
  // FastLED.addLeds<LED_TYPE, DATA_PIN, CLK_PIN, COLOR_ORDER, SPI_HZ>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  LEDS.showColor(CRGB(0, 0, 0));
}

void loop() {
  unsigned long jetztMillis1 = millis();

  if (jetztMillis1 - letzteMillis1 >= interval1)
  {
    letzteMillis1 = jetztMillis1;
    leds[i1] = CRGB::White;
    FastLED.show();
    leds[i1] = CRGB::Black;
    if (i1 > 13) interval1 += 50;
    if (i1 < NUM_LEDS) {
      i1++;
    } else {
      i1 = 0;
      interval1 = 50;
    }
  }
}