Neopixel mit Taster steuern

Hallo,

Habe ein Arduino Uno mit Taster, Mikro und Neopixel kombiniert. Für das Mikro habe ich zwei Leuchtprogramme zusammengefügt, das ganze funktionierte wunderbar mit dem Taster. Für die nächsten Leuchtprogramme wollte ich einige FastLED Beispiele einfügen. Hier bemerkte ich zwei Probleme.

Problem 1:
Nach dem FastLED bleiben die LEDs stehen. (Ich dachte mal, hier was gelesen zu haben finde aber den Link nicht mehr)

Problem 2:
Einige Leuchtprogramme dauern etwas länger. Da der Leuchtmodus zu beginn abgefragt wird, kann es manchmal zur Glückssache werden wann der Taster gelesen wird.

Kennt hier jemand optimale Lösungen?
Den Code im Anhang habe ich auf das wesentliche reduziert.

#include "FastLED.h"

#define N_PIXELS 60                     // Wie viele LEDs sind im Strip
#define LED_TYPE NEOPIXEL               // LED Type
#define LED_PIN 6                       // NeoPixel LED ist mit diesem Pin angeschlossen
#define BRIGHTNESS  128                 // Für FastLED - colorTemperatur
#define TEMPERATURE_1 Tungsten100W      // Für FastLED - colorTemperatur
#define TEMPERATURE_2 OvercastSky       // Für FastLED - colorTemperatur
#define DISPLAYTIME 20                  // Für FastLED - colorTemperatur | How many seconds to show each temperature before switching
#define BLACKTIME   3                   // Für FastLED - colorTemperatur | How many seconds to show black between switches

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

//Konstante Variablen
const int TasterPin = 8; // Taster an Pin 8 angeschlossen


//Variablen

int Leuchtmodus = 0; // Variable für die verschiedenen festgelegten Farben





//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Setup
void setup() {
  delay( 3000 ); // power-up safety delay
  FastLED.addLeds<LED_TYPE, LED_PIN>(leds, N_PIXELS);
  FastLED.setBrightness( BRIGHTNESS );            // Für FastLED - colorTemperatur

  // Festlegen der Ein- und Ausgänge
  pinMode(TasterPin, INPUT); //Setzt den TasterPin als Eingang
  digitalWrite(TasterPin, HIGH); // Pull Up Wiederstand aktivieren (Achtung kehrt HIGH und LOW um)

  Serial.begin(9600);


}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Loop
void loop() {


  int TasterStatus = !digitalRead(TasterPin);       // Abfrage ob der Taster gedrückt ist

  //Wenn Taster gedrückt ist, Leuchtmodus +1
  if (TasterStatus == HIGH) {
    Leuchtmodus = Leuchtmodus++;
    delay(500);
  }

  // Anzahl der Leutmodi auf 3 begrenzen. (0 bis 2)
  if (Leuchtmodus == 3) {
    Leuchtmodus = 0;
  }


  //+++++++++++++++LEUCHTPROGRAMME +++++++++++++++++

  //  ------------------------------------ Modus 0 = rot leuchten
  if (Leuchtmodus == 0) {
    Serial.print("Leuchtmodus: ");    // Serial Monotior
    Serial.println(Leuchtmodus);      // Serial Monotior

    redblink(); 

  }

  // ------------------------------------ Modus 1 = Blau
  if (Leuchtmodus == 1) {
    Serial.print("Leuchtmodus: ");
    Serial.println(Leuchtmodus);

    colorTemperatur(); 

  }

  //  ------------------------------------ Modus 2 = grün
  if (Leuchtmodus == 2) {
    Serial.print("Leuchtmodus: ");
    Serial.println(Leuchtmodus);

    greenblink(); 

  }

  // Modus 3 = 
  if (Leuchtmodus == 3) {
    Serial.print("Leuchtmodus: ");
    Serial.println(Leuchtmodus);

  }

  // Modus 4 =
  if (Leuchtmodus == 4) {
    Serial.print("Leuchtmodus: ");
    Serial.println(Leuchtmodus);

  }
}





