Lichterketten Farbverläufe mit NeoPixel

Arduino-Bastelprojekt: Farbverläufe und Effekte mit WS2812b NeoPixel-LEDs.

60 RGB LED STRIP 5M
60 RGB LED STRIP 5M

WS2812b-LEDs (NeoPixel) ermöglichen individuelle RGB-Steuerung jeder LED über eine einzige Datenleitung. Dieses Projekt steuert eine Lichterkette oder einen LED-Strip mit sanften Farbverläufen – ideal für Lampen, Deko oder indirekte Beleuchtung. Ein Taster wechselt zwischen verschiedenen Fade-Modi und ermöglicht die Einstellung einer festen Farbe.

Materialien

Pinbelegung

KomponenteArduino
WS2812b DI (Daten)Pin 1
Taster (ein Anschluss)Pin 2
Taster (anderer Anschluss)Pin 3 (als Ausgang auf GND)
WS2812b GND, 5VGND, 5V

Bedienung

Die aktuelle Einstellung wird im EEPROM gespeichert und beim nächsten Einschalten wiederhergestellt. Die Adafruit NeoPixel-Bibliothek wird benötigt.

/*
 * NeoPixel Lampen & LED-Strip Steuerung mit Button
 * Für: Arduino UNO, Nano, Mega2560, Digispark USB, ...
 * Bitte beachte: je nach Programmspeicher koennen verschieden viele LED's angeschlossen werden.
 * 
 * BEDIENUNGSANLEITUNG:
 * 
 * WENN DIE LAMPE AN IST:
 * KURZ DRUECKEN: 
 * schaltet zu den verschiedenen Fade-Modi.
 * Es gibt fünf Fade-Modi in den folgenden Farbstimmungen:
 * Orange, Lila, Türkis, Grün, Weiß (weiß= alle Farben)
 * LANG DRUECKEN:
 * die Lampen beginnen die Farbe schnell zu wechseln bis losgelassen wird.
 * So laesst sich eine feste Farbe einstellen.
 * 2X SCHNELL DRUECKEN:
 * Schaltet die Lampen in den Standby.
 * Durch einmaliges kurzes Druecken werden sie wieder eingeschalten.
 * Der zuletzt eingestellte Modi wird nach dem Einschalten wieder abgerufen.
 * 
 * WENN DIE LAMPE AUS IST:
 * KURZ DRUECKEN:
 * Schaltet die Lampe ein.
 * LANG DRUECKEN:
 * Schaltet die Lampe ein und dimmt diese.
 * Die Helligkeit verändert sich, bis man die Taste los lässt.
 * SEHR LANGE DRÜCKEN -> RESET
 * Wird die Lampe beim Einschalten länger als 15 Sekunden gedrückt, wird ein Reset ausgelöst.
 * Die Lampe beginnt nach dem Reset weiß zu blinken, bis man loslässt
 * 
 * WENN DIE LAMPE KAPUTT IST:
 * Sie bekommen 1 Jahr Garantie, d. h. ich repariere Ihnen defekte Lampen, 
 * sofern Sie diese nicht aus Eigenverschulden grob fahrlässig beschädigt haben.
 * SELBER REPARIEREN:
 * Abgebrochene Teile mit farblosen Sekundenkleber oder Zweikomponentenkleber befestigen.
 * VERDRAHTUNG:
 * WS2812: DI an Pin 0, GND zu GND, VIN/5V an 5V
 * Button zwischen Pin 1 & Pin 2
 * ENTSORGUNG:
 * Ich kann mich um die fachgerechte Demontage und Entsorgung kümmern.
 * ANSONSTEN:
 * Die Elektronik ausbauen und als Elektronikmüll entsorgen.
 * Den Lampenschirm in den gelben Sack legen.
 * Den Untersetzer je nach Material:
 * Gips zum Bauschutt, Holz zu den Gartenabfällen, Glas & Spiegel zum Altglas, Aluuntersetzer in Alusammelbehälter.
 * 
 * Autor: Veit Goetz
 * Date:  06.01.2017 V.1.1
 *        15.01.2017 V.1.2
 *        20.02.2017 V.1.3
 *        23.03.2017 V.1.3.1
 *        27.03.2017 V.1.4
 * Email: goetz@veit.tk
 * Web:   www.goetz-veit.tk
 *        www.3d-druck.tk
 */

