NeoPixel einzelne Pixel dimmen

Eigentlich wollte ich das hier an meinen bestehenden Thread hängen, aber da ich im Internet sehr wenig über dieses spezielle Problem gefunden habe, dachte ich, dass es so besser gefunden werden kann.

Ich versuche momentan für ein LED Strip Lauflicht einen “Schweif” zu erzeugen.

Bspl.: laufender balken hat 10 Leds, der Scheif soll auch 10 LEDs lang sein.
Dabei soll die aktuelle Farbe pro Pixel um 1/10 gedimmt werden.

Da es keine feste Farbe ist, sonder die Farbe geändert werden kann, muss ich die gedimmte Farbe für jeden Pixel neu berechnen.

Ich habe bis jetzt das hier. bei einzelnen Farben funktioniert es aber bei Fade oder Color Flow flasht der Balken nur.

pickColor(colrType);                                                        // Get Color for strip
cycle();
void Cycle(){
  uint16_t i, j, k;
  thisMillis=millis();
  if(thisMillis - prevMillisCYCLE >= intervalCYCLE){
    for(i = 0; i< strip.numPixels(); i++){                                              // all pixel off
      strip.setPixelColor(i, 0, 0, 0);
    }

    if(colrType == 7){                                                                          //Switch Case Rainbow!
       for(j = 0; j < ((strip.numPixels()/10)+1); j++){  
         strip.setPixelColor(pixelPos-j, Wheel2(((i * 256 / strip.numPixels()) + j) & 255));
       }
       for(k = 0; k <= ((strip.numPixels()/10)+1); k++){                                  // draw tail
         pixelColor = colorDimm(pixelColor, ((strip.numPixels()/10)+1), k+1);
         strip.setPixelColor(pixelPos-((strip.numPixels()/10)+1)-k, Wheel2(((i * 256 / strip.numPixels()) + j) & 255));
       }
    }
    else{
      for(j = 0; j < ((strip.numPixels()/10)+1); j++){                                    // draw bar
        strip.setPixelColor(pixelPos-j, pixelColor);
      }
      for(k = 0; k <= ((strip.numPixels()/10)+1); k++) {                                  // draw tail
        pixelColor = colorDimm(pixelColor, ((strip.numPixels()/10)+1), k+1);
        strip.setPixelColor(pixelPos-((strip.numPixels()/10)+1)-k, pixelColor);
      }
    }
    strip.show();
    pixelPos++;                                                                             // shift pixel 
    if(pixelPos == PIXEL_COUNT+(strip.numPixels()/15)+1)                                    // reset pixel position (running a vew frames out of the strip)
      pixelPos = 0;
      
    prevMillisCYCLE = thisMillis;
  }
}
uint32_t colorDimm(uint32_t colorValue, long lenght, long pixel){

  uint8_t red = (colorValue & 0x00FF0000) >> 16;
  uint8_t green = (colorValue & 0x0000FF00) >> 8;
  uint8_t blue = (colorValue & 0x000000FF);

  double prozent = 100 / lenght;

  red = red - red * ((prozent * pixel) / 100);
  green = green - green * ((prozent * pixel) / 100);
  blue = blue - blue * ((prozent * pixel) / 100);

  colorValue = strip.Color(red,green,blue);

  return colorValue;
}
void pickColor(int c) {                                   
  switch(c){
    
    case 0: {                                                      // RED
      pixelColor = strip.Color(255, 0, 0);                         
    }
      break;
      
    case 1: {                                                      // GREEN
      pixelColor = strip.Color(0, 255, 0);                         
    }
      break;
      
    case 2: {                                                      // BLUE
      pixelColor = strip.Color(0, 0, 255);                         
    }
      break;
      
    case 3: {                                                      // WHITE
      pixelColor = strip.Color(255, 255, 255);                     
    }
      break;
    case 4: {                                                      // FADE IN/OUT SINGLE COLOR  
      thisMillisFade=millis();
      if(thisMillisFade - prevMillisFade >= intervalFadeIO){                         
        FadeInOut(255, 0, 0);                                      
        if(fade == 512){
          fade = 0;
        }
        prevMillisFade = thisMillisFade;  
      }
    }
      break;
      
    case 5: {                                                      // FADE IN/OUT
      thisMillisFadeIO=millis();
      if(thisMillisFadeIO - prevMillisFadeIO >= intervalFadeIO){
        FadeColors(fadeColor);
        FadeInOut(fadeR, fadeG, fadeB);                                      
        if(fade == 512){
          fade = 0;
          fadeColor++;
        }
        if(fadeColor > 5)                                          // Begrenzung der wechselnden Farben im Switch Case von FadeColors()!
          fadeColor = 0;
            
        prevMillisFadeIO = thisMillisFadeIO;  
      }  
    }
      break;
      
    case 6: {                                                     // COLOR FADE
      thisMillisCFlow=millis();
      if(thisMillisCFlow - prevMillisCFlow >= intervalCFlow){
        Wheel(color);                                                
        color++;
        prevMillisCFlow = thisMillisCFlow;
      }
    }
      break;
      
    case 7: {                                                      // RAINBOW
      thisMillisRainbow=millis();
      if(thisMillisRainbow - prevMillisRainbow >= intervalRainbow){
        if(j < 256){                                               
          j++;
        }
        else
          j = 0;
        prevMillisRainbow = thisMillisRainbow;
      }
    }
      break;
      
    case 8: {                                                      // Black/off
      pixelColor = strip.Color(0, 0, 0);                           
    }
      break;
  }
}

