Arduino Nano WS2812B Lauflicht FastLED Sketch

Hallo,

ich habe hier ein WS2812B Stripe mit einem Arduino Nano mit folgendem FastLED Sketch in Betrieb:

#include <FastLED.h>

#define LED_PIN     6
#define NUM_LEDS    120
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS  200

CRGB leds[NUM_LEDS];

void setup() {
    delay(1000);
    LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
    FastLED.setBrightness(BRIGHTNESS);
    FastLED.clear();
    FastLED.show();
}

void loop() {

  leds[0] = CRGB(255, 255, 255);
  leds[1] = CRGB(255, 255, 255);
  leds[2] = CRGB(255, 255, 255);
  leds[3] = CRGB(255, 255, 255);
  leds[4] = CRGB(255, 255, 255);
  leds[5] = CRGB(255, 0, 0);
  leds[6] = CRGB(255, 255, 255);
  leds[7] = CRGB(255, 255, 255);
  leds[8] = CRGB(255, 255, 255);
  leds[9] = CRGB(255, 255, 255);
  leds[10] = CRGB(255, 255, 255);
  leds[11] = CRGB(255, 0, 0);
  leds[12] = CRGB(255, 255, 255);
  leds[13] = CRGB(255, 255, 255);
  leds[14] = CRGB(255, 255, 255);
  leds[15] = CRGB(255, 255, 255);
  leds[16] = CRGB(255, 255, 255);
  leds[17] = CRGB(255, 0, 0);
  leds[18] = CRGB(255, 255, 255);
  leds[19] = CRGB(255, 255, 255);
  leds[20] = CRGB(255, 255, 255);
  leds[21] = CRGB(255, 255, 255);
  leds[22] = CRGB(255, 255, 255);
  leds[23] = CRGB(255, 0, 0);
  leds[24] = CRGB(255, 255, 255);
  leds[25] = CRGB(255, 255, 255);
  leds[26] = CRGB(255, 255, 255);
  leds[27] = CRGB(255, 255, 255);

  
  leds[32] = CRGB(255, 255, 255);
  leds[33] = CRGB(255, 0, 0);
  leds[34] = CRGB(255, 255, 255);
  leds[35] = CRGB(255, 255, 255);
  leds[36] = CRGB(255, 255, 255);
  leds[37] = CRGB(255, 255, 255);
  leds[38] = CRGB(255, 255, 255);
  leds[39] = CRGB(255, 0, 0);
  leds[40] = CRGB(255, 255, 255);
  leds[41] = CRGB(255, 255, 255);
  leds[42] = CRGB(255, 255, 255);
  leds[43] = CRGB(255, 255, 255);
  leds[44] = CRGB(255, 255, 255);
  leds[45] = CRGB(255, 0, 0);
  leds[46] = CRGB(255, 255, 255);
  leds[47] = CRGB(255, 255, 255);
  leds[48] = CRGB(255, 255, 255);
  leds[49] = CRGB(255, 255, 255);
  leds[50] = CRGB(255, 255, 255);
  leds[51] = CRGB(255, 0, 0);
  leds[52] = CRGB(255, 255, 255);
  leds[53] = CRGB(255, 255, 255);
  leds[54] = CRGB(255, 255, 255);
  leds[55] = CRGB(255, 255, 255);
  leds[56] = CRGB(255, 255, 255);
  leds[57] = CRGB(255, 0, 0);
  leds[58] = CRGB(255, 255, 255);
  leds[59] = CRGB(255, 255, 255);


  leds[60] = CRGB(255, 255, 255);
  leds[61] = CRGB(255, 255, 255);
  leds[62] = CRGB(255, 255, 255);
  leds[63] = CRGB(255, 0, 0);
  leds[64] = CRGB(255, 255, 255);
  leds[65] = CRGB(255, 255, 255);
  leds[66] = CRGB(255, 255, 255);
  leds[67] = CRGB(255, 255, 255);
  leds[68] = CRGB(255, 255, 255);
  leds[69] = CRGB(255, 0, 0);
  leds[70] = CRGB(255, 255, 255);
  leds[71] = CRGB(255, 255, 255);
  leds[72] = CRGB(255, 255, 255);
  leds[73] = CRGB(255, 255, 255);
  leds[74] = CRGB(255, 255, 255);
  leds[75] = CRGB(255, 0, 0);
  leds[76] = CRGB(255, 255, 255);
  leds[77] = CRGB(255, 255, 255);
  leds[78] = CRGB(255, 255, 255);
  leds[79] = CRGB(255, 255, 255);
  leds[80] = CRGB(255, 255, 255);
  leds[81] = CRGB(255, 0, 0);
  leds[82] = CRGB(255, 255, 255);
  leds[83] = CRGB(255, 255, 255);
  leds[84] = CRGB(255, 255, 255);
  leds[85] = CRGB(255, 255, 255);
  leds[86] = CRGB(255, 255, 255);
  leds[87] = CRGB(255, 0, 0);


  leds[92] = CRGB(255, 255, 255);
  leds[93] = CRGB(255, 255, 255);
  leds[94] = CRGB(255, 255, 255);
  leds[95] = CRGB(255, 255, 255);
  leds[96] = CRGB(255, 255, 255);
  leds[97] = CRGB(255, 255, 255);
  leds[98] = CRGB(255, 0, 0);
  leds[99] = CRGB(255, 255, 255);
  leds[100] = CRGB(255, 255, 255);
  leds[101] = CRGB(255, 255, 255);
  leds[102] = CRGB(255, 255, 255);
  leds[103] = CRGB(255, 255, 255);
  leds[104] = CRGB(255, 0, 0);
  leds[105] = CRGB(255, 255, 255);
  leds[106] = CRGB(255, 255, 255);
  leds[107] = CRGB(255, 255, 255);
  leds[108] = CRGB(255, 255, 255);
  leds[109] = CRGB(255, 255, 255);
  leds[110] = CRGB(255, 0, 0);
  leds[111] = CRGB(255, 255, 255);
  leds[112] = CRGB(255, 255, 255);
  leds[113] = CRGB(255, 255, 255);
  leds[114] = CRGB(255, 255, 255);
  leds[115] = CRGB(255, 255, 255);
  leds[116] = CRGB(255, 0, 0);
  leds[117] = CRGB(255, 255, 255);
  leds[118] = CRGB(255, 255, 255);
  leds[119] = CRGB(255, 255, 255);


  FastLED.show();
  
}