//+++++++++++++++Funktionen +++++++++++++++++

//-------------------------------------------------redblink
void redblink() {

  leds[0] = CRGB::Red;
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(500);

}


//-------------------------------------------------FastLED - colorTemerature
void colorTemperatur() {

  // draw a generic, no-name rainbow
  static uint8_t starthue = 0;
  fill_rainbow( leds + 0, N_PIXELS - 0, --starthue, 20);

  // Choose which 'color temperature' profile to enable.
  uint8_t secs = (millis() / 1000) % (DISPLAYTIME * 2);
  if( secs < DISPLAYTIME) {
    FastLED.setTemperature( TEMPERATURE_1 ); // first temperature
    leds[0] = TEMPERATURE_1; // show indicator pixel
  } 
  else {
    FastLED.setTemperature( TEMPERATURE_2 ); // second temperature
    leds[0] = TEMPERATURE_2; // show indicator pixel
  }

  // Black out the LEDs for a few secnds between color changes
  // to let the eyes and brains adjust
  if( (secs % DISPLAYTIME) < BLACKTIME) {
    memset8( leds, 0, N_PIXELS * sizeof(CRGB));
  }
}

//-------------------------------------------------greenblink
void greenblink() {

  leds[2] = CRGB::Green;
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
  leds[2] = CRGB::Black;
  FastLED.show();
  delay(500);

}

Taster entprellen und DelayWithoutMillis im Playground durchlesen

Hallo,
möglicherweise entsinnst Du Dich noch an meinen Vorschlag, anstelle eines Tasters eine codierten Drehschalter oder so etwas zu verwenden. Dann liest Du am Anfang von loop den Zusrand von beispielsweise drei Eingängen ein, machst daraus eine Zahl (0 bis 7), die dann Dein Leuchtmodus ist. Fertig zum Genießen der NeoPixel!

Du denkst: “Irgendwie muß es doch auch mit einem Taster gehen!” Geht es auch, nur schwieriger. Da mich das als Anfänger auch interessiert, hier meine Lernschritte (IDE 1.5.8; Arduino UNO V3).

  1. Aufgabe: Ich lasse eine LED blinken (Blinksketch mit Änderungen von mir):
// Eine blinkende LED
#define ausgangLED1 6   // UNO Ausgang 

void setup() {
  pinMode(ausgangLED1, OUTPUT);
}

void loop() {
  digitalWrite(ausgangLED1, !digitalRead(ausgangLED1));   // invertiert den Ausgang
  delay(500);              // warten
}

Funktioniert prima beispielsweise für eine Ampelschaltung auf einer Modellbahn.

  1. Aufgabe: Ich lasse zwei LEDs mit unterschiedlicher Frequenz blinken:
// Zwei mit unterschiedlicher Frequenz blinkende LEDs
#define ausgangLED1 6
#define delayLED1 500  // Verzoegerungszeit in Millisekunden
#define ausgangLED2 7
#define delayLED2 100  // Verzoegerungszeit in Millisekunden

unsigned long millisLED1 = millis();
unsigned long millisLED2 = millis();

void setup() {
  pinMode(ausgangLED1, OUTPUT);
  pinMode(ausgangLED2, OUTPUT);
}

void loop() {
  if (millis() > millisLED1 + delayLED1) {                  // Verzoegerungszeit abgelaufen?
    digitalWrite(ausgangLED1, !digitalRead(ausgangLED1));   // invertiert den Ausgang von LED1
    millisLED1 = millis();                                  // neue Zeit merken
  }
  if (millis() > millisLED2 + delayLED2) {
    digitalWrite(ausgangLED2, !digitalRead(ausgangLED2));   // invertiert den Ausgang von LED2
    millisLED2 = millis();
  }
}