Wenn ich Dich rchtig verstanden habe, macht das Muster sinelon des Beispiels DemoReel100.ino der Bibliothek FastLED sowas. Möglicherweise kannst Du da eine Anregung finden.

Ich habe ein Foto versucht. In Real sieht es besser aus, da muß ich noch üben:
Schweif.png

Der Trick mit dem Schweif ist der, dass man ein klassisches Lauflicht programmiert - aber das alte Frame nicht löscht, sondern die RGB Werte jeder einzelnen LED nur ein bisschen runterdimmt.

Mit FastLED macht man das z.B. mit

fadeToBlackBy (CRGB *leds, uint16_t num_leds, uint8_t fadeBy)

was seinerseits scale8 benutzt.

beatsin8() kann man für die Positionskontrolle nehmen.

Sind also mit FastLED exakt 3 Zeilen Code im Loop, um den von Dir gewünschten Effekt zu erzeugen.

Gruß,

Helmuth

P.S. Es gibt keinen mir bekannten rationalen Grund, die Adafruit Library zu benutzen...

@agmue: Danke für den Tipp, ja genau so soll es aussehen. Bei einzelnen Farben tut es das auch, nur wenn der Schweif bzw. das ganze Lauflicht als ClorFlow dargestellt werden soll, also wäredn des Laufens die RGB Farben durchfaden oder wärend des Laufens ein Rainbow Effekt durch den Balken läuft klappt es bei mir halt nicht.

Danke Helmuth. Da hier scheinbar alle außer mir FastLED bentzen, werde ich mein ganzes Prog wohl auch mal umwerfen und auf FastLED umsteigen :)

Okay, das wird ein fettes Stück arbeit… :fearful:

Ich fange jetzt an alle Modes zu ersetzen.
Das Timing und die Schleifen sollten ja beibehalten werden können.

Es fängt schon mit der einfachen Füllung des Strips an :-/

Um diese farblich variabel zu gestalten, wird die Farbe in einem Switch Case geändert und bei jedem Funktionsaufruf neu abgefragt.
Wie übergebe bzw. änder ich die Farbe denn bei FastLED?

Kann ich den 32bit int “colorValue” übernehmen?

Gibt es eine Befehlsübersicht aller FastLED befehle?
Ich habe im Netz keine gefunden.

Liebe Grüße

PART1:

#include <FastLED.h>

// Digital IO pin buttons----------------------------------------------------------------------
#define BTN01_PIN   3  // This will be
#define BTN02_PIN   5  // driven with a pull-up resistor so the switch should
                      // pull the pin to ground momentarily.  On a high -> low
                      // transition the button press logic will execute.
//---------------------------------------------------------------------------------------------
// Digital IO pin NeoPixels--------------------------------------------------------------------
#define PIXEL_PIN    6  // BOTTOM STRIP

// LED Anzahl
#define NUM_LEDS  92

//VU METER-------------------------------------------------------------------------------------
#define MIC_PIN   A5  // Microphone is attached to this analog pin
#define DC_OFFSET  0  // DC offset in mic signal - if unusure, leave 0
#define NOISE     40  // Noise/hum/interference in mic signal
#define SAMPLES   60  // Length of buffer for dynamic level adjustment
#define TOP       NUM_LEDS // Allow dot to go slightly off scale <- NOT
#define PEAK_FALL 10  // Rate of peak falling dot
//---------------------------------------------------------------------------------------------
//NEO PIXELS-----------------------------------------------------------------------------------
CRGB leds[NUM_LEDS];
//---------------------------------------------------------------------------------------------