/* ------------------ Librarys ------------------- */


//#include <avr/wdt.h>
/*void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void)
{
 MCUSR = 0;
 wdt_disable();
 return;
}*/

 // Include Librarys
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>

/* ---------------- Main Settings ---------------- */

#define ledPin     1  // Pin to connect the LED's
#define pixels     12 // Number of pixels - Anzahl LEDs
#define buttonOut  3  // Button pin (output)
#define buttonIn   2  // Button pin
#define RESET_PIN  4  // Wire to reset pin

/* ---------------- other Settings --------------- */

// Hier koennen Farben definiert werden, die in den Farbverlaufen vorkommen sollen
const byte colors[][3] = {// Statische Farben {r, g, b}, -> Nummerierung automatisch nach Reihenfolge
  {255, 150, 150}, // 0=White
  {255,   90,   0}, // 1=Yellow
  {255,   60,   0}, // 2=yellow-orange
  {255,   40,   0}, // 3=Orange
  {255,   0,   0}, // 4=Red
  {255,   0,  80}, // 5=Pink
  {150,   0, 200}, // 6=Purple
  {  0,   0, 255}, // 7=Blue
  {  0, 186, 255}, // 8=Light Blue
  {  0, 255,   0}, // 9=Green
  {200, 255,   0}, // 10=Light green
};
const byte colorCnt = 11; // number of colors - Anzahl der Farben

// hier koennen verschiedene Farbverlaeufe erstellt werden
const byte modes[][colorCnt+1] = {   // Fade-Programme {Anzahl Farben, [Farbnummer] },
  {10, 0,2,6,3,8,5,1,7,4,9}, // Fade each color
  {3, 1,10,3},               // Fade yellow
  {4, 3,1,2,4},                // Fade orange
  {3, 4,3,5},                // Fade red
  {4, 5,6,7},                // Fade purple
  {3, 7,8,6},                // Fade Blue
  {4, 9,10,8,1},             // Fade green
};
const byte modeCnt = 7; // number of Fade-programmes - Anzahl der Fade-Programme im Array

const unsigned int fadeSteps   = 255; // default:255 // Anzahl Zwischenschritte zwischen zwei Farben
const unsigned int fadeDelay   = 20;  // default:20  // Pause zwischen zwei Zwischenschritten
/* LED's  delay
 *  7     20
 *  12    17
 *  16    15
 *  24    10
 */
const unsigned int fastFade    = 2;   // default:2   // Pause bei schnellem Farbwechsel (bei 24 LED's:1)
const float fadeSize           = 0.1; // default:0.5 // Groeße des Farbverlaufs (0-1) - 1=alle LED's gleichzeitig 0=alle hintereinander
const unsigned int longPress   = 500; // default:500 // time (in ms) for long pressdown - Schwellwert für langen Tastendruck (in ms)
const unsigned int dubblePress = 600; // default:600 // max. time for dubble pressdown - Schwellwert für zweifachen Tastendruck

const byte EprAddr1 = 2;  // default:2  // Eeprom address for "mode"
const byte EprAddr2 = 6;  // default:6  // Eeprom address for "color"
const byte EprAddr3 = 10; // default:10 // Eeprom address for "pos"


/* ----------------- global vars ----------------- */

unsigned int mode = 0;         // current Modus (0-4=fade 5=static color)
unsigned int currentColor = 0; // current color
unsigned int pos = 0;          // current fade Position
//int intensy = 255;             // current brightnes
bool swichOff = false;         // Standby = true, wird durch zweifachen Tastendruck geändert