Mit delay() funktioniert das nicht mehr. Meine erste Idee war, Interrupts und Timer zu nutzen. Für präzise Zeitmessung geht es wahrscheinlich nicht ohne, aber nach dem Studium verschiedener Forumsbeiträge kann man bei blinkenden LEDs auch mit einer Zählvariablen arbeiten. Zunächst habe ich mir eine eigene definiert (Zaehler++;), alternativ geht es aber auch mit der eingebauten Zählerfunktion millis().

  1. Aufgabe: Tasterentprellung zum sicheren Weiterschalten:
// Zwei mit unterschiedlicher Frequenz blinkende LEDs
// Drei Leuchtmodi, weitergeschaltet mit entprelltem Taster
#define ausgangLED1 6
#define delayLED1 500  // Verzoegerungszeit in Millisekunden
#define ruheLED1 LOW    // Ruhezustand
#define ausgangLED2 7
#define delayLED2 100  // Verzoegerungszeit in Millisekunden
#define ruheLED2 LOW    // Ruhezustand
#define TasterPin 8    // Taster an Pin 8 angeschlossen
#define delayTaster 50 // Verzoegerungszeit in Millisekunden
#define Tasterstatusendwert 10 // Entprellzyklen

unsigned long millisLED1 = millis();
unsigned long millisLED2 = millis();
int Leuchtmodus = 0; // Variable fuer die verschiedenen festgelegten Farben
byte Tasterstatus = 0;
unsigned long millisTaster = 0;

void setup() {
  pinMode(ausgangLED1, OUTPUT);
  pinMode(ausgangLED2, OUTPUT);
  pinMode(TasterPin, INPUT);
  digitalWrite(TasterPin, HIGH); // Pull Up Wiederstand aktivieren, gedrueckter Taster = LOW
}

void loop() {
  if ((digitalRead(TasterPin) == LOW) && (Tasterstatus == 0)) {     // Taster gedrueckt (Flanke HIGH nach LOW)?
    millisTaster = millis();
    Tasterstatus = 1;
  }
  if ((digitalRead(TasterPin) == LOW) && (Tasterstatus > 0) && (Tasterstatus < Tasterstatusendwert) && (millis() > millisTaster + delayTaster)) {   // Taster immer noch gedrueckt?
    millisTaster = millis();
    Tasterstatus++;
  }
  if (Tasterstatus == Tasterstatusendwert) {
    Leuchtmodus++;
    if (Leuchtmodus > 2) {   // Anzahl der Leutmodi begrenzen.
      Leuchtmodus = 0;
    }
    Tasterstatus = 255;    // warten auf Loslassen des Tasters
  }
  if ((digitalRead(TasterPin) == HIGH) && (Tasterstatus == 255)) {  // Taster losgelassen?
    Tasterstatus = 0;
  }

  switch (Leuchtmodus) {
    case 0:                                                     // LED1 blinkt
      if (millis() > millisLED1 + delayLED1) {                  // Verzoegerungszeit abgelaufen?
        digitalWrite(ausgangLED1, !digitalRead(ausgangLED1));   // invertiert den Ausgang von LED1
        millisLED1 = millis();                                  // neue Zeit merken
      }
      digitalWrite(ausgangLED2, ruheLED2);                      // auf definierten Zustand setzen
      break;
    case 1:                                                     // LED2 blinkt
      if (millis() > millisLED2 + delayLED2) {
        digitalWrite(ausgangLED2, !digitalRead(ausgangLED2));   // invertiert den Ausgang von LED2
        millisLED2 = millis();
      }
      digitalWrite(ausgangLED1, ruheLED1);                      // auf definierten Zustand setzen
      break;
    case 2:                                                     // LED1 und LED2 blinken
      if (millis() > millisLED1 + delayLED1) {                  // Verzoegerungszeit abgelaufen?
        digitalWrite(ausgangLED1, !digitalRead(ausgangLED1));   // invertiert den Ausgang von LED1
        millisLED1 = millis();                                  // neue Zeit merken
      }
      if (millis() > millisLED2 + delayLED2) {
        digitalWrite(ausgangLED2, !digitalRead(ausgangLED2));   // invertiert den Ausgang von LED2
        millisLED2 = millis();
      }
      break;
  }
}