//VARIABLES------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------

//TIMING---------------------------------------------------------------------------------------
unsigned long 
currentMillis = 0,
thisMillis = 0,

thisMillisFade = 0,
thisMillisRainbow = 0,
thisMillisFadeIO = 0,
thisMillisCFlow = 0,

prevMillisFade = 0,
prevMillisRainbow = 0,
prevMillisFadeIO = 0,
prevMillisCFlow = 0,

prevMillisCYCLE = 0,
prevMillisCYLONDUAL = 0,
prevMillisFLASH = 0,
prevMillisFLASHPause = 0,
prevMillisSTROBE = 0,
prevMillisSTROBEPause = 0,
prevMillisEMERG = 0,
prevMillisEMERGPause = 0;


long intervalFadeIO = 50;                          // In Out Fade Speed
long intervalCFlow = 250;                           // Color Flow Speed
long intervalRainbow = 30;                         // Rainbow Speed
//---------------------------------------------------------------------------------------------

int modeType = 0;
int colrType = 0;

int pixelPos = 0;

bool oldState01 = HIGH;
bool oldState02 = HIGH;

uint32_t pixelColor = CRGB(0, 0, 0);
byte color = 0;

//FADE COLOR-----------------------------------------------------------------------------------
int fade = 0;
byte fadeColor = 0;

byte fadeR = 0;
byte fadeG = 0;
byte fadeB = 0;
//---------------------------------------------------------------------------------------------

//CYCLE MODE-----------------------------------------------------------------------------------
long intervalCYCLE = 30;                           // Cycle interval
//---------------------------------------------------------------------------------------------
//CYLON DUAL MODE------------------------------------------------------------------------------
long intervalCYLONDUAL = 30;                       // Cycle interval
//---------------------------------------------------------------------------------------------
//FLASH MODE----------------------------------------------------------------------------------
bool flash = 1;                    
byte flashCount = 0; 

byte flashes = 3;                   // Amount of flashes
long intervalFLASH = 50;            // Flash interval   
//---------------------------------------------------------------------------------------------
//STROBE MODE----------------------------------------------------------------------------------                    
long intervalSTROBE = 80;                  // Strobe interval      
//---------------------------------------------------------------------------------------------
//VU-METER-------------------------------------------------------------------------------------
byte
  peak      = 0,      // Used for falling dot
  peakSize  = 2,      // Size of peak bar
  dotCount  = 0,      // Frame counter for delaying dot-falling speed
  volCount  = 0;      // Frame counter for storing past volume data
int
  vol[SAMPLES],       // Collection of prior volume samples
  lvl       = 10,      // Current "dampened" audio level standard 10
  minLvlAvg = 0,      // For dynamic adjustment of graph low & high
  maxLvlAvg = 512;    //512 standard
uint32_t 
  vuColors[NUM_LEDS] = {0};
//---------------------------------------------------------------------------------------------
//EMERG----------------------------------------------------------------------------------------
bool side = 0;
bool emergFlash = 1;                    
byte emergFlashCount = 0; 

byte emergFlashes = 3;                   // Amount of strobes
long intervalEMERG = 80;                  // Strobe interval  
//---------------------------------------------------------------------------------------------

//FUNCTIONS------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
void colorWipe(int strip, int color[]);
int pickcolor(int c);
void Wheel(byte WheelPos);

uint16_t j = 0; 

void setup() {
  FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, NUM_LEDS);

  pinMode(BTN01_PIN, INPUT_PULLUP);
  pinMode(BTN02_PIN, INPUT_PULLUP);
  //Serial.begin(9600);
  //Serial.begin(250000);

  analogReference(INTERNAL);
  memset(vol, 0, sizeof(vol));                                         // Initializing array
  
  FastLED.show();
}