Die ersten 5 LED leuchten Weiß und die nachfolgende 6. LED jeweils Rot. Zwichend der 27. und 32., sowie 87. und 92. LED sind jeweiels 4 LED's, die aus sind und auch aus bleiben sollen. Nicht fragen wieso, ist Anwendungbedingt so und diese je 4 LED's werden nicht benötigt und bruachen daher auch keine Licht zu erzeugen (und schont das Netzteil um ein paar Milli-Ampere). Nun bin ich nicht der Sketch Experte und bin mal froh, das ich das erst einmal so zum laufen bekommen habe ... :slight_smile:

Nun möchte ich aber folgende Situation haben, und zwar das die jeweils 6. Roten LED's sich als Lauflicht bewegen, ohne das der Abstand zu den roten LED's sich zueinander verändert, also als Lauflicht und die je 4 LED's allerdings an den in meinem Sketch definierten Positionen auch ausbleiben.

Wäre jemand ggf. so nett und könnte mir vieleicht meinen o.g. Sketch bitte auf das on mir gewünschte Verhaltenmuster abändern?

Vielen Dank ... :slight_smile:

Ein erster Ansatz könnte so aussehen:

#include <FastLED.h>

#define LED_PIN     6
#define NUM_LEDS    120
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS  200

CRGB leds[NUM_LEDS];

void setup() {
  //delay(1000);
  LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  for (byte led = 0; led < NUM_LEDS; led++) {
    leds[led] = CRGB(255, 255, 255);
  }

  leds[5] = CRGB(255, 0, 0);
  leds[11] = CRGB(255, 0, 0);
  leds[17] = CRGB(255, 0, 0);
  leds[23] = CRGB(255, 0, 0);
  leds[28] = CRGB(0, 0, 0);
  leds[29] = CRGB(0, 0, 0);
  leds[30] = CRGB(0, 0, 0);
  leds[31] = CRGB(0, 0, 0);
  leds[33] = CRGB(255, 0, 0);
  leds[39] = CRGB(255, 0, 0);
  leds[45] = CRGB(255, 0, 0);
  leds[51] = CRGB(255, 0, 0);
  leds[57] = CRGB(255, 0, 0);
  leds[63] = CRGB(255, 0, 0);
  leds[69] = CRGB(255, 0, 0);
  leds[75] = CRGB(255, 0, 0);
  leds[81] = CRGB(255, 0, 0);
  leds[87] = CRGB(255, 0, 0);
  leds[88] = CRGB(0, 0, 0);
  leds[89] = CRGB(0, 0, 0);
  leds[90] = CRGB(0, 0, 0);
  leds[91] = CRGB(0, 0, 0);
  leds[98] = CRGB(255, 0, 0);
  leds[104] = CRGB(255, 0, 0);
  leds[110] = CRGB(255, 0, 0);
  leds[116] = CRGB(255, 0, 0);

  FastLED.show();
}

void loop() {
  CRGB tmp = leds[NUM_LEDS - 1];
  for (byte led = NUM_LEDS - 1; led > 0; led--) {
    leds[led] = leds[led - 1];
  }
  leds[0] = tmp;
  FastLED.show();
  delay(100);
}

Hallo und erst einmal vielen Dank für den Sketch, im Prinzip genau das was ich gesucht habe.

Jedoch wandern die LED's, die eigentlich ausbleiben sollen, dummerweise gleich mit, was sie ja nicht tun sollen.

Lässt sich die Position der entsprechden Pixels, die ausbleiben sollen, irgendwie noch fixieren?

Hallo,

das ist ein sehr schönes Bsp. zum programmieren lernen. Du benötigst dazu weitere Arrays und in sich geschachtelte for Schleifen. Vorsicht vorm Logik Hirnknoten. :slight_smile:

Folgendes. Du hast ein Muster. Im Wechsel sind immer 5 an und die 6. aus. Das wiederholt sich.
Für das Muster kannst du dir ein Array bauen.
const bool muster [] = {true, true, true, true, true, false};
Oder du schiebst immer ein Bit als Maske, verundest und fragst auf true ab. Je nach Belieben.
Die Pins die immer AUS bleiben sollen schreibste auch in ein Array.
const byte pinNotUsed [] = {28, 29, 30, 31, 88, 89, 90, 91};

Jetzt gehst du mit einer for Schleife über alle 120 Leds drüber. Dabei vergleichst du mittels Muster ob diese eingeschalten werden darf oder nicht. Und! Du vergleichst mit dem pinOff Array ob die überhaupt beachtet werden soll. Wenn nicht, setzt du den Mustervergleich erst bei der nächsten Leds fort. Du wirst wie schon erwähnt in sich verschachtelte Schleifen bauen. Das wird richtig gut. :slight_smile:

Tipp. Die übliche Indexzählvariable kann man auch im for Anweisungsblock unterbringen.

Eine sehr schöne Aufgabe um vom Spaghetti Code wegzukommen. Arrays und for Schleifen wirst du sowieso immer wieder benötigen.

Wünsche fröhliches grübeln.