Ich hoffe, Du erkennst die grundsätzliche Struktur Deines Programms wieder:
Leuchtmodus 0: LED1 blinkt
Leuchtmodus 1: LED2 blinkt
Leuchtmodus 2: beide LEDs blinken

Schönheit: “#define” sind nach meinem Verständnis Compileranweisungen zur Textersetzung, die der Übersichtlichkeit dienen, aber anders als “const int” keinen Arduino-Speicher verbrauchen. Anstelle vieler “if” habe ich “case” verwendet, macht dasselbe.

Idee Entprellen: Nach einer abfallenden Flanke schaue ich mehrmals nach, ob der Taster immer noch gedrückt ist. Wenn das geschehen ist, wird der Leuchtmodus weitergezählt. Dann warte ich auf das Loslassen des Tasters, um dann wieder auf den nächsten Tastendruck zu warten.

Ich habe das Programm, das hauptsächlich meinem Lernen dienen soll, probiert, es funktioniert für den Spaß an blinkenden LEDs hinreichend gut. Mit den Werten von “delayTaster” und “Tasterstatusendwert” kann man noch spielen, bis sie dem eigenen Empfinden entsprechen.

Wenn Du Zeit hast, suche bitte nach einer besseren Entprellmöglichkeit, es gibt wohl sogar eine Programmbiblioithek dafür, baue sie bei Dir ein und zeige sie mir.

Irgendjemand unterschreibt seine Beiträge mit “Rot ist Blau und Plus ist Minus”. Bei mir könnte stehen: “Fehler gibt’s gratis!” :grin:

agmue: Schönheit: "#define" sind nach meinem Verständnis Compileranweisungen zur Textersetzung, die der Übersichtlichkeit dienen, aber anders als "const int" keinen Arduino-Speicher verbrauchen.

const mit primitiven Datentypen sollte in den meisten Fällen auch kein RAM verbrauchen. Der Compiler merkt i.d.R. dass die Variable nie verändert wird und optimiert sie weg.

Beispiel:

int test = 50;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println(test);
  delay(2000);
}

RAM Vebrauch: 184 Bytes

Änderung:

const int test = 50;

RAM Verbrauch: 182 Bytes

Also genau was man erwartet. const hat den Vorteil, dass es typsicher ist.

Serenifly: const mit primitiven Datentypen sollte in den meisten Fällen auch kein RAM verbrauchen. Der Compiler merkt i.d.R. dass die Variable nie verändert wird und optimiert sie weg. ... Also genau was man erwartet. const hat den Vorteil, dass es typsicher ist.

Ich hatte noch überlegt, es zu testen, aber dann verworfen. Danke! Ohne bionic7 stören und vom eigentlichen Thema ablenken zu wollen: Du hast mich ja nun schon etwas kennengelernt, welches Buch sollte ich mir zum baldigen Geburtstag wünschen? OOP nur, wenn es sein muß, die Sache mit den Pointern würde ich aber doch gerne mal lernen.

@agmue: Bin mir nicht sicher ob du mich meintest bezüglich Buch. Naja ich bin jetzt ca. seit 4 Wochen dabei und habe/hatte weder Beruflich noch Privat mit Elektronik oder Programmierung zu tun, also sprich das ganze ist Neuland für mich.
Ich denke dass ich in diesen Wochen schon einiges gelernt habe, aber auch ebenso viele neue Fragen aufgetaucht sind. Naja im Großen und ganzen kann ich dir nur sagen das du sicher um einiges weiter bist als ich. Also das StarterKit Book und die Galileo Arduino DVD werden dir nicht helfen. Ich schaue mir hauptsächlich Beispiele von http://www.adafruit.com/ an und probiere von hier einige dinge abzuleiten.