void loop() {
 
  //Serial.print("  |  MODE: ");
  //Serial.print(modeType);

  //Serial.print("  |  COLR: ");
  //Serial.print(colrType);

  //Serial.print("  |  FARBCODE: ");
  //Serial.print(pixelColor);

  //Serial.print("  |  MIC IN: ");
  //Serial.print(analogRead(MIC_PIN));

  //Serial.print("  |  PEAK: ");
  //Serial.println(peak);



  bool newState01 = digitalRead(BTN01_PIN);
  bool newState02 = digitalRead(BTN02_PIN);

  // Check if state changed from high to low (button press).
  if (newState01 == LOW && oldState01 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState01 = digitalRead(BTN01_PIN);
    if (newState01 == LOW) {
      colrType++;
      pixelPos = 0;
      if (colrType > 8)                                                      // Color overflow
        colrType=0;
    }
  }

  // Set the last button state to the old state.
  oldState01 = newState01;
  
  // Check if state changed from high to low (button press).
  if (newState02 == LOW && oldState02 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState02 = digitalRead(BTN02_PIN);
    if (newState02 == LOW) {
      modeType++;
      pixelPos = 0;
      if (modeType > 6)                                                       // Mode overflow
        modeType=0;
    }
  }
  
  // Set the last button state to the old state.
  oldState02 = newState02;
  
    
  //pickColor(colrType);                                                        // Get Color for strip
  startShow(modeType);                                                        // Start strip with selected Mode

}
void pickColor(int c) {                                   
  switch(c){
    
    case 0: {                                                      // RED
      CRGB(255, 0, 0);                         
    }
      break;
      
    case 1: {                                                      // GREEN
      CRGB(0, 255, 0);                         
    }
      break;
      
    case 2: {                                                      // BLUE
      CRGB(0, 0, 255);                         
    }
      break;
      
    case 3: {                                                      // WHITE
      CRGB(255, 255, 255);                     
    }
      break;
    case 4: {                                                      // FADE IN/OUT SINGLE COLOR  
      thisMillisFade=millis();
      if(thisMillisFade - prevMillisFade >= intervalFadeIO){                         
//        FadeInOut(255, 0, 0);                                      
        if(fade == 512){
          fade = 0;
        }
        prevMillisFade = thisMillisFade;  
      }
    }
      break;
      
    case 5: {                                                      // FADE IN/OUT
      thisMillisFadeIO=millis();
      if(thisMillisFadeIO - prevMillisFadeIO >= intervalFadeIO){
 //       FadeColors(fadeColor);
//        FadeInOut(fadeR, fadeG, fadeB);                                      
        if(fade == 512){
          fade = 0;
          fadeColor++;
        }
        if(fadeColor > 5)                                          // Begrenzung der wechselnden Farben im Switch Case von FadeColors()!
          fadeColor = 0;
            
        prevMillisFadeIO = thisMillisFadeIO;  
      }  
    }
      break;
      
    case 6: {                                                     // COLOR FADE
      thisMillisCFlow=millis();
      if(thisMillisCFlow - prevMillisCFlow >= intervalCFlow){
        Wheel(color);                                                
        color++;
        prevMillisCFlow = thisMillisCFlow;
      }
    }
      break;
      
    case 7: {                                                      // RAINBOW
      thisMillisRainbow=millis();
      if(thisMillisRainbow - prevMillisRainbow >= intervalRainbow){
        if(j < 256){                                               
          j++;
        }
        else
          j = 0;
        prevMillisRainbow = thisMillisRainbow;
      }
    }
      break;
      
    case 8: {                                                      // Black/off
      CRGB(0, 0, 0);                           
    }
      break;
  }
} 

void FadeColors(int c){
  switch(c){
    case 0:{                          //RED
      fadeR = 255;                    
      fadeG = 0;
      fadeB = 0;
    }
      break;
    case 1:{                          //GREEN
      fadeR = 0;                      
      fadeG = 255;
      fadeB = 0;
    }
      break;
    case 2:{                          //BLUE    
      fadeR = 0;
      fadeG = 0;
      fadeB = 255;
    }
      break;
    case 3:{                          //ORANGE
      fadeR = 254;
      fadeG = 80;
      fadeB = 0;
    }
      break;
    case 4:{                          //CRYSTAL
      fadeR = 43;
      fadeG = 255;
      fadeB = 241;
    }
      break; 
    case 5:{                          //LIME
      fadeR = 191;
      fadeG = 255;
      fadeB = 0;
    }
      break;
         
  }
}


//Modes to be implemented:
//  - colorWipe                                           CHECK!
//  - Cycle (all around)                                  *
//  - cylonDual (parallel Up and Down)                    *
//  - cylonBi (parallel bidirectional)
//  - Strobe
//  - SoundBar (Equalizer over Microphone)                *
//  - Police (Flashing red and blue

void startShow(int mode) {
  switch(mode){
    case 0: {                                             // Fill whole strip with color
      colorWipe();
    }
            break;
    case 1: {                                             // Bar running in cycles through strip
//      Cycle();
    }
            break;
    case 2: {
//      cylonDual();                                        // Bar running parallel up and down
    }
            break;

    case 3:{
//      Flash();                                           // Full bar flashing
    }
            break; 

    case 4:{
//      Strobe();                                           // Full bar flashing
    }
            break;
            
    case 5: {                                             // Colored VU-Meter raising parallel by external sound
//      VUmeter();
    }
            break;

    case 6: {                                             // Switching flashes
//      EMERG();
    }
            break;
  }
}