Tipp 2:
Um in das Schleifen denken besser reinzukommen. Programmiere erstmal je eine zum nacheinander an und wieder ausschalten. Das sollte helfen für das Verständnis. Versuche nicht gleich alles auf einmal.

Zwichend der 27. und 32., sowie 87. und 92. LED sind jeweiels 4 LED's, die aus sind und auch aus bleiben sollen. Nicht fragen wieso, ist Anwendungbedingt so und diese je 4 LED's werden nicht benötigt und bruachen daher auch keine Licht zu erzeugen

sollen diese LEDs nur aus bleiben und der wandernde Punkt sozusagen abgeschaltet trotzdem durchwandern oder
sollen diese Pixel "übersprungen" - werden - also von der 27 direkt auf 32?

sanweb:
Lässt sich die Position der entsprechden Pixels, die ausbleiben sollen, irgendwie noch fixieren?

Ja, vier Zeilen zusätzlich:

void loop() {
  CRGB tmp = leds[NUM_LEDS - 1];
  for (byte led = NUM_LEDS - 1; led > 0; led--) {
    leds[led] = leds[led - 1];
  }
  leds[0] = tmp;
  leds[92] = leds[88];
  leds[88] = CRGB(0, 0, 0);
  leds[32] = leds[28];
  leds[28] = CRGB(0, 0, 0);
  FastLED.show();
  delay(100);
}

Jetzt weiter bei #3 :slight_smile:

Hallo,

ich stifte ja nicht nur an, ich mach auch mit. Du, sanweb, bist aber auch gefordert. :wink:

Eine Sache muss ich nachfragen. Hast du im Muster ein Fehler drin? Sonst stimmt das 5+1 nicht mehr Mit Led 92 - 97 wären 6 Leds hintereinander "ON".

Hallo,

erst einmal vielen Dank an alle Teilnehmer, die mir hier weiter geholfen haben bei meinem (aus ihrer Sicht) "Problemchen" ... :slight_smile:

Doc_Arduino:
das ist ein sehr schönes Bsp. zum programmieren lernen. Du benötigst dazu weitere Arrays und in sich geschachtelte for Schleifen. Vorsicht vorm Logik Hirnknoten. :slight_smile:

In der Tat ist das eine gute Übung. Kann zwar bischen PHP programmieren, was ja im Prinzip nach längerem betrachten ja "fast" identisch ist, jedoch die zu ladenen Bibliotheken und deren Syntax zu berücksichtigen sind.
Das es mein zweites, kleines Projekt mit einem Arduino nano ist, kam dann erst einmal der von dir erwähnte "Spaghetti-Code" zustande, der ja im Prinzip ja schon mal als Basis seinen Zweck erfüllte. Deine ausführliche Erklärungen mit den Arrays brngen da tatsächlich schonmal Licht ins Dunkel und dürften mir sehr hilfreich sein für eventuell künftig geplante Kleinst-Projekte.

noiasca:
sollen diese LEDs nur aus bleiben und der wandernde Punkt sozusagen abgeschaltet trotzdem durchwandern oder
sollen diese Pixel "übersprungen" - werden - also von der 27 direkt auf 32?

Diese Pixel solllen eine feste Position haben, stets ausgeschaltet sein und trotzdem durchwandert werden. "Kosmetischer" Sinn und Erklärung dafür siehe unten die angehängten Bilder.

agmue:
Ja, vier Zeilen zusätzlich:

void loop() {

CRGB tmp = leds[NUM_LEDS - 1];
  for (byte led = NUM_LEDS - 1; led > 0; led--) {
    leds[led] = leds[led - 1];
  }
  leds[0] = tmp;
  leds[92] = leds[88];
  leds[88] = CRGB(0, 0, 0);
  leds[32] = leds[28];
  leds[28] = CRGB(0, 0, 0);
  FastLED.show();
  delay(100);
}



Jetzt weiter bei #3 :)

Funktioniert jetzt perfekt, vielen Dank für Deine rasche Hilfe. Bin stets immer wieder erstaunt, mit welcher Leichtigkeit sich Leute komplette Programme (in diesem falle Sketche) mal gerade so aus dem Ärmle schütteln können basierend auf Fragestellungen ohne Kenntnis des Einsatzgebietes. Hut ab und tiefe Verbeugung ... :wink:

Um nun im wahrsten Sinne des Wortes Licht ins Dunkel zu bringen hier nun mal eine kurze Projektvorstellung, wofür ich das ganze benötige:

Das mir regelmäßig von einem namhaften Hersteller regelmäßig pünktlich nach 15 Monaten die teure LED Beleuchtung des 250 Liter Aquariums ausfiel und ich nicht mehr bereit war (zum einen auch aus Zeitgründen) eine neue zu kaufen, habe ich kurzerhand das Aquarium in seiner eigentlichen Funktion ausser Betrieb genommen und das Aquarium zu einer Art "Gewächshaus" mit Kakteen, Sukulenten und lebenden Steinen umfunktioniert.

Die defekte Beleuchtung, die fest in der Abdeckung integriert ist, habe ich an den einzelnen Röhren mit WS2812B LEDs mit durchsichtigem Klebeband befestigt. Am Afang, in der Mitte und am Ende habe ich bei den beiden WS2512B Streifen eine Spannungsversorgung angeschlossen, damit die Stripes auf Grund der Länge eine gleichmäßige Spannungsversorgung (mathematisch gesehen also an insgesamt je 3 Punkten pro Stripe) erhalten.

Als Controller kam nun ein Arduino Nano zum Einsatz, wobei zwischen dem Arduino Nano und der LED Spannungseinspeisung ein 1000 μf 16v Elko gesetzt wurde. In der Datenleitung zwischen dem Arduino und dem WS2812B kommt ein 470 Ohm Widerstand zum Einsatz. Die Bauteile habe ich eingefügt, da ich mehrfach im Internet gelesen habe, das man damit die erste LED im WS2812B vor Zerstörung schützen kann. Die Bauteile hatte ich in der grabbelkiste noch rumfliegen aus einem Ambilight Projekt meiner PC-Monitore, welches ebenefalls mit Arduino Nano's betrieben wird.