möglicherweise entsinnst Du Dich noch an meinen Vorschlag, anstelle eines Tasters eine codierten Drehschalter…

Wäre sicher eine Möglichkeit, aber möchte den Drehschalter erst nach dem Nervenzusammenbruch verwenden. Grund: der Drehschalter im Kit ist hässlich :slight_smile: und ein neuen zu bestellen mit Kleinmengenzuschlag und Porto möchte ich im Moment noch vermeiden.

So… möchte mich zuerst um das Problem 2 kümmern. Ich glaube ich habe das ganze falsch formuliert:

Sagen wir ich möchte 4 unterschiedliche Leuchtprogramme über den Taster starten.
Also 1x Drücken Leuchtprogramm 1, dieses Leuchtprogramm wird solange abgespielt bis ich denn Taster nochmals betätige → dann wird Leuchtprogramm 2 abgespielt.
Das Problem liegt nicht beim entprellen sondern eher aus dem Loop herauszukommen da der Taster ja nicht ständig abgefragt wir.

Mein zwischenstand:
Habe mir Entprellen, Millis und die Case Geschichte angesehen und bin noch über Bounce Library gestolpert, habe hier ein schönes Beispiel gefunden das ich umgeschrieben habe. Die ganzen Neopixel Codes habe ich rausgenommen, somit ist es übersichtlicher für euch und kann auch mit dem Taster und Seriellen Monitor selbst getestet werden.

#include <Bounce2.h>


#define BUTTON_PIN 8
#define LED_PIN 6

// Instantiate a Bounce object
Bounce debouncer = Bounce(); 

int showType = 0;

int buttonState;
unsigned long buttonPressTimeStamp;


void setup() {

  Serial.begin(9600);

  // Setup the button
  pinMode(BUTTON_PIN,INPUT);
  // Activate internal pull-up
  digitalWrite(BUTTON_PIN,HIGH);

  // After setting up the button, setup debouncer
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);

  //Setup the LED
  pinMode(LED_PIN,OUTPUT);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Loop