int fadeStartPos = 0;         // Startpixel for color fade, wird automatisch (zufällig) bestimmt

bool buttonPressed = false;    // if the button pressed - zwischenspeicher, wenn Button gedrückt ist
unsigned long downTime = 0;    // time of Pressdown - Zwischenspeicher für die Dauer, die der Button gedrückt ist
bool longStart = false;        // did the long pressdown allready start - zwischenspeicher , ob dies jetzt ein langer Tastendruck ist

bool modeSaved = true;    // Zwischenspeicher, ob aktueller Mode schon im EEPROM abgelegt wurde

/* ----------------- Initialize ------------------ */

Adafruit_NeoPixel strip = Adafruit_NeoPixel(pixels, ledPin, NEO_GRB + NEO_KHZ800); // initialize (LED's, pin, mode)


void setup() {
  initVars();
  #ifdef buttonOut
    pinMode(buttonOut, OUTPUT); // set the button as output
    digitalWrite(buttonOut, LOW); // Set one button PIN to LOW
  #endif
  pinMode(buttonIn, INPUT_PULLUP); // set the button as input with pullup
  strip.begin(); // start library
  strip.setBrightness(255); // set the max Brightness (0-255)
}

#ifdef RESET_PIN
void softReset()
{
  pinMode(RESET_PIN, OUTPUT);    // sets the digital pin as output
  digitalWrite(RESET_PIN, LOW);  // sets the LED off
  delay(20);
  digitalWrite(RESET_PIN, HIGH); // sets the LED on
  
}
#endif

/* ------------------ Main Loop ------------------ */

void loop() { // code runs repeatly
  if(!swichOff&&(mode<modeCnt||longStart)){ // if in Fade mode
    pos = (pos+1) % fadeSteps; // Fade
    if(pos==0){ // new color
      currentColor = (currentColor+1) % ((mode<modeCnt)?modes[mode][0]:colorCnt); // calculate color
      fadeStartPos = random(pixels-1); // get random start position
    }
    setRgb(); // update LED's
  }

  delay((mode<modeCnt||swichOff)?fadeDelay:fastFade); // slow/fast fade

  
  bool btState = 1-digitalRead(buttonIn); // read button
  if(btState==LOW&&!swichOff&&!modeSaved&&millis()-downTime>dubblePress){ // save current mode
    EEPROM.write(EprAddr1, mode); // Save in EEPROM
    modeSaved = true; // mark data as saved
  }
  if(buttonPressed==true){ // button was still pressed down (by the last request)
    if(btState==LOW){ // ButtonPressUp now
      longStart = false;
      if(!swichOff){ // if LED is on -> swich of
        if(millis()-downTime<longPress){ // Short pressup
          changeMode(1); // next Fade-Mode
          modeSaved = false; // mode was changed but not saved in EEPROM yet
        }else{ // long pressup
          EEPROM.write(EprAddr2, currentColor); // Save current static color in EEPROM
          EEPROM.write(EprAddr3, pos); // save current static fade position in EEPROM
        }
      }else if(downTime>0){ // led was off -> swich on
        if(millis()-downTime<longPress){ // Short pressup
          swich_On(); // Swich the lamp on
          swichOff=false; // save, that lamp is now swiched on
        }else{ // swich on with long press
          #ifdef RESET_PIN
            softReset(); //call reset
          #endif
        }
      }
    }else if(!longStart&&millis()-downTime>longPress){ // start long Pressdown
      if(downTime>0){ // lamp is on
        longStart = true;
        if(!swichOff){ // if the lamp is allready on
          if(mode!=modeCnt){ // from fade to static mode
            currentColor = modes[mode][1+currentColor]; // get current color
            mode = modeCnt; // set to static mode (fast fade each color)
            EEPROM.write(EprAddr1, mode); // Save "static mode" to EEPROM
          }
        }
      }
    }
  }
  else if(buttonPressed==false&&btState==HIGH){ // new ButtonPressDown
    if(millis()-downTime<dubblePress&&!swichOff){ // dubble pressdown
      swich_Off(); // swich off
      downTime = 0;
      //asm volatile ( "jmp 0");  
    }else{
      downTime = millis(); // save the time of Pressdown
      if(swichOff){
        //swich_On(); // Swich the lamp on
      }
    }
  }
  if(buttonPressed!=btState) buttonPressed = btState; // ButtonChange

}