Die Unterbrechung in beiden LED Stripes von je 4 LED's kommt durch den Quersteg des Aquariums zustande, da ich nicht einsah, diesen Steh zum einen zu beleuchten (das Licht kame dann ja eh nicht zu den Pflanzen durch) und zum anderen dadurch paar mA einzusparen.

Die Kombination mit 5 weißen LED's gefolgt von einer einzelnen roten LED fand ich durch ein Vorgängerprojekt heraus, da habe ich bereits ein Nano-Aquarium mit 10 Weißen und 2 Roten LED's als Beleuchtung mit Sukulenten bepflanzt und die wuchsen bei dem Licht rasanter als unter normalen Tageslichtverhältnissen. Daher gehe ich mal von einem optimalen Farbspektrum zum Vorteil für die Pflanzen aus.

Warum nun das ganze rotierend? Um das erzeugte Farbspektrum gleichmäßig über die zu beleuchtende Fäche zu genieren und die Pflanzen sich nicht eventuell in einem für sie günstige einseitige (und mich optisch ungünstige) Richtung wachsen. So zumindest die Idee dahinter ...

Ein-/Aus-Schaltung habe ich über einen smarten GoSund SP111 Stecker realisiert, welchen ich mit Tasmota geflasht habe (für mehr funktionalität und zum anderen, um die integration in einer China-Cloud durch die original-Firmware zu umgehen). Dort meine GPS-Daten und Zeitzone eingegeben, damit das Licht dann mit dem regulärem Sonnenauf- und Untergang automatisch gesteuert wird.

Soo, habe nun fertig mit meinem Roman ... :slight_smile: ... Vielen Dank noch einmal an dieser Stelle für die großartige und schnelle Hilfe für die Umsetzung meines Projektes.

Hallo,

du "züchtest" dir also deinen eigenen Urwald? Schön. :slight_smile:

Könntest du noch auf die Frage in #6 eingehen?

Doc_Arduino:
Eine Sache muss ich nachfragen. Hast du im Muster ein Fehler drin? Sonst stimmt das 5+1 nicht mehr Mit Led 92 - 97 wären 6 Leds hintereinander "ON".

Also ehrlich gesagt, hättest Du jetzt nicht noch einmal expliziet daraf hingewiesen, hätte ich es erst einmal optisch so nicht gemerkt, aber du hast vollkommen recht, das da ein Fehler im Muster ist. und zwar habe ich auf jedem LED streifen beim rotieren jeweils einen Bereich mit 6 weißen LED's. Während des rotierens fällt das erst einmal so gar nicht auf, musste erst einmal das delay hoch drehen um den von dir genannten Fehler im Muster zu erkennen ... :slight_smile: Auf meinem mittleren Foto ist das bei der Querstrebe gut zu erkennen bei genauem betrachtem (Vorne links neben der Strebe und hinten rechts neben der Strebe)

Ich vermute, das hängt wohl mit der Unterbrechung in jedem Stripe zusammen, oder habe im Kopfrechnen auf Grund des Alters nachgelassen ... :slight_smile:

//Nachtrag:
Habs jetzt mal jede rote LED einzeln definiert und danach neu gestartet. Sobald ich die fünfte rote LED definiere und er über die erste unterbrechung wegläuft, wird aus der ersten 5'er Gruppe ein eine 6'er Gruppe. Läuft er danach mit der ersten LED über die zweite unterbrechung (bei allen rot definierten Stellen), wird bei der ersten Unterbrechung aus der dort befindlichen 5'er Gruppe auch eine 6'er Gruppe, wobei dann permanent 2 6'er Gruppen rotieren und der Rest 5'er Gruppen. Lag ich also nicht verkehrt mit der Annahme, das es mit den unterbrechungen zu tun hat ... :slight_smile: ... Mal weiter expermimentieren ... :smiley: ... Mathematisch kann es aber nicht aufgehen das muster, da bei 120 LED's 8 aus sind und die Zahl 112 sich nicht gerade durch 6'er Gruppen teilen lässt.

Hallo,

okay, auch wenn du dich erstmal zufrieden gibts, zeige ich dir einmal meine Version. Da ich keine Led Streifen habe teste ich das mit der seriellen Ausgabe. Ein Vorschlag wie du das verwendest ist enthalten. Die fehlende Lib und Objekt bauste noch drum herum.

Am Ende habe ich auf weitere for Schleifen verzichtet um Rückgabewerte nach Vergleich zu erhalten und um die letzte Funktion noch etwas schneller zu machen. In der letzten Funktion isLedUsed war erst eine for Schleife drin, die würde aber 120 x 8 durchlaufen. Jetzt wird sich der letzte gültige Index gemerkt und damit Mehrfachvergleiche vermieden.

Betrachte das von innen nach außen.
isLedSampleOn() Wird die aktuelle Led laut Muster überhaupt angesteuert?
isLedUsed(led) Wird die Led überhaupt verwendet oder übersprungen?
Das wird mit allen 120 Leds verglichen.

/*
  Doc_Arduino - german Arduino Forum
  IDE 1.8.13
  avr-gcc 10.2.0
  Arduino Mega2560
  16.11.2020
  License: GNU GPLv3
  https://forum.arduino.cc/index.php?topic=713848.0
  Durchlaufzeit etwas verbessert
*/

const byte NUM_LEDS = 120;
const bool sample [] = {true, true, true, true, true, false};
const byte pinNotUsed [] = {28, 29, 30, 31, 88, 89, 90, 91};
const byte NUM_SAMPLE = sizeof(sample);