void loop() {
  // Update the debouncer and get the changed state
  boolean changed = debouncer.update();



  if ( changed ) {
    // Get the update value
    int value = debouncer.read();
    if ( value == HIGH) {

      buttonState = 0;
      Serial.println("Button released (state 0)");

    } 
    else {
      buttonState = 1;
      Serial.println("Button pressed (state 1)");
      buttonPressTimeStamp = millis();

      showType++;
      if (showType > 8) {
        showType=0;
        
      }
      Serial.println(showType);
      startShow(showType);
    }
  }

  if  ( buttonState == 1 ) {
    if ( millis() - buttonPressTimeStamp >= 500 ) {
      buttonPressTimeStamp = millis();
      
   
     
      Serial.println("Retriggering button");
    }
  }
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Case
void startShow(int i) {
  switch(i){
case 0: aus();
  Serial.println("modus 0");
  break;
case 1: redblink();
  Serial.println("modus 1");
  break;
case 2: blueblink();
  Serial.println("modus 2");
  break;
  }
}



void aus() {
  Serial.println("aus");
}

void redblink() {
  Serial.println("red");
}

void blueblink() {
  Serial.println("blue");
}

Nun, das Problem ist im Moment noch bestehend. Auch hier müsste ich warten bis das Leuchtprogramme zu ende wäre damit der Taster wieder abgefragt wird.
Und eigentlich möchte ich, dass sich das Leuchtprogramm solange abspielt bis der Taster erneut gedrückt wird.

Ich glaube man könnte so was mit DoWhile Funktionen lösen?
Muss mich hier aber noch besser einlesen → Tipps gerne Willkommen.

bionic7: @agmue: Bin mir nicht sicher ob du mich meintest bezüglich Buch.

Eigentlich meinte ich Serenifly, da er mich schon mehrfach freundlich korrigiert hat. Das finde ich auch gut, besser wäre aber, ich wüßte mehr über Pointer usw. Die Bücher "Einführung in ..." sind wohl nichts mehr für mich, denke ich. Meine Anfänge (#69) liegen noch nicht lange zurück, der "Vorsprung" beträgt, wenn überhaupt, nur einen Hauch. Ich hoffe, ein Nervenzusammenbruch bleibt Dir erspart! Die Bounce Library scheint interessant zu sein, werde mal nach ihr suchen. Darf ich davon ausgehen, das Programm "ohne ganzen Neopixel Codes" funktioniert?

//-------------------------------------------------redblink
void redblink() {

  leds[0] = CRGB::Red;
  FastLED.show();
  delay(500);
  // Now turn the LED off, then pause
  leds[0] = CRGB::Black;
  FastLED.show();
  delay(500);

}

Hast Du die delay() noch drin?

Du musst nicht suche: Hier der Link

Darf ich davon ausgehen, das Programm “ohne ganzen Neopixel Codes” funktioniert?

Die Bounce Library sowiso und mein Zwischenstand im Post oben auch. Habe alle Neopixels entfernt, der Rückgabewert kanst du über Serial Monitor verfolgen.

Ja der Delay ist noch drin.

Mein gedanke war, das ich im Leuchtprogramm im Beispiel “redblink” ausgeführt wird solange (while) Tasterstatus (showType) gleich 1 ist. Nun leider entkomme ich dem While Loop nicht. :’(

void redblink() {
  do {
  Serial.println("red");
  }
  while (showType == 1);
  Serial.println("while schleife ist:");
 Serial.println(showType);
}

Lerne es, nicht blockierenden Code zu schreiben. Dazu gehört in dem meisten Fällen jegliche Art von delays zu unterbinden. es gibt nur wenige Anwendungsfälle wo delay aktzeptabel und sinnvoll ist. Das ist keiner.

While-Schleifen sind auch nicht immer eine sinnvolle Idee wenn es schwer ist, aus dieser herauszukommen.

In deinem Fall klappt es nicht, da showType sobald es einmal 1 ist, nicht mehr auf 0 fällt. Denn du bist in der while Schleife gefangen. Da wird dein restlicher Code nicht mehr ausgeführt, ua. die Erkennung ob ein Taster gedrückt wird oder nicht.

Edit:

Wo und wie wird showType defeniert und gesetzt?

Wo und wie wird showType defeniert und gesetzt?

Wird im Loop gesetzt

    else {
      buttonState = 1;
      Serial.println("Button pressed (state 1)");
      buttonPressTimeStamp = millis();

      showType++;
      if (showType > 8) {
        showType=0;

      }
      Serial.println(showType);
      startShow(showType);
    }
  }

und an startShow übergeben ->

void startShow(int i) {
  switch(i){
  case 0:
    aus(); 
    Serial.println("modus 0");
    break;
    
  case 1: 
  while(showType == 1) {
    redblink();
    loop();
  }
    Serial.println("modus 1");
    break;
    
  case 2: 
    blueblink();
    Serial.println("modus 2");
    break;
  }
}

Habe die while Schleife jetzt hier eingefügt + noch die "loop" abfrage -> so komme ich jetzt wieder aus der While raus.

Du hast recht das grosse Problem ist die "delay" funktion. Die einzelnen Pixel brauchen leider diese Zeit um sich von links nach rechts zu bewegen. Wüsste gar nicht ob man dies ohne "delay" überhaupt machen könnte.

bionic7:
Wüsste gar nicht ob man dies ohne “delay” überhaupt machen könnte.

Hier mein Versuch, ausgehend von #5, zur kritischen Beurteilung (habe jetzt leider keine Zeit zur Kommentierung):

#include <Bounce2.h>


#define BUTTON_PIN 8
#define LED_PIN 6

// Instantiate a Bounce object
Bounce debouncer = Bounce(); 

int showType = 0;

int buttonState;
unsigned long buttonPressTimeStamp;
unsigned long altmillis = 0;
byte prgStatus = 255;

void setup() {

  Serial.begin(9600);

  // Setup the button
  pinMode(BUTTON_PIN,INPUT);
  // Activate internal pull-up
  digitalWrite(BUTTON_PIN,HIGH);

  // After setting up the button, setup debouncer
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);

  //Setup the LED
  pinMode(LED_PIN,OUTPUT);

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Loop
void loop() {
  // Update the debouncer and get the changed state
  boolean changed = debouncer.update();



  if ( changed ) {
    // Get the update value
    int value = debouncer.read();
    if ( value == HIGH) {

      buttonState = 0;
      Serial.println("Button released (state 0)");

    } 
    else {
      buttonState = 1;
      Serial.println("Button pressed (state 1)");
      buttonPressTimeStamp = millis();

      showType++;
      if (showType > 2) {
        showType=0;
      }
      prgStatus = 0;
      Serial.print("Type: ");
      Serial.println(showType);
      
    }
  }

  if  ( buttonState == 1 ) {
    if ( millis() - buttonPressTimeStamp >= 500 ) {
      buttonPressTimeStamp = millis();
      
   
     
      Serial.println("Retriggering button");
    }
  }
  startShow(showType);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Case
void startShow(int i) {
  switch(i){
case 0: aus();
//  Serial.println("modus 0");
  break;
case 1: redblink();
//  Serial.println("modus 1");
  break;
case 2: blueblink();
//  Serial.println("modus 2");
  break;
  }
}



void aus() {
//  Serial.println("aus");
}

void redblink() {
  if (prgStatus == 0) {
    Serial.println("red 1");
    altmillis = millis();
    prgStatus++;
  }
  if ((prgStatus == 1) && (millis() > altmillis + 3000)) {
    Serial.println("red 2");
    altmillis = millis();
    prgStatus++;
  }
  if ((prgStatus == 2) && (millis() > altmillis + 3000)) {
    Serial.println("red fertig");
    altmillis = millis();
    prgStatus++;
  }
}

void blueblink() {
//  Serial.println("blue");
}

Habe es getestet -> funktioniert mit den Pixeln auch nicht so wie gewünscht.

Naja ich füge jetzt mal alle Codes zusammen und schau mal ob ich mit den Pausen leben kann. Wenn nicht, dann komme ich auf den Drehschalter zurück ;)

Kleiner Nachtrag falls jemand interessiert ist.

Bei denn meisten Funktionen komme ich ohne Probleme raus. Nur bei einer Funktion ist es etwas knifflig. Ich umgehe dieses Problem wie folgt: Wenn der Button länger gedrückt wird, wird der Tastersatus auch um 1 erhöht aber nur wenn genau dieser Modus zutrifft.

Bei meinem Beispiel habe ich in direkt auf 3 gesetzt, mann könnte in auch um eins erhöhen und evtl. ein delay, damit nicht mehrere übersprungen werden.

void loop() {
  // Update the debouncer and get the changed state
  boolean changed = debouncer.update();



  if ( changed ) {
    // Get the update value
    int value = debouncer.read();
    if ( value == HIGH) {

      buttonState = 0;
      Serial.println("Button released (state 0)");

    } 
    else {
      buttonState = 1;
      Serial.println("Button pressed (state 1)");
      buttonPressTimeStamp = millis();

      showType++;
      if (showType > 8) {
        showType=0;
        
      }
      Serial.println(showType);
      startShow(showType);
    }
  }

  if  ( buttonState == 1 ) {
    if ( millis() - buttonPressTimeStamp >= 2000 ) {
      buttonPressTimeStamp = millis();
      if (showType == 2) {
        showType = 3;
        startShow(showType);
       }
   
     
      Serial.println("Retriggering button");
    }
  }
}