/* -------------------- init --------------------- */

void initVars(){
  mode = EEPROM.read(EprAddr1);// %(modeCnt+1); // get the current mode
  currentColor = EEPROM.read(EprAddr2)%((mode<modeCnt)?modes[mode][0]:colorCnt); // get the current color
  pos = EEPROM.read(EprAddr3)%(fadeSteps); // get the current fade pos.
  strip.setBrightness(200); // set Brightness && Initialize all pixels
  return;
}


/* -------------- Lamp Swich on/off -------------- */

void swich_On(){
  mode = EEPROM.read(EprAddr1);//%(modeCnt+1); // get the current mode
  currentColor = EEPROM.read(EprAddr2); // get the current color
  pos = EEPROM.read(EprAddr3)%(fadeSteps); // get the current fade pos.
  setRgb(); // Update mode on LED's
  return;
}

void swich_Off(){
  swichOff=true; // swich off
  for(unsigned long n=0;n<pixels; n++){ // Set Color to each LED
    //strip.setPixelColor(n, 0, 0, 0); // Swich OFF
    strip.setPixelColor(n, strip.Color(0, 0, 0)); // Swich OFF
  }
  strip.show(); // Show update on LED-Strip
  return;
}


/* ---------- Caclculate RGB and upload ---------- */

void setRgb(){
  float col[3];
  float fadeStart = (0.5+fadeSize)*pos/fadeSteps;
  float fadeEnd = fadeStart-fadeSize;
  for(long n=0;n<pixels; n++){ // Set Color to each LED
    float distance = 1.0*abs(n-fadeStartPos)/pixels; if(distance>0.5) distance = 1-distance;
    float intensy = (distance>=fadeStart)?0:(distance<=fadeEnd)?1:(fadeStart-distance)/fadeSize;
    if(mode==modeCnt) intensy = 1.0*pos/fadeSteps;
    for(byte n=0;n<3;n++){ // calculate RGB-Value
      byte col1 = colors[ (mode<modeCnt) ? modes[mode][1+currentColor] : currentColor ][n];
      byte col2 = colors[ (mode<modeCnt) ? modes[mode][1+((currentColor+1)%modes[mode][0])] : ((currentColor+1)%colorCnt) ][n];
      col[n] = 1.0*(col2-col1)*intensy + col1 ;
    }
    //strip.setPixelColor(n, col[0], col[1], col[2]);
    strip.setPixelColor(n, strip.Color(col[0], col[1], col[2]));
  }
  strip.show(); // Show update on LED-Strip
  return;
}

/* ---------- Swich between Color-Modes ---------- */

void changeMode(int change){ // Update fade mode & LED's
  mode = (mode+change)%(modeCnt);
  pos=0;
  currentColor = 0; //mode%colorCnt;
  setRgb();
  return;
}
MIKADO LAMP RGB
MIKADO LAMP RGB
144 RGB LED STRIP 2M
144 RGB LED STRIP 2M
60 RGB LED STRIP 5M
60 RGB LED STRIP 5M
60 RGB LED STRIP 5M
60 RGB LED STRIP 5M
LOTUS LAMP RGB
LOTUS LAMP RGB
WS2812B LICHTERKETTE
WS2812B LICHTERKETTE
WS2812B LICHTERKETTE
WS2812B LICHTERKETTE

Kommentare

Zum Absenden den Slider nach rechts ziehen


Weitere Artikel

Gefällt dir die Webseite? Unterstütz die werbefreie Seite mit einer Spende.

© Veit Götz 2012 - 2026
Impressum
Datenschutz
Statistiken