void setup(void)
{
  Serial.begin(115200);
  Serial.println("\nStart");

  for (byte led = 0; led < NUM_LEDS; led++)
  {
      if(isLedUsed(led) )
      {
        //  Kontrollausgaben 
        Serial.print(led); Serial.print('\t');
        if (isLedSampleOn(NUM_SAMPLE) ) Serial.println("ON");
        else Serial.println("OFF");

        /*
        // das sollte dann bei dir verwendet werden
        if (isLedSampleOn(NUM_SAMPLE) ) leds[led] = CRGB(255, 255, 255);
        else leds[led] = CRGB(255, 0, 0);
        */
      }
  }
}

void loop(void)
{

}

bool isLedSampleOn (const byte MAX)
{
  static byte indexSample = 0;;
  bool state = false;
  if (sample[indexSample]) state = true;
  indexSample++;
  if (indexSample >= MAX) indexSample = 0;
  return state;
}


bool isLedUsed (const byte led)
{
  const byte NUM_NOT_USED = sizeof(pinNotUsed);
  static byte index = 0;
  bool state = true;

  // wird insgesamt 8x aufgerufen
  if(led == pinNotUsed[index])
  {
    state = false;
    index++;
    if (index >= NUM_NOT_USED) index = 0;
  }  
   
  return state;
}

Edit:
Deine Unterbrechung blieb unbetrachtet. Das macht es jetzt doch komplizierter als Anfangs gedacht.

Hallo,

nochmal kurz nachgedacht. Die Streifen werden doch in Reihe zusammengeschalten. Einen elektrischen Grund kann es dafür nicht geben das du 6er Gruppen einschalten musst. Hängt das mit baulichen Anordnung zusammen?
Also bleibt alles wie im Eingangspost?

  leds[0]  = CRGB(255, 255, 255);
  leds[1]  = CRGB(255, 255, 255);
  leds[2]  = CRGB(255, 255, 255);
  leds[3]  = CRGB(255, 255, 255);
  leds[4]  = CRGB(255, 255, 255);
  leds[5]  = CRGB(255, 0,   0);
  leds[6]  = CRGB(255, 255, 255);
  leds[7]  = CRGB(255, 255, 255);
  leds[8]  = CRGB(255, 255, 255);
  leds[9]  = CRGB(255, 255, 255);
  leds[10] = CRGB(255, 255, 255);
  leds[11] = CRGB(255, 0,   0);
  leds[12] = CRGB(255, 255, 255);
  leds[13] = CRGB(255, 255, 255);
  leds[14] = CRGB(255, 255, 255);
  leds[15] = CRGB(255, 255, 255);
  leds[16] = CRGB(255, 255, 255);
  leds[17] = CRGB(255, 0,   0);
  leds[18] = CRGB(255, 255, 255);
  leds[19] = CRGB(255, 255, 255);
  leds[20] = CRGB(255, 255, 255);
  leds[21] = CRGB(255, 255, 255);
  leds[22] = CRGB(255, 255, 255);
  leds[23] = CRGB(255, 0,   0);
  leds[24] = CRGB(255, 255, 255);
  leds[25] = CRGB(255, 255, 255);
  leds[26] = CRGB(255, 255, 255);
  leds[27] = CRGB(255, 255, 255);
// -------------------------------------  
  leds[32] = CRGB(255, 255, 255);
  leds[33] = CRGB(255, 0,   0);
  leds[34] = CRGB(255, 255, 255);
  leds[35] = CRGB(255, 255, 255);
  leds[36] = CRGB(255, 255, 255);
  leds[37] = CRGB(255, 255, 255);
  leds[38] = CRGB(255, 255, 255);
  leds[39] = CRGB(255, 0,   0);
  leds[40] = CRGB(255, 255, 255);
  leds[41] = CRGB(255, 255, 255);
  leds[42] = CRGB(255, 255, 255);
  leds[43] = CRGB(255, 255, 255);
  leds[44] = CRGB(255, 255, 255);
  leds[45] = CRGB(255, 0,   0);
  leds[46] = CRGB(255, 255, 255);
  leds[47] = CRGB(255, 255, 255);
  leds[48] = CRGB(255, 255, 255);
  leds[49] = CRGB(255, 255, 255);
  leds[50] = CRGB(255, 255, 255);
  leds[51] = CRGB(255, 0,   0);
  leds[52] = CRGB(255, 255, 255);
  leds[53] = CRGB(255, 255, 255);
  leds[54] = CRGB(255, 255, 255);
  leds[55] = CRGB(255, 255, 255);
  leds[56] = CRGB(255, 255, 255);
  leds[57] = CRGB(255, 0,   0);
  leds[58] = CRGB(255, 255, 255);
  leds[59] = CRGB(255, 255, 255);
  leds[60] = CRGB(255, 255, 255);
  leds[61] = CRGB(255, 255, 255);
  leds[62] = CRGB(255, 255, 255);
  leds[63] = CRGB(255, 0,   0);
  leds[64] = CRGB(255, 255, 255);
  leds[65] = CRGB(255, 255, 255);
  leds[66] = CRGB(255, 255, 255);
  leds[67] = CRGB(255, 255, 255);
  leds[68] = CRGB(255, 255, 255);
  leds[69] = CRGB(255, 0,   0);
  leds[70] = CRGB(255, 255, 255);
  leds[71] = CRGB(255, 255, 255);
  leds[72] = CRGB(255, 255, 255);
  leds[73] = CRGB(255, 255, 255);
  leds[74] = CRGB(255, 255, 255);
  leds[75] = CRGB(255, 0,   0);
  leds[76] = CRGB(255, 255, 255);
  leds[77] = CRGB(255, 255, 255);
  leds[78] = CRGB(255, 255, 255);
  leds[79] = CRGB(255, 255, 255);
  leds[80] = CRGB(255, 255, 255);
  leds[81] = CRGB(255, 0,   0);
  leds[82] = CRGB(255, 255, 255);
  leds[83] = CRGB(255, 255, 255);
  leds[84] = CRGB(255, 255, 255);
  leds[85] = CRGB(255, 255, 255);
  leds[86] = CRGB(255, 255, 255);
  leds[87] = CRGB(255, 0,   0);
