LEDs ansteuern mit FastLED

Hey ,

bin noch ein Neuling was Arduino-Programmierung angeht, habe aber eine schöne Geschenkidee für meine Schwester gefunden und wollte das mal nachbasteln.
Das Projekt ist von Nerdforge ([Making a Whimsical LANTERN (with Realistic Fire Effect)! - YouTube]).
Den Code habe ich von ihm kopiert und meine Daten in dem Code geändert.
Ich habe einen WS2812B LED-Streifen und einen Arduino Nano wie auch im Video.

Jetzt kommen wir zu meinem Problem, das kompilieren und hochladen funktioniert ohne Probleme, aber es leuchten nur die ersten drei LEDs auf allen Streifen.
Hier ein Bild


Der Feuereffekt und das Ändern der Farbe funktioniert einwandfrei.
Ich hab mich jetzt mehrere Tage mit dem Code beschäftigt finde den Fehler aber leider nicht.
Hier ist der Code

#include <FastLED.h>

/* Leds per addressable section. Normally this is 1, for me it was 3 */
#define LEDS_PER_SECTION 13

/* If LEDS_PER_SECTION is 1, the number of sections is your amount of LEDs */
#define SECTIONS 5

/* LED PIN */
#define DATA_PIN 6

/* BUTTON PIN for changing colors */
#define BUTTON_PIN 2

#define NUM_LEDS LEDS_PER_SECTION*SECTIONS
CRGB leds[NUM_LEDS];


CRGB colorsFire[] = {CRGB(255, 120, 3), CRGB(255, 80, 0), CRGB(255, 65, 0)};
CRGB colorsPurple[] = {CRGB(220, 120, 255), CRGB(170, 0, 255), CRGB(225, 0, 255)};
CRGB colorsGreen[] = {CRGB(50, 255, 5), CRGB(55, 255, 0), CRGB(140, 255, 0)};
CRGB colorsTeal[] = {CRGB(50, 255, 60), CRGB(0, 255, 90), CRGB(10, 255, 120)};
CRGB colorsBlue[] = {CRGB(50, 140, 140), CRGB(30, 200, 200), CRGB(20, 160, 255)};
CRGB colorsRed[] = {CRGB(120, 20, 0), CRGB(150, 0, 0), CRGB(255, 0, 0)};
CRGB colorsPink[] = {CRGB(255, 110, 120), CRGB(255, 0, 150), CRGB(255, 0, 70)};
CRGB colorsWhite[] = {CRGB(255, 255, 100), CRGB(200, 200, 60), CRGB(150, 150, 40)};
CRGB *colors[] = {colorsFire, colorsPurple, colorsGreen, colorsTeal, colorsBlue, colorsRed, colorsPink, colorsWhite};

/* Updates at 60hz */
float tickCount = 1000/60;

class LedSegment {
  private:
  int fadeSpeed, ledIndex;
  long lastFade, fadeTimeRemaining;
  bool fading;
  float fadeVector[3];
  CRGB currentColor;
  public:
  LedSegment(int idx, int f_speed) {
    fadeSpeed = f_speed;
    ledIndex = idx;
  }
  
  void setColor(CRGB color) {
    leds[ledIndex] = color;
    currentColor = color;
    fading = true;
    fadeVector[0] = (float)color.r / (float)fadeSpeed;
    fadeVector[1] = (float)color.g / (float)fadeSpeed;
    fadeVector[2] = (float)color.b / (float)fadeSpeed;
    lastFade = millis();
    fadeTimeRemaining = fadeSpeed;
  }

  
  void fade() {
    if (fading) {
      long millisSinceLast = millis() - lastFade;
      lastFade = millis();
      long fadeMultiplier = (millisSinceLast >= fadeTimeRemaining) ? fadeTimeRemaining : millisSinceLast;
      fadeTimeRemaining = max(fadeTimeRemaining - millisSinceLast, 0);
      currentColor = CRGB(
        currentColor.r - min(fadeVector[0] * fadeMultiplier, currentColor.r), 
        currentColor.g - min(fadeVector[1] * fadeMultiplier, currentColor.g),
        currentColor.b - min(fadeVector[2] * fadeMultiplier, currentColor.b)
      );        
      if (fadeTimeRemaining == 0)
        fading = false;
      leds[ledIndex] = currentColor;
    }
  }
  
};