// MODE 01 COLOR WIPE - FILL LEDS ONE AFTER THE OTHER-----------------------------------------------------------------------------------------------------------------
void colorWipe() {
  uint16_t i;
    if(colrType == 7){                                                                          //Switch Case Rainbow!
        for(i=0; i< NUM_LEDS; i++) {
//          strip.setPixelColor(i, Wheel2(((i * 256 / strip.numPixels()) + j) & 255));
        }
    }
    else{
      for(i=0; i<NUM_LEDS; i++) {
        leds[i].setRGB(pickColor(colrType));
      }
    }
    FastLED.show();
}

Kann ich den 32bit int "colorValue" übernehmen?

Das ist bei beiden libs ein uint8_t, also ein Byte ohne Vorzeichen.

Bei FastLED benutzt du das HSV Farbmodell z.B. mit

leds[i] = CHSV(Farbe, Sättigung, Helligkeit);

Es sind jeweils 8 Bit Werte (0-255) zu übergeben.

Alternativ für RGB:

leds[i] = CRGB(rot, grün, blau);

Oder mit Paletten:

leds[i] = ColorFromPalette( const CRGBPalette16& pal, uint8_t index, uint8_t brightness, TBlendType blendType)

FastLED allemeine Einführung: hier

ALLE Funktionen sind hier aufgelistet.

Es fängt schon mit der einfachen Füllung des Strips an :-/

/// fill_solid -   fill a range of LEDs with a solid color
///                Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200));
void fill_solid( struct CRGB * leds, int numToFill,
                 const struct CRGB& color);

Gruß,

Helmuth

    case 0: {                                                      // RED
      CRGB(255, 0, 0);                         
    }

CRGB ist eine Klasse. Du rufst hier nur den Konstruktor auf. Das erzeugt lediglich ein temporäres CRGB Objekt das sofort danach aufhört zu existieren.

Vieln Dank für deine Geduld Helmuth :)

Die Befehlsübersicht habe ich gesucht! Super, vielen Dank.

Die FastLED overview habe ich schon gelesen. Einen Strip herkömmlich mit Farben füllen, das ist ja recht einfach.

Mein Problem ist:

in der Funktion ColorWipe soll dergesamte Strip in einer "Farbe" eingefärbt werden. Die Farbe ist über einen Taster wählbar und wird in einem Switch Case durchgeschaltet. Ich habe "Farben" geschreiben, da Farben sein können: Farbe(Rot, Grün, Blau...), Fade(Rot InOut oder über mehrere Farben), ColorFade oder Rainbow.

Da für Rainbow ja jeder Pixel einzeln gesetzt werden muss, würde ich die Funktion ColorWipe gleich so schreiben, dass grundsätzlich alle Pixel einzeln gefüllt werden.

Hast du eine Idee wie man das lösen könnte?

hier mal ein seeehr einfaches Video von dem Mode, noch mit der Adafruit Bib:

https://vid.me/EBta

Danke für den Hinweis Serenifly, muss mir die Bib nochmal ansehen :-/ Hatte da nur mal rumprobiert.

Du willst also verschiede Animationen mit einem Button durchklicken, richtig?

Und manche Animationen sind einfach Standbilder.

Sind wir also mal wieder beim endlichen Automat. Du brauchst eine Zustandsvariable.

Wenn Zustand == x, dann Animation y.

Bei welcher konkreten Animation brauchst Du Hilfe?

würde ich die Funktion ColorWipe gleich so schreiben, dass grundsätzlich alle Pixel einzeln gefüllt werden.

Verstehe ich nicht und ColorWipe kenne ich nicht. Zeig mal den Code von Deiner alten Version, oder erkläre es nachvollziehbar.

P.S. Inspiration + Code für simple LED Animationen findest Du hier. Grundsätzlich ist der meiste Code Mist, weil pausengesteuert (also voll mit Delays), aber um grundsätzlich zu verstehen, was in welcher Reihenfolge passieren muss, taugt er schon.

Ich glaube, damit hat so ziemlich jeder schonmal gespielt, der LEDs programmiert, auch, wenn er es nicht mehr zugeben würde… :smiley:

Habe für dieses Projekt leider keinen Programmablauf erstellt.

In dem Video ist “Bewegungsmodus 1” gewählt.
Der heißt bei mir ColorWipe. Alle LEDs mit “Farbe” einfärben.
Dort schalte ich nur die Farben durch. Die “Bewegung” ist immer gleich.