// -------------------------------------  
  leds[92]  = CRGB(255, 255, 255);
  leds[93]  = CRGB(255, 255, 255);
  leds[94]  = CRGB(255, 255, 255);
  leds[95]  = CRGB(255, 255, 255);
  leds[96]  = CRGB(255, 255, 255);
  leds[97]  = CRGB(255, 255, 255);
  leds[98]  = CRGB(255, 0,   0);
  leds[99]  = CRGB(255, 255, 255);
  leds[100] = CRGB(255, 255, 255);
  leds[101] = CRGB(255, 255, 255);
  leds[102] = CRGB(255, 255, 255);
  leds[103] = CRGB(255, 255, 255);
  leds[104] = CRGB(255, 0,   0);
  leds[105] = CRGB(255, 255, 255);
  leds[106] = CRGB(255, 255, 255);
  leds[107] = CRGB(255, 255, 255);
  leds[108] = CRGB(255, 255, 255);
  leds[109] = CRGB(255, 255, 255);
  leds[110] = CRGB(255, 0,   0);
  leds[111] = CRGB(255, 255, 255);
  leds[112] = CRGB(255, 255, 255);
  leds[113] = CRGB(255, 255, 255);
  leds[114] = CRGB(255, 255, 255);
  leds[115] = CRGB(255, 255, 255);
  leds[116] = CRGB(255, 0,   0);
  leds[117] = CRGB(255, 255, 255);
  leds[118] = CRGB(255, 255, 255);
  leds[119] = CRGB(255, 255, 255);

Hallo,

Ausnahmebehandlung ist eingebaut. Ein Test wäre nett. Wenn okay ziehe ich mich zurück.
Die fehlende Lib und Objekt bauste noch drum herum.

/*
  Doc_Arduino - german Arduino Forum
  IDE 1.8.13
  avr-gcc 10.2.0
  Arduino Mega2560
  16.11.2020
  License: GNU GPLv3
  https://forum.arduino.cc/index.php?topic=713848.0
  Durchlaufzeit etwas verbessert
  Muster Ausnahmereglung wegen Streifenübergang
*/

const byte NUM_LEDS = 120;
const bool sample [] = {true, true, true, true, true, false};
const byte pinExeption [] = {97};
const byte pinNotUsed [] = {28, 29, 30, 31, 88, 89, 90, 91};


void setup(void)
{
  Serial.begin(115200);
  Serial.println("\nStart");

  for (byte led = 0; led < NUM_LEDS; led++)
  {
      if(isLedUsed(led) )
      {
        Serial.print(led); Serial.print('\t');
        if (exeptionHandling(led) )
        {
          Serial.println("ON");
        }
        else
        {
          if (isLedSampleOn() ) Serial.println("ON");
          else Serial.println("OFF");
        }

        /*
        // das sollte dann bei dir verwendet werden
        if (exeptionHandling(led) )
        {
          leds[led] = CRGB(255, 255, 255);
        }
        else
        {
          if (isLedSampleOn() ) leds[led] = CRGB(255, 255, 255);
          else leds[led] = CRGB(255, 0, 0);
        }
        */
      }
  }
}

void loop(void)
{

}

bool exeptionHandling (const byte led)
{
  const byte MAX = sizeof(pinExeption)/sizeof(pinExeption[0]);
  static byte index = 0;
  bool state = false;
  if (led == pinExeption[index]) state = true;
  index++;
  if (index >= MAX) index = 0;
  return state;
}


bool isLedSampleOn (void)
{
  const byte MAX = sizeof(sample)/sizeof(sample[0]);
  static byte index = 0;
  bool state = false;
  if (sample[index]) state = true;
  index++;
  if (index >= MAX) index = 0;
  return state;
}


bool isLedUsed (const byte led)
{
  const byte MAX = sizeof(pinNotUsed)/sizeof(pinNotUsed[0]);
  static byte index = 0;
  bool state = true;

  // wird insgesamt 8x aufgerufen
  if(led == pinNotUsed[index])
  {
    state = false;
    index++;
    if (index >= MAX) index = 0;
  }  
   
  return state;
}

Hallo,

