[gelöst] WS2801 "gruselige" Hintergrundbeleuchtung

Hallo zusammen,

ich habe ein Problem bei dem ich nicht weiter komme. Ich habe ein kleines Projekt am laufen. Eine kleine Wetterstation welches nun ihr Finsch erhalten soll. Ich habe die DIspalys meiner Wetterstation an eine Scheibe gklebt und möchte diese nun im Hintergrund beleuchten. Vorn klebt auf der Scheibe ein Skelettkopf. Daher hätte cih gern etwas "gruseliges". Da ich noch ein Reststück eines WS2801 LED Strip übrig habe wollte ich es gern damit realisieren. Es sind noch 25 LEDs drauf. Ich hätte gern irgendetwas mit rot. Vielleicht pulsierend oder eine Art lauflicht im Kreis. Ich habe auch schon versucht den "fire2012" sketch zum laufen zu bekommen aber ohne Erfolg.
Ich habe mir die Biblithek FastLED und die Beispiele in der Adafruit WS2801 angesehen

Der Sketch von Adafruit "strandtest" läuft.

#include "Adafruit_WS2801.h"
#include "SPI.h" // Comment out this line if using Trinket or Gemma
#ifdef __AVR_ATtiny85__
 #include <avr/power.h>
#endif

/*****************************************************************************
Example sketch for driving Adafruit WS2801 pixels!


  Designed specifically to work with the Adafruit RGB Pixels!
  12mm Bullet shape ----> https://www.adafruit.com/products/322
  12mm Flat shape   ----> https://www.adafruit.com/products/738
  36mm Square shape ----> https://www.adafruit.com/products/683

  These pixels use SPI to transmit the color data, and have built in
  high speed PWM drivers for 24 bit color per pixel
  2 pins are required to interface

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution

*****************************************************************************/

// Choose which 2 pins you will use for output.
// Can be any valid output pins.
// The colors of the wires may be totally different so
// BE SURE TO CHECK YOUR PIXELS TO SEE WHICH WIRES TO USE!
uint8_t dataPin  = 2;    // Yellow wire on Adafruit Pixels
uint8_t clockPin = 3;    // Green wire on Adafruit Pixels

// Don't forget to connect the ground wire to Arduino ground,
// and the +5V wire to a +5V supply

// Set the first variable to the NUMBER of pixels. 25 = 25 pixels in a row
Adafruit_WS2801 strip = Adafruit_WS2801(25, dataPin, clockPin);

// Optional: leave off pin numbers to use hardware SPI
// (pinout is then specific to each board and can't be changed)
//Adafruit_WS2801 strip = Adafruit_WS2801(25);

// For 36mm LED pixels: these pixels internally represent color in a
// different format.  Either of the above constructors can accept an
// optional extra parameter: WS2801_RGB is 'conventional' RGB order
// WS2801_GRB is the GRB order required by the 36mm pixels.  Other
// than this parameter, your code does not need to do anything different;
// the library will handle the format change.  Examples:
//Adafruit_WS2801 strip = Adafruit_WS2801(25, dataPin, clockPin, WS2801_GRB);
//Adafruit_WS2801 strip = Adafruit_WS2801(25, WS2801_GRB);

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif

  strip.begin();

  // Update LED contents, to start they are all 'off'
  strip.show();
}


void loop() {
  // Some example procedures showing how to display to the pixels
  
  colorWipe(Color(255, 0, 0), 50);
  colorWipe(Color(0, 255, 0), 50);
  colorWipe(Color(0, 0, 255), 50);
  rainbow(10);
  rainbowCycle(20);
}

void rainbow(uint8_t wait) {
  int i, j;
   
  for (j=0; j < 256; j++) {     // 3 cycles of all 256 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel( (i + j) % 255));
    }  
    strip.show();   // write all the pixels out
    delay(wait);
  }
}

// Slightly different, this one makes the rainbow wheel equally distributed 
// along the chain
void rainbowCycle(uint8_t wait) {
  int i, j;
  
  for (j=0; j < 256 * 5; j++) {     // 5 cycles of all 25 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      // tricky math! we use each pixel as a fraction of the full 96-color wheel
      // (thats the i / strip.numPixels() part)
      // Then add in j which makes the colors go around per pixel
      // the % 96 is to make the wheel cycle around
      strip.setPixelColor(i, Wheel( ((i * 256 / strip.numPixels()) + j) % 256) );
    }  
    strip.show();   // write all the pixels out
    delay(wait);
  }
}