class ColorRow {
  public:
  unsigned long last_check;
  LedSegment* myLeds[3];
  CRGB colors[3];
  
  ColorRow(int idx1, int idx2, int idx3, CRGB colorset[3]) {
    int fadeTime = random(500, 3000);
    updateColors(colorset);
    myLeds[0] = new LedSegment(idx1, fadeTime);
    myLeds[1] = new LedSegment(idx2, fadeTime);
    myLeds[2] = new LedSegment(idx3, fadeTime);
    last_check = millis();
    
  }

  void updateColors(CRGB colorset[3]) {
    colors[0] = colorset[0];
    colors[1] = colorset[1];
    colors[2] = colorset[2];
  }
  
  void updateLeds() {
    for (int i = 0; i < 3; i++) {
      myLeds[i]->fade();
    }
  }
  void setTop() {
    myLeds[2]->setColor(colors[2]);
  }
  void setMid() {
    myLeds[1]->setColor(colors[1]);
  }
  void setBase() {
    myLeds[0]->setColor(colors[0]);
  }
  
  void fire() {
    int i = random(0, 0.5 * 60);
    switch (i) {
      case 1:
        setTop();
        setBase();
        setMid();
        break;
      case 2:
      case 3:
        setBase();
        setMid();
        break;
      case 4:
      case 5:
        setBase();
      
    }
  }
  void tick() {
    if (millis() - last_check > tickCount) {
      last_check = millis();
      fire();     
      FastLED.show();

    }

    updateLeds();

  }
};

ColorRow* first;
ColorRow* second;
ColorRow* third;
ColorRow* fourth;
ColorRow* fifth;
ColorRow* sixth;
ColorRow* allRows[SECTIONS];
int currentColor = 0;
CRGB* colorset = colors[currentColor];


void rowsTick() {
    for (int i = 0; i < SECTIONS; i++)
    {
      allRows[i]->tick();
    }
}


void setColor() {
    for (int i = 0; i < SECTIONS; i++)
    {
      allRows[i]->updateColors(colors[currentColor]);
    }
}

void setup() { 
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  Serial.begin(9600);
  bool rising = true;
  int idx = 0;
  for (int i = 0; i < SECTIONS; i++)
  {
      /* This part here is here because I have soldered the led rows from top
         to the top of the next, then from the bottom to the bottom of the next, so the
         index of which led is at the "top" will be alternate each round
       */
      int idx = LEDS_PER_SECTION * i;
      if (rising) {
        allRows[i] = new ColorRow(idx, idx + 1, idx + 2, colorset);
      }
      else {
        allRows[i] = new ColorRow(idx + 2, idx + 1, idx, colorset);
      }
      rising = !rising;
  }
  pinMode(BUTTON_PIN, INPUT_PULLUP);

}

int buttonState = 0;
int state = 0;

void loop() {
  rowsTick();
  int buttonState = digitalRead(BUTTON_PIN);
  if (buttonState != state) {
    state = buttonState;
    if (state == 0) {
         currentColor = (currentColor + 1) % (sizeof(colors)/sizeof(CRGB*));
         colorset = colors[currentColor];
         setColor();
    }
  }

  delay(5);
}

Hoffe ihr könnt mir weiterhelfen.

Gruß Yannik

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Hm...

Könnte es sein, das Du 5 Sectionen auf einem Stripe abbilden willst, aber nur die erste beschreibst?
Was passiert, wenn Du SECTIONS auf 1 stellst? Alternativ LEDS_PER_SECTION auf 3.
(Ich habe den Code noch nicht durchgesehen - mit fastled bin ich noch nicht so bei...)

Wenn ich Sections auf 1 stelle leuchten auf dem ersten Streifen die ersten 3 LEDs und wenn ich LEDS_PER_SECTIONS auf 3 stelle und die Sections auf 5 leuchten die ersten 15 LEDs.
Bei Sections 1 und LEDS_PER_SECTIONS 3 leuchten auch nur die ersten 3 auf dem ersten Streifen.

Gruß Yannik

Hier gibt es eine magische Nummer:

LedSegment* myLeds[3];

Es ändert sich dadurch leider nichts es leuchten nach wie vor die ersten 3 LEDs von allen Streifen.

Und was kommt da raus?

/* Leds per addressable section. Normally this is 1, for me it was 3 */
#define LEDS_PER_SECTION 5