die LED streifen sind in Reihe geschaltet, wurden am Anfang, in der Mitte (bei der Querstrebe des Aquariums) und am Ende an den kontakten mit einer Spannungsversorgung versehen um eine gleichmäßige Versorgung durch die Stripelänge (120 LED's) zu gewährleisten.

Nun habe ich mal mit meinem Wissen (oder gar Unwissen) das mal so nach meinem "Gutdünken umgesetzt" und folgenden Sketch kompiliert und auf den Arduino Nano geladen.

#include <FastLED.h>

#define LED_PIN 6
#define NUM_LEDS 120
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS 200

CRGB leds[NUM_LEDS];

const bool sample [] = {true, true, true, true, true, false};
const byte pinExeption [] = {97};
const byte pinNotUsed [] = {28, 29, 30, 31, 88, 89, 90, 91};

void setup(void)
{
 LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
 FastLED.setBrightness(BRIGHTNESS);
 FastLED.clear();

 for (byte led = 0; led < NUM_LEDS; led++)
 {
 if (isLedUsed(led) )
 {
 if (exeptionHandling(led) )
 {
 leds[led] = CRGB(255, 255, 255);
 }
 else
 {
 if (isLedSampleOn() ) leds[led] = CRGB(255, 255, 255);
 else leds[led] = CRGB(255, 0, 0);
 }

 }
 }

 FastLED.show();
}

void loop(void)
{

}

bool exeptionHandling (const byte led)
{
 const byte MAX = sizeof(pinExeption) / sizeof(pinExeption[0]);
 static byte index = 0;
 bool state = false;
 if (led == pinExeption[index]) state = true;
 index++;
 if (index >= MAX) index = 0;
 return state;
}


bool isLedSampleOn (void)
{
 const byte MAX = sizeof(sample) / sizeof(sample[0]);
 static byte index = 0;
 bool state = false;
 if (sample[index]) state = true;
 index++;
 if (index >= MAX) index = 0;
 return state;
}


bool isLedUsed (const byte led)
{
 const byte MAX = sizeof(pinNotUsed) / sizeof(pinNotUsed[0]);
 static byte index = 0;
 bool state = true;

 // wird insgesamt 8x aufgerufen
 if (led == pinNotUsed[index])
 {
 state = false;
 index++;
 if (index >= MAX) index = 0;
 }

 return state;
}

Resultat ist, das FAST alle LED's nach dem gewollten Muster (5x Weiß + 1 x Rot) konstant leuchten, OHNE zu rotieren. lediglich ein einzelner 7'er Block (6x weiß + 1x Rot) ist in der gesamten Länge des Stripes vorhanden (siehe Bild, Led Stripe vorne Links bei der Querstrebe).

Danke für die Beschreibung, das macht die Sache anschaulicher.

Ich schreibe Animationen für meine Kellerbar, da gibt es aber derzeit keine Zuschauer. Deshalb ist Dein Hobby momentan weitaus spannender :wink:

sanweb:
... und zum anderen dadurch paar mA einzusparen.

Da habe ich jetzt schlechte Nachrichten (alle Pixel weiß):

  • WS2812B: 120 x 60 mA x 5 V = 36 W
  • WS2815: 120 x 10 mA x 12 V = 14,4 W

Die WS2815 werden mit 12 V versorgt, brauchen 10 mA (gemessen, 15 mA lt. Datenblatt) je Pixel bei weiß, werden sonst aber wie WS2812B angesteuert (BI des ersten Pixels an GND). Da könntest Du mächtig sparen.

Die WS2812B/WS2815 Streifen kann man auftrennen und mit Kabel verbinden, um Strecken zu überbrücken.

sanweb:
... mit Sukulenten bepflanzt ...

In die kann ich mich nicht so recht hineinversetzen, aber möglicherweise mögen sie einen weichen Übergang von Weiß nach Rot und zurück:

// https://forum.arduino.cc/index.php?topic=713848.msg4796217#msg4796217
// Arduino Nano WS2812B Lauflicht FastLED Sketch
#include <FastLED.h>

#define LED_PIN     6
#define NUM_LEDS    120
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS  200
#define LED_GRUPPE 6
CRGB leds[NUM_LEDS];

void setup() {
  LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  FastLED.show();
}

void loop() {
  static byte gb = 0;
  static byte led = 0;
  for (byte j = 0; j < LED_GRUPPE; j++) {
    leds[j] = CRGB(255, 255, 255);
  }
  leds[led] = CRGB(255, gb, gb);
  if (led + 1 < LED_GRUPPE) {
    leds[led + 1] = CRGB(255, 255 - gb, 255 - gb);
  } else {
    leds[0] = CRGB(255, 255 - gb, 255 - gb);
  }
  if (gb < 255) {
    gb++;
  } else {
    gb = 0;
    led + 1 < LED_GRUPPE ? led++ : led = 0;
  }
  for (byte j = LED_GRUPPE; j < NUM_LEDS; j++) {
    leds[j] = leds[j - LED_GRUPPE];
  }
  leds[28] = CRGB(0, 0, 0);
  leds[29] = CRGB(0, 0, 0);
  leds[30] = CRGB(0, 0, 0);
  leds[31] = CRGB(0, 0, 0);
  leds[88] = CRGB(0, 0, 0);
  leds[89] = CRGB(0, 0, 0);
  leds[90] = CRGB(0, 0, 0);
  leds[91] = CRGB(0, 0, 0);
  FastLED.show();
  delay(10);
}

Das menschliche Auge sieht das Rot recht spät, die Wahrnehmung ist nicht linear. Was die
Sukkulenten dazu meinen, weiß ich nicht. Für das menschliche Auge läßt sich das mit einer nichtlinearen math. Funktion optimieren.

Hallo,

sorry, ich bin von deinem Eingangssketch ausgegangen, da sah ich keine Farbänderungen. Zudem ich alles einmalig im setup ausführen lasse, da es sich
a) eh nicht änderte
b) ich meinen seriellen Monitor nicht zumüllen wollte

Du musst das nur in die loop verlagern damit es ständig ausgeführt wird. Du kannst aber deine RGB Werte

CRGB(255, 255, 255);

als Variablen definieren und diese mit jeden Durchlauf oder wie auch immer ändern. Hier bietet sich dann wiederum ein struct an. Du merkst, hier baut sehr schnell Eins auf das Andere auf. Da ich merke das du wirklich noch am Anfang stehst, möchte ich dich jedoch nicht gleich überfordern. Das braucht alles sein Zeit. :slight_smile:

Hallo,

agmue:

// https://forum.arduino.cc/index.php?topic=713848.msg4796217#msg4796217

// Arduino Nano WS2812B Lauflicht FastLED Sketch
#include <FastLED.h>

#define LED_PIN     6
#define NUM_LEDS    120
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS  200
#define LED_GRUPPE 6
CRGB leds[NUM_LEDS];

void setup() {
 LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
 FastLED.setBrightness(BRIGHTNESS);
 FastLED.clear();
 FastLED.show();
}