// fill the dots one after the other with said color
// good for testing purposes
void colorWipe(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

/* Helper functions */

// Create a 24 bit color value from R,G,B
uint32_t Color(byte r, byte g, byte b)
{
  uint32_t c;
  c = r;
  c <<= 8;
  c |= g;
  c <<= 8;
  c |= b;
  return c;
}

//Input a value 0 to 255 to get a color value.
//The colours are a transition r - g -b - back to r
uint32_t Wheel(byte WheelPos)
{
  if (WheelPos < 85) {
   return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
   WheelPos -= 85;
   return Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170; 
   return Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Aber wie kann ich den jetzt umbauen? Ich verstehe in den Funktionen leider gar nichts und mein Englisch ist nicht gut genug um den Inhalt zu verstehen.

Hat vielleicht jemand eine Idee.

Hast Du WS2801 oder WS2812 Led-Streifen?
Grüße Uwe

Moin. Such mal nach "WLED"
Das dann einfach auf einen ESP8266 flashen und du hast auch Fire2012.

.....und vieeeeeeeeel mehr.

Lieben Gruß,
Chris

uwefed:
Hast Du WS2801 oder WS2812 Led-Streifen?
Grüße Uwe

Ich habe einen WS2801.

themanfrommoon:
Moin. Such mal nach "WLED"
Das dann einfach auf einen ESP8266 flashen und du hast auch Fire2012.

.....und vieeeeeeeeel mehr.

Lieben Gruß,
Chris

Ich finde in der Bibliothek kein "WLED". Außerdem will, wenn möglich, diese Funktion in einen anderen Sketch integrieren.
Ich nutze für die Programmierung einen Arduino Uno und später soll alles auf einem Nano laufen.

Wie ich sehe hast du mich leider nicht verstanden.

  1. Suche im Internet nach "WLED"
  2. Flashe das auf einen nodeMCU v2
  3. Schließe das an deinen WS2801 an

Was erreichst du damit?

  1. Du musst gar nichts programmieren.
  2. Du hast neben dem Fire2012 Effekt noch über 100 weitere Effekte, Paletten, Funktionen. Du kannst auch mehrere Controller synchronisieren
  3. Du kannst alles über ein Smartphone steuern
  4. Das ist alles in 10min erledigt und du kannst dich schnell daran erfreuen

Ist die Frage was ist denn dein Ziel? Selber programmieren lernen oder sich an schönen Lichteffekten erholen?

Man muss ja nicht immer unbedingt das Rad neu erfinden. Manchen Leuten reicht es ja auch mit Bus, Bahn, Auto oder Fahrrad zu fahren.

Ah ok. Das habe ich dann wirklich falsch verstanden.

Ich habe leider keinen nodeMCU v2 und möchte eigentlich auch keinen kaufen.

Fernziel soll sein, dass ich den WS2801 auf dem selben Nano betreiben kann auf der meine Wetterstation läuft. Als zwiuschenziel würde mir ein Sketch reichen mit dem ich den WS2801 auf dem Uno betreiben kann und den ich dann entsprechend umbauen kann.

themanfrommoon:
Ist die Frage was ist denn dein Ziel? Selber programmieren lernen oder sich an schönen Lichteffekten erholen?

Wenn du so fragst möchte ich lernen wie man den programmiert damit ich mich an meiner Wetterstation im Totenkopfstyle mit gruseliger Hintergrundbeleuchtung erfreuen kann.

marcelbastler:
Daher hätte cih gern etwas "gruseliges".

Darin bin ich nicht so begabt, ich mag eher schöne Dinge. Zur Wetterstation paßt ein Regenbogen.

marcelbastler:
... WS2801 LED Strip ...

Habe ich leider nicht, daher mit WS2815 an Nano getestet:

#include <FastLED.h>

FASTLED_USING_NAMESPACE

#define DATA_PIN    11
//#define CLK_PIN     13
#define LED_TYPE    WS2812B // WS2801
#define COLOR_ORDER GRB
#define NUM_LEDS    25
CRGB leds[NUM_LEDS];

uint32_t jetzt;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void setup() {
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // Daten und Takt an einem Pin
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // freie Pin-Wahl
  //FastLED.addLeds<LED_TYPE,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // Hardware SPI: DATA_PIN Pin 11, CLK_PIN Pin 13
}

void loop()
{
  jetzt = millis();
  rainbow();
}

void rainbow()
{
  static uint32_t vorhin = jetzt;
  if (jetzt - vorhin >= 20) {
    vorhin = jetzt;
    fill_rainbow( leds, NUM_LEDS, gHue, 7); // FastLED's built-in rainbow generator
    FastLED.show(); // send the 'leds' array out to the actual LED strip
    gHue++;  // slowly cycle the "base color" through the rainbow
  }
}

Bei WS2801 würde ich zur Verwendung der µC-Hardware für SPI raten, da sich dadurch eine Beschleunigung ergeben soll. Ich nutze das bei APA102 mit 300 Pixeln. Bei 25 Pixeln ist das aber nicht so relevant.

Also der Regenbogen funktioniert. Wie kann ich beim Regenbogen die Farbe ändern? Gruselig wäre ja ein rotes pulsieren oder Farbwechsel im Farbebereich Rot.

marcelbastler:
Also der Regenbogen funktioniert.

:slight_smile:

marcelbastler:
Wie kann ich beim Regenbogen die Farbe ändern?

Der ändert doch ständig die Farbe ::slight_smile:

marcelbastler:
... Farbwechsel im Farbebereich Rot.

Bei mir gruselt es da nicht, aber wenn Du meinst:

// getestet mit Nano
#include <FastLED.h>

FASTLED_USING_NAMESPACE

#define DATA_PIN    11
//#define CLK_PIN     13
#define LED_TYPE    WS2812B // WS2801
#define COLOR_ORDER GRB
#define NUM_LEDS    25
CRGB leds[NUM_LEDS];

uint32_t jetzt;
bool neu = true;
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void setup() {
  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // Daten und Takt an einem Pin
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // freie Pin-Wahl
  //FastLED.addLeds<LED_TYPE,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // Hardware SPI: DATA_PIN Pin 11, CLK_PIN Pin 13
}

void loop()
{
  jetzt = millis();
  animation();
}

void animation(){
  static byte schritt = 0;
  switch (schritt) {
    case 0:
      if (rainbow()) schritt++;
      break;
    case 1:
      if (rotpuls(1, 100)) schritt++;
      break;
    case 2:
      if (rotpuls(0, 100)) schritt++;
      break;
    case 3:
      if (rotpuls(1, 100)) schritt++;
      break;
    case 4:
      if (rotpuls(0, 100)) schritt++;
      break;
    case 5:
      if (rotpuls(1, 100)) schritt++;
      break;
    case 6:
      if (rotpuls(0, 100)) schritt++;
      break;
    case 7:
      if (rotpuls(1, 100)) schritt++;
      break;
    default:
      schritt = 0;
  }
  if (neu) {
    FastLED.show(); // send the 'leds' array out to the actual LED strip
    neu = false;
  }
}

bool rainbow()
{
  bool fertig = false;
  static byte zaehler = 10;
  static uint32_t vorhin = jetzt;
  if (jetzt - vorhin >= 22) {
    vorhin = jetzt;
    byte farbe = gHue;
    for (byte j = 0; j < NUM_LEDS; j++) {
      leds[j] = CHSV( farbe, 255, 255);
      farbe += 7;
    }
    neu = true;
    gHue++;  // slowly cycle the "base color" through the rainbow
    zaehler--;
    if (!zaehler) {
      zaehler = random(100, 2000);
      fertig = true;
    }
  }
  return fertig;
}

bool rotpuls(bool an, uint32_t intervall) {
  bool fertig = false;
  static uint32_t vorhin = jetzt;
  if (jetzt - vorhin >= intervall) {
    vorhin = jetzt;
    if (an) {
      for (byte j = 0; j < NUM_LEDS; j++) {
        leds[j] = CRGB(255, 0, 0);
      }
    } else {
      for (byte j = 0; j < NUM_LEDS; j++) {
        leds[j] = CRGB(0, 0, 0);
      }
    }
    neu = true;
    fertig = true;
  }
  return fertig;
}

Schau Dir mal die Bibliotheksbeispiele an, möglicherweise findest Du da noch Anregung. Denn richtig gruselig ist nur, was man selbst zusammengeschrieben hat.

Hmmm. So richtig komm ich noch nicht klar. Ich würde mal versuchen selbst was zu basteln aber ich verstehe die Befehle nicht.

Gibt es irgendwo ein Beschreibung wie so ein Befehl aufgebaut ist? Ich stelle mir da irgendwie vor, dass ich die LEDs der reihe nach anspreche und ihnen einen Farbe mitgeben kann.

Also irgendwie sowas:

LEDan(LEDNr, Farbe, Helligkeit);

Gibt es sowas?

Es gibt viel Dokumentation zu FastLed. Lesen musst Du selbst.

Gruß Tommy

marcelbastler:
Also irgendwie sowas:

LEDan(LEDNr, Farbe, Helligkeit);

Ja, gibt es:

leds[j] = CHSV(farbe, 255, 255);
...
leds[j] = CRGB(255, 0, 0);

Um sich gezielt eine Farbe herauszupicken, muß man sich mit den Farbräumen HSV und RGB beschäftigen. FastLED kennt auch Farbnamen (Predefined colors list).

Ok. Das hilft schonmal weiter. Ich habe auch schon einiges gelesen und sogar ein kleines Lauflicht hinbekommen. Aber ich denke das was ich will bekomme ich noch nicht hin. Daher werd ich den Regenbogen oder irgend einen Farbwechsel nehmen.

Jetzt quält mich eine andere Frage. Wie kann ich das in meinen bestehenden Sketch intergieren? Geht das überhaupt? Wenn es absolut nicht möglich ist müsste ich einen 2 Nano in der Wetterstation verbauen. Und eine Tolle Idee habe ich noch zusätzlich. Kann ich den LED Strip mit einem Kippschalter schalten?

Hier der Sketch

// basiert auf [Forumsketch(5) https://forum.arduino.cc/index.php?topic=713953.0]
// und https://forum.arduino.cc/index.php?topic=713953.msg4798029#msg4798029
// Funktion des Sketches:
// Auf einem 1,8 Zoll Display sollen alle 5 Sekunden abwechselnd die Temperatur, die Luftfeuchtigkeit und der Luftdruck angezeigt werden.
// Gleichzeitig soll auf einer 7 Segementanzeige eine Digitale Uhr laufen. Die Punkte der Uhr sollen im Sekundentakt blinken. 

#include <TFT.h>
#include <SPI.h>
#include <Seeed_BME280.h> 
#include <Wire.h> 
#include "RTClib.h"
#include <TM1637Display.h>

BME280 bme280;

 #define cs   10
 #define dc   9
 #define rst  8
 #define CLK 2
 #define DIO 3

  TFT TFTscreen = TFT(cs, dc, rst);                 // 1,8 Zoll TFT Display
  RTC_DS3231 rtc;                                   // Real Time Clock
  TM1637Display display = TM1637Display(CLK, DIO);  // 7 Segmentanzeige

  char TempPrintout[5];     // Variable für den Temperaturwert mit der Begrenzung der Nachkommastellen
  char DruckPrintout[6];    // Variable für den Luftdruckwert
  char FeuchtPrintout[3];   // Variable für den Luftfeuchtigkeitswert

void setup()
{
  Serial.println("Start...");
  TFTscreen.begin();    
  if(!bme280.init()){       // Initialisierung des BME280 und Abfrage ob dieser initialisert ist
    Serial.println("Device error!");
  }
  if (!rtc.begin()) {       // Initialisierung des RTC und Abfrage ob dieser initialisert ist
    Serial.println("Couldn't find RTC");
    while (1);
  }
   if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  TFTscreen.background(0, 0, 0);
  TFTscreen.stroke(255,255,255);
  Serial.begin (115200);    // Einstellen der Baudrate

  display.setBrightness(5); // Helligkeit der 7 Segmentanzeige
  display.clear();          // Anzeige leeren
  
}

void loop()
{
  schrittketteWetter(); // Funktion für die Ausgabe der Wetterdaten
  schrittketteZeit();   // Funktion für die Uhr
}

void schrittketteWetter()
{
  const unsigned long intervallWetter = 5000; // Länge des Intervalls
  const unsigned int maxschrittWetter = 3; // Hier die Festlegung, wieviele Schritte gewollt sind
  static unsigned long Wettermillis = 0;
  static unsigned int schrittWetter = 0;
  if (millis() - Wettermillis >= intervallWetter) //Wetterdaten Ausgabeschleife
  {
    Serial.println (F ("Hier wird alle 5 Sekunden eine WetterAusgabe ausgelöst"));
    Wettermillis = millis();
    if (schrittWetter >= maxschrittWetter)
    {
      Serial.print (F ("Maximale Anzahl der Schritte Wetter erreicht -letzter Schritt war:"));
      Serial.println (schrittWetter);
      schrittWetter = 0;
    }
    schrittWetter++;
    switch (schrittWetter)
    {
      case 1:
        Serial.println (F ("Jetzt wird Schritt 1 Wetter ausgeführt"));
        Temperatur();
        break;
      case 2:
        Serial.println (F ("Jetzt wird Schritt 2 Wetter ausgeführt"));
        Luftdruck();
        break;
      case 3:
        Serial.println (F ("Jetzt wird Schritt 3 Wetter ausgeführt"));
        Luftfeuchtigkeit();
        break;
      default:
        Serial.print (F ("Variable schrittWetter: "));
        Serial.print (schrittWetter);
        Serial.println (F ("nicht im case unterstützt!"));
        break;
    }
  }
}

void schrittketteZeit()
{
  DateTime now = rtc.now();
  int displaytime = (now.hour() * 100) + now.minute();
  
  const unsigned long intervallZeit = 1000; // Länge des Intervalls
  const unsigned int maxschrittZeit = 2; // Hier die Festlegung, wieviele Schritte gewollt sind
  static unsigned long Zeitmillis = 0;
  static unsigned int schrittZeit = 0;
  
  if (millis() - Zeitmillis >= intervallZeit) // Bedingung erfüllt?
  {
    Serial.println (F ("Hier wird in intervallZeit ein Durchlauf ausgelöst"));
    Zeitmillis = millis();
    if (schrittZeit >= maxschrittZeit)
    {
      Serial.print (F ("Maximale Anzahl der Zeit Schritte erreicht -letzter Schritt war:"));
      Serial.println (schrittZeit);
      schrittZeit = 0;
    }
    schrittZeit++;
    switch (schrittZeit)
    {
      case 1:
        display.showNumberDecEx(displaytime, 0b11100000, true);
        Serial.println (F ("Jetzt wird Schritt 2 Zeit ausgeführt"));
        Serial.println(displaytime);
        break;
      case 2:
        display.showNumberDec(displaytime, true);
        Serial.println (F ("Jetzt wird Schritt 2 Zeit ausgeführt"));
        Serial.println(displaytime);
        break;
      default:
        Serial.print (F ("Variable schrittZeit: "));
        Serial.print (schrittZeit);
        Serial.println (F ("nicht im case unterstützt!"));
        break;
    }
  }
}

  void Temperatur(){
    String Temp = String(bme280.getTemperature());  // speichern des Wertes in einer Variablen
    Temp.toCharArray(TempPrintout, 5);  
    Serial.println(bme280.getTemperature());
    TFTscreen.fillScreen(0);              // Bildschirm schwarz füllen = leeren der Anzeige
    TFTscreen.stroke(255,255,255);        // Schriftfarbe einstellen
    TFTscreen.setTextSize(4);             // Textgröße für der Anzeigewert
    TFTscreen.text(TempPrintout,20,60);   // Wert und Position des Wertes
    TFTscreen.setTextSize(2);             // Textgröße für die Bezeichnung
    TFTscreen.text("Temperatur", 20, 30); // Text und Position der Bezeichnung
    TFTscreen.setTextSize(1);             // Textgröße für die Einheit (da es kein Gradzeichen gibt verwende ich hier eon kleines o)
    TFTscreen.text("o",118,58);           // Text und Position der Einheit
    TFTscreen.setTextSize(4);             // -"-
    TFTscreen.text("C",125,60);           // -"-
  }
  void Luftfeuchtigkeit(){
    String Feuchte = String(bme280.getHumidity());
    Feuchte.toCharArray(FeuchtPrintout, 3);
    
    TFTscreen.fillScreen(0);
    TFTscreen.stroke(255,255,255); 
    TFTscreen.setTextSize(4);
    TFTscreen.text(FeuchtPrintout, 40, 80); 
    TFTscreen.setTextSize(2);
    TFTscreen.text("Luft-",50,30);
    TFTscreen.text("feuchtigkeit", 10, 50);
    TFTscreen.setTextSize(4);
    TFTscreen.text("%",100,80);
  }

  void Luftdruck(){
    float Pascal = bme280.getPressure();  // Luftdruckwert ermitteln (dieser wird in Pascal ausgegeben)
    float hPa = Pascal/100;               // Umrechnen in hPa 
    String Druck = String(hPa);           // Variable für den Luftdruckwert als String speichern
    Druck.toCharArray(DruckPrintout,6);
    
    TFTscreen.fillScreen(0);
    TFTscreen.stroke(255,255,255); 
    TFTscreen.setTextSize(3);
    TFTscreen.text(DruckPrintout, 10, 60); 
    TFTscreen.setTextSize(2);
    TFTscreen.setTextSize(2);
    TFTscreen.text("Luftdruck", 20, 30);
    TFTscreen.setTextSize(3);
    TFTscreen.text("hPa",110,60);
  }

marcelbastler:
Geht das überhaupt? Wie kann ich das in meinen bestehenden Sketch intergieren?

Klar, die Voraussetzungen dafür sind günstig.
Zum Beispiel so:

void loop()
{
  schrittketteWetter(); // Funktion für die Ausgabe der Wetterdaten
  schrittketteZeit();   // Funktion für die Uhr
  schrittketteLicht();   // Funktion für den LED Strip
}

wno158:
Klar, die Voraussetzungen dafür sind günstig.

@marcelbastler: Dem kann ich nur zustimmen, denn ich hatte die Animation in eine Funktion gesteckt!

Das klingt eigentlich nicht schlecht. Jetzt habe ich nur noch ein Problem.

Ich bekomme es nicht hin. Ich hätte auch gern die Möglichkeit die Beleuchtung mit einem Separaten Schalter auszuschalten. Doch leider bekomme ich das auch nicht hin.

marcelbastler:
Ich hätte auch gern die Möglichkeit die Beleuchtung mit einem Separaten Schalter auszuschalten. Doch leider bekomme ich das auch nicht hin.

Einfachster Fall: Strom weg.

Gruß Tommy

Eins nach dem anderen der Reihe nach bitte.

marcelbastler:
Ich bekomme es nicht hin.

Also dann müssten wir erstmal Deinen letzten Versuch sehen (kompletter Sketch, falls zu groß, als .txt anhängen) - verbunden mit einer Beschreibung, was genau denn nun schiefläuft (und vielleicht auch was zu Deiner Zufriedenheit geht).

Ich hätte auch gern die Möglichkeit die Beleuchtung mit einem Separaten Schalter auszuschalten.

Das kommt dann danach.

marcelbastler:
Ich bekomme es nicht hin. Ich hätte auch gern die Möglichkeit die Beleuchtung mit einem Separaten Schalter auszuschalten. Doch leider bekomme ich das auch nicht hin.

Na dann einen PIN festlegen und dem sagen, was er machen soll:

// ergänzen:
const byte aus_PIN = 4; // NEU! Pin nummer anpassen!
// im setup() ergänzen
pinmode(aus_PIN, INPUT_PULLUP); // SCHALTER geht nach GND

Ausgehend von Schrittkette Licht wird die nur erweitert:
Erstens muss das max switch Licht um einen Schritt erhöht werden.
Dann muss dafür ein case rein.
Und dann muss der Code ergänzt werden

    if (!digitalRead(aus_PIN)) {schrittLicht=maxSchrittLicht;} // NEU festlegen, das aus!
    switch (schrittLicht)
    {

      case maxSchrittLicht:
// digitalWrite(LichtPIN, AUS); Natürlich passend bauen
        break;
    }

[edit]
Wenn Du das selbst nicht hibekommst, dann nur das "void schrittkettelLicht()" und den PinNamen für den Schalterpin posten - das passt dann schon...