/* If LEDS_PER_SECTION is 1, the number of sections is your amount of LEDs */
#define SECTIONS 13

Du hast 65 LEDs die hier zusammen gezählt werden:

#define NUM_LEDS LEDS_PER_SECTION*SECTIONS
CRGB leds[NUM_LEDS];

Wenn du LEDS_PER_SECTION auf 1 machst muss SECTIONS auf 65 damit alle LEDs da sind ( leds[NUM_LEDS])

oder so

Wenn ich das so eingebe bleiben alle LEDs dunkel.

DATEI - BEISPIELE - FASTLED - blink

Anzupassen sind die Anzahl der LED, die PIN CLK und DATA.
Die aktive Zeile FastLED.addLeds .... ist auszukommentieren und die Zeile 34 müste die richtige mit den WS2812 sein; Wenn es nicht WS2812b sind.

Den Code hochladen und es sollte sich auf allen Pixeln was tun.

Auch mit LEDS_PER_SECTION 1 und SECTIONS 65?

Das musste ich erstmal durchscrollen..
Ich habs mir in die IDE kopiert und nen STRG-T drauf gemacht. Und dann fällt auf, das da ne class hinter LedSegment steckt.
Da ist ein Pointer gesetzt. Die 3 dürften den RGB abdecken.

Zumindest kompiliert es durch.
Nu kommt es blos drauf an, was da an Stripe verbaut und wie angeschlossen ist... Aber blinken sollte es schon.

Die Anzahl der LED und die verwendeten Pins zum ansteuern passt alles blinken tut es auch aber nur die ersten 3 LED auf allen Streifen, wie mehr oder weniger auf dem einen Bild zu erkennen ist.

Wenn ich das aus kommentiere blinkt nichts mehr.
Ich hab einen WS2812B LED-Streifen

Da der Blink-Sketch die erste LED ansteuert, frag ich mich grad wieso 3 angehen...

Das ist richtig.
Dann musst Du die Zeile:

    // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical

aktivieren.

EDIT:
Nimm mal diesen Sketch und las den mal laufen (DATA_PIN anpassen!):


#include <FastLED.h>
const byte NUM_LEDS=65;

// For led chips like WS2812, 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
// Clock pin only needed for SPI based chipsets when not using hardware SPI
#define DATA_PIN 3
#define CLOCK_PIN 13

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

void setup()
{
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
}

void loop()
{
  // Turn the LED on, then pause
  for (byte b = 0; b < NUM_LEDS; b++)
  {
    leds[b] = CRGB::Red;
    FastLED.show();
    delay(500);
    // Now turn the LED off, then pause
    leds[b] = CRGB::Black;
    FastLED.show();
    delay(500);
  }
}

Wenn ich den Sketch draufspiele blinken alle 65 LEDs nacheinander auf.

Ok. Wenn immer nur eine leuchtet, dann sind wir safe.
Wenn die auch noch rot aufblinken, dann musst Du in Deinem setup() schon mal die Farbreihenfolge ändern:

  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical

Wenn Du Deinen Sketch hochlädst, muss zum Start irgendwas passieren. Weil es wird erstmal die Richtung bestimmt.

Die LEDs leuchten Grün und beim Start von meinem Sketch fangen die LEDs von vorne an zu leuchten so wie bei dem Blink-Sketch auch.
Wenn ich beim Blink-Sketch die Farbreihenfolge von RGB zu GRB ändere dann leuchtet er auch rot wie im Sketch gewollt.

OK. Dann ist Deine Farbreihenfolge die richtige.

Damit muss irgendwo im Code was faul sein.

Aber da bin ich leider raus.

Trotzdem danke, dann werde ich den Code nochmal komplett auseinandernehmen.

Meine Hoffnungen ruhten auf Deinen Schultern!

Die Aussagen von Yannik kann ich bestätigen, mein (unzerschnittener) Streifen tut dasselbe.

Ich habe keine Geduld für Videos, mich würde der originale Code interessieren.

Damit siehst Du, daß die blau leuchtenden Pixel später im Programm nicht erreicht werden:

void setup() { 
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  for (int j=0;j<NUM_LEDS;j++)
  {
    leds[j] = CRGB::Blue;
  }
  FastLED.show();
  delay(2000);
...

Hat er unterm Video auf Github verlinkt.
https://github.com/hansjny/Natural-Nerd/blob/master/arduino/lantern_torch.ino