Ich versuch es mal so:

Button1: “Mode” Auswahl
Button2: “Color” Auswahl

Modes:

  1. ColorWipe (Alle LEDs)
  2. Cycle (Lauflicht im Kreis)
  3. CylonDual (Doppeltes Lauflicht - parallel)
  4. Flash (Alle Leds: 3 x Flash - Pause - 3 x Flash - Pause…)
  5. Strobe (Stroboskop)
  6. VU-Meter (VU-Meter Bar Grün über Gelb zu Rot die auf geräusche reagiert) ← Farbunabhängig
  7. EMERG Mode (Police Light - Rot/Blau) ← Farbunabhängig

Colors:

  1. Rot
  2. Grün
  3. Blau
  4. Weiß
  5. FadeInOut Rot
  6. FadeInOut (Farben ← faded eine Liste von Farben nacheinander die eingegeben wurden)
  7. ColorFade (RGB Farbrad)
  8. Rainbow (der typische Rainboweffect - bewegtes Farbrad durch den Strip )
  9. Black / Off

In (fast) jedem Mode kann jede Farbe aus Color gewählt werden.

Hier mein kompletter Code mit der Adafruit Bib.
Hier funktioniert alles, außer die Modes mit “Scheif” also Cycle und CylonDual.
Dort funktionieren lediglich einzelne Farben. Alles andere flackert.

LED_CONTROLLER.txt (29.5 KB)

Okay, es geht also eigentlich um pickColor

Bei Dir sieht das so aus:

void pickColor(int c) {                                   
  switch(c){
    
    case 0: {                                                      // RED
      pixelColor = strip.Color(255, 0, 0);                         
    }
      break;

Mit FastLED würdest Du Dein

uint32_t pixelColor = strip.Color(0, 0, 0);

ersetzen durch

CRGB pixelColor = 0;

und in pickColor dann entsprechend

void pickColor(int c) {                                   
  switch(c){
    
    case 0: {                                                      // RED
      pixelColor = CRGB(255, 0, 0);                         
    }
      break;

u.s.w.

Es wird langsam etwas klarer :smiley:

Ich habe in der Zwischenueit überlegt die Pixelposition an pickColor (jetzt setColor) zu übergeben.
Meinst du, dass das vielleicht besser ist?

void colorWipe() {
  uint16_t i;
    for(i=0; i<NUM_LEDS; i++) {
      setColor(i);
    }
    FastLED.show();
}
void setColor(int i) {                                   
  switch(colrType){
    
    case 0: {                                                      // RED
      leds[i] = CRGB::Red;                         
    }
      break;
      
    case 1: {                                                      // GREEN
      leds[i] = CRGB::Green;                         
    }
      break;
      
    case 2: {                                                      // BLUE
      leds[i] = CRGB::Blue;                         
    }
      break;
      
    case 3: {                                                      // WHITE
      leds[i] = (200, 200, 200);                     
    }
      break;
    case 4: {                                                      // FADE IN/OUT SINGLE COLOR (RED) 
     // thisMillisFade=millis();
     // if(thisMillisFade - prevMillisFade >= intervalFadeIO){
          leds[i].fadeLightBy( 64 );                                                      
     // }
     // prevMillisFade = thisMillisFade;  
    }
      break;

Funktioniert soweit schon ganz gut :slight_smile:
Arbeite jetzt grad an dem Fade in Fade out.

Funktioniert soweit schon ganz gut :)

Schön, das ist erstmal die Hauptsache.

Ich würde das anders machen, aber egal - solange Performance und Übersichtlichkeit noch keine Rolle spielen, ist das erstmal nicht nötig.

Und Erfahrung ist schließlich die Summe der selbstgemachten Fehler. Also: weiter so! ;-) Solange Du nicht für ein paar Tausend LEDs mit über 100 fps Animationen berechnen musst, kann man sich auch ein switch-case vor dem Schreiben jeder einzelnen (!) LED leisten.

Optimieren kann man das später immer noch.

Beste Grüße,

Helmuth

Ja, schön ist das nicht, das weiß ich wohl :sweat_smile:
Ich versuche das zu nutzen, was ich kann/was mir zur verfügung steht (an Wissen :wink: )
Da wird es erstmal nur ne “Wellblechhütte” :slight_smile:

Beim nächsten Schritt:
Gibt es für das Dimmen bzw für das Faden von Farbe zu Schwarz und zurück eine fertige Funktion?
Alles was ich im Netz finde sind eigene Berechnungen.

Ich finde in der FastLED ein paar Funktionen, verstehe aber noch nicht wie ich die benutze, bzw wo ich die Funktionen dann einsehen kann :relaxed:

Z.B.:
void fadeLightBy (CRGB *leds, uint16_t num_leds, uint8_t fadeBy)

void fadeToBlackBy (CRGB *leds, uint16_t num_leds, uint8_t fadeBy)

void fadeUsingColor (CRGB *leds, uint16_t numLeds, const CRGB &colormask)

Grober Ansatz:

case 4: {                                                      // FADE IN/OUT SINGLE COLOR  
     thisMillisFade=millis();
     if(thisMillisFade - prevMillisFade >= intervalFadeIO){
       leds[i].fadeLightBy(fade);                       
           // FadeInOut(255, 0, 0);                                    
       if(fade == 255){
         fade = 0;
       fade++;
       prevMillisFade = thisMillisFade;  
       }
     }
}

Gibt es für das Dimmen bzw für das Faden von Farbe zu Schwarz (...) eine fertige Funktion?

Ja, z.B. die, die Du schon rausgesucht hast. Und noch viele mehr... Beispiel folgt unten.

Gibt es für das Dimmen bzw für das Faden (...) zurück eine fertige Funktion?

Ja, z.B. blend und nblend.

Ich finde in der FastLED ein paar Funktionen, verstehe aber noch nicht wie ich die benutze, bzw wo ich die Funktionen dann einsehen kann

Im Quellcode. In den Docs steht ja drin, in welcher Datei. Momentan sprechen wir z.B. über colorutils.h

Alternativ googelst Du einfach nach FastLED + Funktionsname und findest manchmal ein Beispiel, wo jemand diese Funktion verwendet.

Dein Codeansatz ist momentan Murks. Bei Animationen ist das i.d.R. so:

A) Man schreibt etwas neu in den Bildschpeicher B) Man manipuliert, was schon im Bildspeicher ist (C) Oder beides oder nur eins davon oder beides mehrfach usw.)

Versuche mal den folgenden kompakten Code zu verstehen. Dort siehst Du auch eine der möglichen Verwendungen von fadeToBlackBy. In diesem Fall auf den gesamten Bildspeicher angewendet.

Wie versprochen, Dein Schweifeffekt mit 3 Zeilen Code im Loop:

#include<FastLED.h>

#define LED_PIN     12
#define BRIGHTNESS  255
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS    240

uint8_t bpm         = 10; // Geschwindigkeit vom Punkt
uint8_t fade_amount = 15; // "Länge vom Schweif"

CRGB leds[NUM_LEDS];

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

void loop() {
  fadeToBlackBy(leds, NUM_LEDS, fade_amount);       // dimmen, was schon da ist
  leds[ beatsin8( bpm, 0, NUM_LEDS) ] = CRGB::Red;  // einen Punkt neu schreiben
  FastLED.show();
}

Und dann ersetze mal fadeToBlackBy(…) durch

memset8(leds, 0, NUM_LEDS * sizeof(CRGB));  // CLS - alles auf 0 setzen

Prinzip jetzt verstanden?

Moin Helmuth,

wow, das hat mich schon ein gutes Stück weiter gebracht! :smiley:

Unglaublich wie viele Funktionen FastLED hat!

Eigentlich hatte ich gedacht, ich setze mich zuerst an die Farbauswahl.

da ich dein beispiel aber ausprobieren wollte und mich da etwas reingearbeitet habe, habe ich jetzt die ersten 3 Muster erstellt.

Funktionieren tun sie auch schon mit festen Farbwerten.

Hier mal meine kreationen :stuck_out_tongue:

ColorWipe / bzw wohl lieber ColorFill :slight_smile:

void colorWipe() {
    fill_solid( leds, NUM_LEDS, pickColor());
    FastLED.show();
}

hier weiß ich allerdings nicht ob das so mit Rainbow funktioniert, dazu aber unten noch etwas.

Cycle

void loop() {
  //memset8(leds, 0, NUM_LEDS * sizeof(CRGB));  // CLS - alles auf 0 setzen
  fadeToBlackBy(leds, NUM_LEDS, fade_amount);       // dimmen, was schon da ist
  for(int i=0; i<bar_lenght; i++){
    leds[ (NUM_LEDS-1)-beatsin8( bpm, 0, NUM_LEDS/2-(bar_lenght-1))-i ] = CRGB::Red;  // einen Punkt neu schreiben
    leds[ i+beatsin8( bpm, 0, NUM_LEDS/2-(bar_lenght-1)) ] = CRGB::Red;  // einen Punkt neu schreiben
  }
  FastLED.show();
}

CylonDual

void loop() {
  //memset8(leds, 0, NUM_LEDS * sizeof(CRGB));  // CLS - alles auf 0 setzen
  fadeToBlackBy(leds, NUM_LEDS, fade_amount);       // dimmen, was schon da ist
  for(int i=0; i<bar_lenght; i++){
    leds[PIXEL_POS+i] = CRGB(50,0,200);
  }
  PIXEL_POS++;
  if(PIXEL_POS == NUM_LEDS)
    PIXEL_POS = 0;
  FastLED.show();
  delay(50);                                // Ich weiß ;) - ist nur zum testen!! 
}

Der CylonDual Mode ist evetuell nicht so schön mit der For-Schleife, aber ich habe keine Funktion gefunden, die am Anfang wieder beginnt.

Bei Cycle wollte ich die länge des Balkens also der LEDs die auf 100% leuchten länger machen. Das konnte ich mit meinem Wissen auch nur über eine For Schleife.

Falls es da noch etwas anderes gibt, bin ich gern offen für Vorschläge :smiley:

Ich glaube beatsin8 habe ich verstanden :slight_smile:
Ich würde es als Parabel beschreiben die die LED Position angibt.

Ich komme bei dem Switch Case bzw bei der Funktion pickColor() die in die Farbauswahl führt auf keinen grünen Zweig.
Dadurch, dass ich dort gern einen Rainbow und einen ColorFlow Effekt auswählen möchte, weiß ich nicht wie ich nun die Farbwahl mit dem Modus verbinden soll.

Soll ich die Farbe (und Rainbow etc) in pickColor() berechnen und je als uint32_t übergeben, oder soll ich in den Modi eine Funktion aufrufen, die dann die Farbe direkt in den Bildspeicher schreibt…?

Aufgrund meiner geringen Kenntnisse sehe ich da evtl. nicht die Möglichkeiten.

Ich habe schon mal einen bekannten gefragt, ob er mir später mit Klassen helfen könnte um das programm zu verfeinern, aber ich dachte erstmal könnte mann es so aufziehen um den Aufwand gering(er) zu halten. Wollte den Controller irgendwann auch mal benutzen. Da darf es gern die beta sein :smiley:

Auf jeden Fall kann ich mich für dein Engagement gar nicht genug bedanken.
echt klasse dass du für so etwas deine zeit opferst :sunglasses:

Liebe Grüße

Ich komme bei dem Switch Case bzw bei der Funktion pickColor() die in die Farbauswahl führt auf keinen grünen Zweig.

So isses.

Wenn es um fixe Farben geht, berechnest Du VOR der for-Schleife einmal das CRGB (also die Farbe mit ihren 3 RGB Anteilen) und setzt danach in der Schleife alle LEDs auf diesen Wert.

CRGB farbe = CHSV( 23, 255, 255 );
 
for(byte i = 0; i < NUM_LEDS; i++) {
    leds[i] = farbe;
  }

Wenn Du “farbe” global anlegst, kannst Du das dann u.a. in einem switch-case modifizieren. Außerhalb der Animation.

Für einen Farbverlauf kannst Du auch eine dynamische Farbe innerhalb der Schleife setzen, z.B.:

for(byte i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(i*5, 255, 255);
}

Siehe zu diesem Thema auch fill_gradient.

Oder die Helligkeit mit einem Sinus steuern:

for(byte i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(i*5, 255, beatsin8(60) );
}

Oder die Sättigung mit einem Sägezahn: (der Sprung von Weiss zu voller Farbe sieht Schxxxx aus)

for(byte i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(i*5, beat8(42), beatsin8(60) );
}

Oder noch wilder mit schwingender Verschiebung des Regenbogens:

for(byte i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV( ( i*3 ) + beatsin8( 42 ), 255, beatsin8(120, 100, 255) );
}

Hier stehen noch andere Wellenformen und viele nützliche Mathefunktionen mehr drin. Hier habe ich in einem Video von vor 1,5 Jahren mal ein paar verglichen.

Usw, es gibt noch viiiel zu entdecken.

Unglaublich wie viele Funktionen FastLED hat!

Ja, da kann man sich ein paar Wochen mit beschäftigen.

Auf jeden Fall kann ich mich für dein Engagement gar nicht genug bedanken.

Danke für Dein Interesse und Deine Bereitschaft selbstständig zu lesen, zu verstehen und zu experimentieren! So macht das Spaß!

Beste Grüße,

Helmuth