void loop() {
 static byte gb = 0;
 static byte led = 0;
 for (byte j = 0; j < LED_GRUPPE; j++) {
   leds[j] = CRGB(255, 255, 255);
 }
 leds[led] = CRGB(255, gb, gb);
 if (led + 1 < LED_GRUPPE) {
   leds[led + 1] = CRGB(255, 255 - gb, 255 - gb);
 } else {
   leds[0] = CRGB(255, 255 - gb, 255 - gb);
 }
 if (gb < 255) {
   gb++;
 } else {
   gb = 0;
   led + 1 < LED_GRUPPE ? led++ : led = 0;
 }
 for (byte j = LED_GRUPPE; j < NUM_LEDS; j++) {
   leds[j] = leds[j - LED_GRUPPE];
 }
 leds[28] = CRGB(0, 0, 0);
 leds[29] = CRGB(0, 0, 0);
 leds[30] = CRGB(0, 0, 0);
 leds[31] = CRGB(0, 0, 0);
 leds[88] = CRGB(0, 0, 0);
 leds[89] = CRGB(0, 0, 0);
 leds[90] = CRGB(0, 0, 0);
 leds[91] = CRGB(0, 0, 0);
 FastLED.show();
 delay(10);
}

funktioniert auch sehr gut und die Abstände passen alle wie in der vordefinierten Anzahl einer Gruppegröße.

Der Übergang ist optisch gesehen weich und langsam (egal wie man nun am delay dreht), so das sich das Farbspektrum permanent zusätzlich zur normal gewollten Rotation der LED's am rotieren ist. Ob die Pflanze das rotierende Farbspektrum mögen, wird sich in ein paar Wochen zeigen.

Die bisher gemachte Erfahrung mit dem Nano Becken war, das die Pflanzen bei permanetem Weißlicht nicht so zügig wachsen, als wenn man einen Rotanteil daugibt. Das kleine Becken hatte nur 14 LED's (davon waren 10 Weiße Leds und je zwei zuschaltbare Rote und Blaue LED's) wovon 10 Weiße genutzt wurden und 2 rote dazugeschaltet wurden. Seit 3 Monaten sitzen die Pflanzen da drin und ich muss die Sukulenten darin schon "ausdünnen", weil sie so gut gedeihen, als wenn nur weißes Licht einschalte.

Die gruppierung finde ich natürlich als sehr interessanten Ansatz, da man somit später durch die einfache Änderung der Zahl die Grupenngröße variabel anpassen kann.

Was ich nicht so verstehe ist der Teil mit dem "soften" Übergang:

  for (byte j = 0; j < LED_GRUPPE; j++) {
    leds[j] = CRGB(255, 255, 255);
  }

Damit schreibst Du die Anzahl der benötigten weißen LED's in ein Array, sofern ich das richtig verstanden habe ...

Dem Array folgt eine einzelne rote LED mit:

 leds[led] = CRGB(255, gb, gb);

Damit wäre die gewünschte Gruppegröße komplett. Mit folgendem Code

if (led + 1 < LED_GRUPPE) {
    leds[led + 1] = CRGB(255, 255 - gb, 255 - gb);
  } else {
    leds[0] = CRGB(255, 255 - gb, 255 - gb);
  }

  
  if (gb < 255) {
    gb++;
  } else {
    gb = 0;
    led + 1 < LED_GRUPPE ? led++ : led = 0;
  }

erzeugst du den weichen Übergang, wie auch immer das funktionieren mag, da mir aktuell die CRGB Struktur Referenz von FastLED bömische Dörfer sind und ich auch aus der Online referenz nicht so ganz schlau werde.

Mit dem Code:

  for (byte j = LED_GRUPPE; j < NUM_LEDS; j++) {
    leds[j] = leds[j - LED_GRUPPE];
  }

schiebst Du die die vorher definierte Gruppe nun stets eine LED weiter und mit

  leds[28] = CRGB(0, 0, 0);
  leds[29] = CRGB(0, 0, 0);
  leds[30] = CRGB(0, 0, 0);
  leds[31] = CRGB(0, 0, 0);
  leds[88] = CRGB(0, 0, 0);
  leds[89] = CRGB(0, 0, 0);
  leds[90] = CRGB(0, 0, 0);
  leds[91] = CRGB(0, 0, 0);

definierst Du die zu übergehenden LED's wegen der Querstrebe ...

Öhem, hab ich das so bisher halbwegs richtig interpretiert und verstanden? Jetzt bitte Keulen raus und druf kloppen bitte ... :smiley: :smiley:

sanweb:
Jetzt bitte Keulen raus und druf kloppen bitte ... :smiley: :smiley:

Das ist meine Lieblingsbeschäftigung, hier aber nicht nötig, wie schade :grin:

Die Variable gb (grün blau) gibt den Grün-Blau-Anteil eines Pixels an, und verändert sich von 0 bis 255. In die umgekehrte Richtung dann 255-gb.

Die Berechnung berücksichtigt nicht die Lücken, weshalb es zu einer kleinen Ungewichtigkeit des Rotanteils kommen kann. Das dürfte den Pflanzen aber egal sein.

Ha, dann hab ich doch keinen Sehschaden trotz Brille, hatte den Eindruck, das ich teilweise einen sehr leichten grün/gelben Schimmer erkenne und zweifelte erst einmal an meiner Sehfähigkeit ... :smiley: :smiley:

Lässt sich das nun noch merklich beschleunigen, da es doch bissel langsam ist trotz mittlerweile entferntem delay ...

sanweb:
Lässt sich das nun noch merklich beschleunigen, da es doch bissel langsam ist trotz mittlerweile entferntem delay ...

Du kannst gb++; durch gb+=5; ersetzen.

Sind denn Sukkulenten Disco-Pflanzen? Ich hätte eher erwartet, die wollen das langsamer.