Nach Tastendruck Drehschalter auswerten

agmue:
Tausche fünf digitale Eingänge gegen einen analogen und 80 µs. Ich habe halt mit einem ATtiny angefangen :slight_smile:

Das verstehe ich jetzt nicht. Die analogen Eingänge des Attiny lassen sich doch auch als digitale Eingänge verwenden.

Gruß Tommy

Meine Vorstellung ist so:

schalter.png

Fünf Schalterstellungen benötigen nicht fünf digitale sondern nur einen analogen Eingang.

Ach das meinst Du. Wenn genügend Eingänge frei sind, würde ich trotzdem die 5 digitalen Eingänge vorziehen. Wenn man diese dann noch auf einen Port legt, ergibt das eine schnelle Lösung.

Gruß Tommy

Ich stimme Dir vollkommen zu, wollte das absolute Wort "iimmer" ja auch nur durch das empfehlende "vorzugsweise" ersetzt haben.

Diese Formulierung von einem Schüler hätte ich überlesen, aber Uwe kennt den sprachlichen Unterschied in der Bedeutung, weshalb ich Absicht vermute. Außerdem hat die Aussage eines Brattain Member besonderes Gewicht, da bin ich dann möglicherweise etwas zu pingelig.

Dein Signal aus #21 ist aber letztendlich ein analoges Signal durch die Widerstandskette.

Ich kann mir immer noch keine sinnvolle Lösung vorstellen, bei der es besser wäre, ein rein binäres Signal analog einlesen zu wollen.

Gruß Tommy

agmue:
Tausche fünf digitale Eingänge gegen einen analogen und 80 µs. Ich habe halt mit einem ATtiny angefangen :slight_smile:

In Diesem Fall hast Du kein digitales Signal sondern machst Du mit einem Spannungsteiler mit mehreren Widerständen und mehreren Schaltern ein analoges Signal. Da braucht es einen analogen Eingang (oder theoretisch gesprochen weil praktisch diskret aufgebaut zu aufwändig einen weiteren Spannungsteiler und viele Komparatoren, was dann aber ein einfacher AD/Wandler ist).
In dem von Dir beschriebenen Fall gebe ich dir recht, es brauchst einen analogen Eingang für ein analoges Signal (Signal mit mehreren diskreten Spannungspegeln).

Ich verstehe unter digitalem Signal ein Signal das 2 Zustände hat (HIGH und LOW).
Grüße Uwe

Hallo Micha,
hab da was gebastelt. Versuche es mal damit und gib mir bescheid, wo es noch hakt.
Deine Taster musst du an folgende Digital-Pins anschliessen:
"Links" = Digi PIN 3
"Stop" = Digi PIN 4
"Rechts" = Digi PIN 5
Ich habe nur 2 Schalterstellungen mit aktiven Funktionen belegt.

  1. Die Stellung 1 macht ein Lauflicht bei dem drei LED's (blau , grün rot) je nach Richtungstaste, entweder von links nach rechts oder umgekehrt laufen.
  2. die Stellung 5 zeigt Dein (ruhendes) Lichtband auch jeweils Abhängig von der Richtungstaste links oder rechts von der Mitte.
    Ich habe das ganze so gelöst, wie Du wolltest: Richtungstaste drücken, Drehschalter wird eingelesen und der Lichteffekt gestartet. Wen du die Richtungstaste nochmals drückst (egal ob links oder rechts) stoppt der Lichteffekt und der Strip wird gelöscht.
    Drückst Du nun wieder eine der Richtungstasten wird wieder der Drehschalter gelesen und der entsprechende Effekt gestartet.
    drückst Du auf "Stop" wird ein laufender Lichteffekt sofort gestoppt, und dann das rote 'Stop'-Band angezeigt.

Sorry, ich musste den Code als Anhang beifügen.

Ich hoffe, Du kanns was damit anfangen.
Ich weiss, der Code ist sicher nicht die eleganteste Lösung, und vele hier könnten das 100 x besser programmieren. aber falls es Dir hilft und stabil läuft, ist ja schon mal ne gewisse Basis da.

LG Stefan

Micha_Eisbahn.ino (9.02 KB)

Warum stellst Du den Code nicht für alle lesbar hier in Codetags ein (</> oben links das kannst Du bei Edit auch noch ändern)

Gruß Tommy

Tommy56:
Warum stellst Du den Code nicht für alle lesbar hier in Codetags ein (</> oben links das kannst Du bei Edit auch noch ändern)

Gruß Tommy

Oh wie dumm von mir!

Ah, jetzt weiss ich es wieder : The message exceeds the maximum allowed length (9000 characters).

LG Stefan

OK. ich Teile den Code auf 2 Teile auf.
Teil 1 - >

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(36, PIN, NEO_GRB + NEO_KHZ800);

const int dsIPin[5] = {8,9,10,11,12}; // drehschalterInputPins
byte lichtEffekt = 0;                 // kein Lichteffekt gewählt 
byte Dir = 0;                         // Dir = die Bewegungsrichtung des Lauflichts. (-1 = links; 0 = stop; +1 = rechts)
byte Step = 1;                        // Schrittweite, zeigt an um wieviele pixel das Lauflicht in einem Schritt wandert               
bool Init = true;                     // Init aktiviert die initialisierung des jeweiligen Lichteffektes
bool keyRelease = true;               // ist true,wenn Taste wieder losgelassen wurde
bool llichtRun = false;               // wird benutzt um zu unterscheiden ob Richtungstaste das Erste oder Zweite mal gderueckt
int Interval = 0;                     /* Verzögerung beim Lauflicht in Millisekunden Von einem Pixel zum nächsten. 
                                         (0=kein lauflicht) je kleiner der Wert, desto schneller läuft das Lauflicht. */
unsigned long IntervalStart;  
                                   
void setup() {
 IntervalStart = millis(); 
  strip.begin();
  strip.show();

  pinMode(3,INPUT_PULLUP);          // Taste LINKS, mit internem pullup Widerstand
  pinMode(4,INPUT_PULLUP);          // Taste STOP,  mit internem pullup Widerstand
  pinMode(5,INPUT_PULLUP);          // Taste RECHTS, mit internem pullup Widerstand
  for (int i=0; i<5; i++){
    pinMode(dsIPin[i],INPUT_PULLUP);   // Pins an denen der Drehschalter hängt auf Input und Pullup-Widerstand einschalten
  }
}

void loop() {
  if(readButton(3)) {
    if (llichtRun == false && keyRelease == true) {         // Taste das erste mal gedrückt 
        lichtEffekt = readDSwitch();  // lichtEffekt erhält die Position des Drehschalters. (1-5) 
        Init = true;                  // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = 1;                      // "Links"
        callLichtEffekt(lichtEffekt); // Lichteffekt ausführen
        llichtRun = true;             // merken dass lichteffekt gestartet
        keyRelease = false;           // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true && keyRelease == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                   // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                        // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                   // Strip löschen
      lichtEffekt = 0;                // Kein LichtEffekt gewählt
      llichtRun = false;              // Taste für erneuten start vorbereiten
    }
  }
  
  if(readButton(4) && keyRelease == true) {   // "Stop" - Taste gedrückt
    Interval = 0;                     // Interval aussschalten , Lauflicht anhalten
    Dir = 0;                          // Richtung auf 0 ( keine Laufrichtung)
    stop();                           // 'Stopp'-Band anzeigen
    keyRelease = false;               // Taste noch nicht wieder losgelassen
    llichtRun = false;                // Richtungstasten für erneuten Start vorbereiten
    lichtEffekt = 0;                  // Kein LichtEffekt gewählt
  }
  
  if(readButton(5)) {
    if (llichtRun == false && keyRelease == true) {         // Taste das erste mal gedrückt 
        lichtEffekt = readDSwitch();   // lichtEffekt erhält die Position des Drehschalters. (1-5) 
        Init = true;                   // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = -1;                      // "Links"
        callLichtEffekt(lichtEffekt);  // Lichteffekt ausführen
        llichtRun = true;              // merken dass lichteffekt gestartet
        keyRelease = false;            // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true && keyRelease == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                    // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                         // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                    // Strip löschen
      lichtEffekt = 0;                 // Kein LichtEffekt gewählt
      llichtRun = false;               // Taste für erneuten start vorbereiten
    } 
  }

  if ((readButton(3) + readButton(4) + readButton(5) == 0) && keyRelease == false) keyRelease = true; /* gedrückte Taste 
                                                                                                        wurde losgelassen */
  
  if (Interval && (millis() - IntervalStart >= Interval)) callLichtEffekt(lichtEffekt);     /* bei laufenden Lichtern 
                                                                                              nächsten Schritt ausführen */
}
//Ende der Schleife (loop)

//
byte readDSwitch() {                       // Fragt den Drehschalter ab
  byte dsp=0;                              // hilfsvariable DrehSchalterPosition
  for(int n=0; n<5; n++) {
    if(digitalRead(dsIPin[n]) == LOW) {    // DrehSchalterInputs nacheinander abfragen, wenn LOW, Schalterposition gefunden
      dsp = n+1;                           // dsp bekommt nun den Positionswert (1-5)  
      break;                               // Schleife verlassen, weil Pos gefunden
    }
  }
  return dsp;                              //Positionswert zurückgeben
}

//
int readButton(int pin) {        // Taste einlesen
  if(digitalRead(pin) == LOW) {  // Analog Eingang abfragen
    delay(150);                  // Wartezeit zum erneut abfragen
    if(digitalRead(pin) == LOW)  // Analog Eingang erneut abfragen
      return 1;                  // war gedrückt
  }
      return 0;                  // war nicht gedrückt
}


// Strip löschen (all LED's off)
void clearStrip() {
   for(int i=0; i<strip.numPixels(); i++) {        // Schleife in der Länge des NeoPixel-Strip
    strip.setPixelColor(i,strip.Color(0,0,0));     // Pixel Ausschalten
    strip.show();
   }  
}
//

// Funktion STOP
// zuerst alle Pixel aus, dann die mittleren 6 auf Rot
void stop() {
  clearStrip();                     // Habe das löschen des Strip's in eine eigene Funktion gepackt, da mehrfach benötigt.
 
  for(int i=0; i<6; i++) {
    strip.setPixelColor(15+i,strip.Color(150,0,0));
    strip.show();
   }
}

void callLichtEffekt(byte LiEf) {    // LiEf enthält die Nummer der auszuführenden Funktion
  switch(LiEf){
    case 1:
    run3Points();
    break;

    case 2:
    // Lichteffekt 2 ausführen
    lichtEffekt2();
    break;

    case 3:
    // Lichteffekt 3 ausführen
    lichtEffekt3();
    break;

    case 4:
    // Lichteffekt 4 ausführen
    lichtEffekt4();
    break;

    case 5:
    richtung();
    break; 
  }
  IntervalStart = millis();
}
//

-> ende Teil 1

Teil 2 ->

// Funktion run3Points    3 Pixel (blau grün rot) laufen von links nach rechts / rechts nach links wobei blau der Kopf ist.
void run3Points() {
    static byte count = 0;   // Zähler für die Anzahl Schritte die gelaufen sind (damit nichts übers stripende hinausläuft
    static byte sPixel = 0;                       // am linken ende des Strip beginnen.
    static byte pixelPos = sPixel;                // absolute Position im Strip
  if (Init == true) {
     clearStrip();
     if (Dir < 0) sPixel = strip.numPixels() -1;  // am Rechten ende des Strip beginnen.
    Step = 1;
    Interval = 120;                               // 120 ms bis zum Nächsten Schritt (kannst Du nach Geschmack einstellen
  }
    if (count) { 
        strip.setPixelColor(pixelPos - Dir,strip.Color(0,0,0)); // Das letzte Pixel löschen
        strip.show(); 
    }
    pixelPos += (Dir*Step);                       // Position um schrittweite weiter (vor oder zurück)
    count += Step;                                // Zähler um schrittweite erhöhen 
    if (count == strip.numPixels()) {             // prüfen ob Stripende erreicht  
      pixelPos = sPixel;                          // pixelPos wieder auf Start
      count = 0;                                  // Schritt-Zaehler auf 0
    }
    strip.setPixelColor(pixelPos,strip.Color(170,0,0));             // Hinteres, rotes Pixel ausgeben
    strip.setPixelColor(pixelPos + Dir,strip.Color(0,170,0));       // mitleres grünes Pixel ausgeben
    strip.setPixelColor(pixelPos + (2*Dir),strip.Color(0,0,170));   // vorderstes blaues Pixel ausgeben
    strip.show();  
}
//


// Funktion Lichteffekt 2
void lichtEffekt2() {
  
}
//


// Funktion Lichteffekt 3
void lichtEffekt3() {
  
}
//


// Funktion Lichteffekt 4
void lichtEffekt4() {
  
}
//


// Funktion Richtung
void richtung() {
   if (Init == false) return;                   // Fuktion nur einmal nach Anwahl ausführen!
   Init = false;
   Interval = 0;                                // Kein Interval, ruhendes Licht.
   uint8_t startpixel = 0;                      // Für Taste  "Links"
   if(Dir < 0) startpixel = 21;                 // wenn Taste "Rechts" gedrückt
   for(int i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i,strip.Color(0,0,0));
    strip.show();
   }
 
  for(int i=0; i<15; i++) {
    strip.setPixelColor(startpixel+i,strip.Color(0,0,150));
    strip.show();
   }
}

-> ende Teil 2

LG Stefan

@Deltaflyer: danke.

Guß Tommy

Sorry, hab grad gesehen, im angehängten Sketch ist im Setup nuch ein 'Serial.begin(9600);' drin, das kann natürlich Ersatzlos raus.
Ich hab den Anhang durch die korrigierte Version ersetzt.

@Tommy
Gern geschehen.

LG Stefan

Tommy56:
Ich kann mir immer noch keine sinnvolle Lösung vorstellen, bei der es besser wäre, ein rein binäres Signal analog einlesen zu wollen.

Ich auch nicht. Es muß sich also um irgendein Mißverständnis handeln. Also nochmal das Thema durchgelesen, dann stoße ich auf diese Stelle:

  pinMode(A0,INPUT);          // Taste LINKS
  digitalWrite(A0,HIGH);      // interner pullup Widerstand
...
    if(analogRead(pin) < 500) // Analog Eingang erneut abfragen
      return 1;               // war gedrückt

Da könnte ich mir vorstellen: "Die Pins des Arduino können verschieden genutzt werden. So kann A0 als analoger oder als vierzehnter digitaler Eingang verwendet werden. Bei einem digitalen Signal (Taster) wäre daher digitalRead(A0) oder digitalRead(14) vorzuziehen."

An dieser Stelle darf ich noch auf meinen Vorschlag #14 hinweisen. Aber der Sketch von Stefan sieht auf den ersten Blick auch interessant aus, den schaue ich mir mal genauer an :slight_smile:

Danke agmue,
hoffe mein sketch hält auch noch nem 2. Blick stand. Ja ich weiss, die Tasterabfrage hätte man noch um einiges besser schreiben können, dann hät ich mir da auch noch ne Variable sparen können. Aber ich wollte bewusst menen Teil des Sketches auf Micha's Basis aufbauen. Drum hab ich auch die Abfrage der Taster und Entprellung mit dem 'Delay 150' so drin gelassen und lediglich die Erkennung, ob Taster das erste oder zweite mal gedrückt, und ob der taster wieder freigegeben worden ist, hinzugefügt.
Micha wollte ja: Richtungstaster 1. mal Drücken ->Drehschalter Position einlesen, und entsprechend Position einen Lichteffekt ausführen. Taster 2. mal drücken -> LichtEffekt stoppt. Beim nächsten Drücken eines Richtungs-Tsters wird dann wieder der Drehschalter ausgelesen..... Bei drücken der STOP-Taste wird ein eigener Effekt auf dem Strip angezeigt. Ich hab das so kombiniert, dass damit alles wieder auf Anfang gestellt wird, also die Stop-Taste pausiert den gerade laufenden Lichteffekt nicht, sondern beendet ihn. Somit sollten immer definierte Verhältnisse herschen.

Aber sicher ist mein Sketch noch verbesserungs fähig, aber Micha soll ja auch noch was zu tun haben. Ausserdem sind ja noch drei Lichteffekte, für die ich lediglich ein leeres 'void' drin habe, wo sich micha drin austoben kann.

LG Stefan

Ich bekomme ein paar Warnungen:

In function 'void loop()':
85:48: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
In function 'void clearStrip()':
115:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
In function 'void run3Points()':
170:16: warning: comparison is always false due to limited range of data type [-Wtype-limits]
In function 'void richtung()':
219:13: warning: comparison is always false due to limited range of data type [-Wtype-limits]
220:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

Nach links läuft ein blauer, grüner und roter Pumkt. Bei Stopp sind 6 Lichtpunkte in der Mitte rot. Bei Rechts blinkt NeoPixel 0 rot, da stimmt noch was nicht. Das könnte mit der Warnung zusammenhängen.

Außerdem habe ich den Effekt, daß das Lauflicht durch einen gedrückten Taster gebremst wird. delay(150); dürfte dafür der Grund sein.

Wenn Du nach Anregungen suchst, darfst Du gerne bei #14 spicken, dafür habe ich es geschrieben.

OK, das mit den Warnungen und der Laufrichtung rechts schau ich mir nochmals an.
Wenn ein taster gedrückt wird, sollte das Lauflicht stehen bleiben, resp, der Strip gelöscht werden.
Hier dürfte das Delay das Lauflicht eigentlich gar nicht stören.

Mach mich gleich an die Arbeit.

LG Stefan.

So, hab die Warnungen jetzt eliminiert. Ausserdem fatte ich noch nen Fehler in der Tasten-Steuerung drin.
Das Lauflicht hab ich auch noch etwas korrigiert.

Jetzt läuft der code.

LG Stefan

Micha_Eisbahn.ino (9.75 KB)

Korrigiert!
Teil1 ->

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(36, PIN, NEO_GRB + NEO_KHZ800);

const int dsIPin[5] = {8,9,10,11,12}; // drehschalterInputPins
byte lichtEffekt = 0;                 // kein Lichteffekt gewählt 
int Dir = 0;                         // Dir = die Bewegungsrichtung des Lauflichts. (-1 = links; 0 = stop; +1 = rechts)
byte Step = 1;                        // Schrittweite, zeigt an um wieviele pixel das Lauflicht in einem Schritt wandert               
bool Init = true;                     // Init aktiviert die initialisierung des jeweiligen Lichteffektes
bool keyRelease = true;               // ist true,wenn Taste wieder losgelassen wurde
bool llichtRun = false;               // wird benutzt um zu unterscheiden ob Richtungstaste das Erste oder Zweite mal gderueckt
unsigned int Interval = 0;                     /* Verzögerung beim Lauflicht in Millisekunden Von einem Pixel zum nächsten. 
                                         (0=kein lauflicht) je kleiner der Wert, desto schneller läuft das Lauflicht. */
unsigned long IntervalStart;  
                                   
void setup() {
 IntervalStart = millis(); 
  strip.begin();
  strip.show();

  pinMode(3,INPUT_PULLUP);          // Taste LINKS, mit internem pullup Widerstand
  pinMode(4,INPUT_PULLUP);          // Taste STOP,  mit internem pullup Widerstand
  pinMode(5,INPUT_PULLUP);          // Taste RECHTS, mit internem pullup Widerstand
  for (int i=0; i<5; i++){
    pinMode(dsIPin[i],INPUT_PULLUP);   // Pins an denen der Drehschalter hängt auf Input und Pullup-Widerstand einschalten
  }
}

void loop() {
  if(keyRelease == true && readButton(3)) {
    if (llichtRun == false) {         // Taste das erste mal gedrückt 
        lichtEffekt = readDSwitch();  // lichtEffekt erhält die Position des Drehschalters. (1-5) 
        Init = true;                  // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = 1;                      // "Links"
        callLichtEffekt(lichtEffekt); // Lichteffekt ausführen
        llichtRun = true;             // merken dass lichteffekt gestartet
        keyRelease = false;           // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true && keyRelease == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                   // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                        // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                   // Strip löschen
      lichtEffekt = 0;                // Kein LichtEffekt gewählt
      llichtRun = false;              // Taste für erneuten start vorbereiten
      keyRelease = false;             // Taste noch nicht wieder losgelassen
    }
  }
  
  if(readButton(4) && keyRelease == true) {   // "Stop" - Taste gedrückt
    Interval = 0;                     // Interval aussschalten , Lauflicht anhalten
    Dir = 0;                          // Richtung auf 0 ( keine Laufrichtung)
    stop();                           // 'Stopp'-Band anzeigen
    keyRelease = false;               // Taste noch nicht wieder losgelassen
    llichtRun = false;                // Richtungstasten für erneuten Start vorbereiten
    lichtEffekt = 0;                  // Kein LichtEffekt gewählt
    keyRelease = false;               // Taste noch nicht wieder losgelassen
  }
  
  if(keyRelease == true && readButton(5)) {
    if (llichtRun == false) {         // Taste das erste mal gedrückt 
        lichtEffekt = readDSwitch();   // lichtEffekt erhält die Position des Drehschalters. (1-5) 
        Init = true;                   // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = -1;                      // "Links"
        callLichtEffekt(lichtEffekt);  // Lichteffekt ausführen
        llichtRun = true;              // merken dass lichteffekt gestartet
        keyRelease = false;            // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                    // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                         // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                    // Strip löschen
      lichtEffekt = 0;                 // Kein LichtEffekt gewählt
      llichtRun = false;               // Taste für erneuten start vorbereiten
      keyRelease = false;  
    } 
  }
  if (!keyRelease) {
      if (readButton(3)==0 && readButton(4)==0 && readButton(5)==0) keyRelease = true; /* gedrückte Taste 
                                                                                         wurde losgelassen */
  }
 // else     // Wenn Du dieses 'else' aktivierst läuft das Licht erst NACH loslassen der Taste los!! 
           // So läuft es etwas Langsamer los und erreicht das eingestellte Tempo nachlLoslassen der Taste!
  if (Interval && (millis() - IntervalStart >= Interval)) callLichtEffekt(lichtEffekt);     /* bei laufenden Lichtern 
                                                                                              nächsten Schritt ausführen */
}
//Ende der Schleife (loop)

//
byte readDSwitch() {                       // Fragt den Drehschalter ab
  byte dsp=0;                              // hilfsvariable DrehSchalterPosition
  for(int n=0; n<5; n++) {
    if(digitalRead(dsIPin[n]) == LOW) {    // DrehSchalterInputs nacheinander abfragen, wenn LOW, Schalterposition gefunden
      dsp = n+1;                           // dsp bekommt nun den Positionswert (1-5)  
      break;                               // Schleife verlassen, weil Pos gefunden
    }
  }
  return dsp;                              //Positionswert zurückgeben
}

//
int readButton(int pin) {        // Taste einlesen
  if(digitalRead(pin) == LOW) {  // Analog Eingang abfragen
    delay(150);                  // Wartezeit zum erneut abfragen
    if(digitalRead(pin) == LOW)  // Analog Eingang erneut abfragen
      return 1;                  // war gedrückt
  }
      return 0;                  // war nicht gedrückt
}


// Strip löschen (all LED's off)
void clearStrip() {
   for(uint8_t i=0; i<strip.numPixels(); i++) {        // Schleife in der Länge des NeoPixel-Strip
    strip.setPixelColor(i,strip.Color(0,0,0));     // Pixel Ausschalten
   } 
   strip.show(); 
}
//

// Funktion STOP
// zuerst alle Pixel aus, dann die mittleren 6 auf Rot
void stop() {
  clearStrip();                     // Habe das löschen des Strip's in eine eigene Funktion gepackt, da mehrfach benötigt.
 
  for(int i=0; i<6; i++) {
    strip.setPixelColor(15+i,strip.Color(150,0,0));
    strip.show();
   }
}

void callLichtEffekt(byte LiEf) {    // LiEf enthält die Nummer der auszuführenden Funktion
  switch(LiEf){
    case 1:
    run3Points();
    break;

    case 2:
    // Lichteffekt 2 ausführen
    lichtEffekt2();
    break;

    case 3:
    // Lichteffekt 3 ausführen
    lichtEffekt3();
    break;

    case 4:
    // Lichteffekt 4 ausführen
    lichtEffekt4();
    break;

    case 5:
    richtung();
    break; 
  }
  IntervalStart = millis();
}
//

Und hier Teil 2 ->

// Funktion run3Points    3 Pixel (blau grün rot) laufen von links nach rechts / rechts nach links wobei blau der Kopf ist.
void run3Points() {
    static byte count;        // Zähler für die Anzahl Schritte die gelaufen sind (damit nichts übers stripende hinausläuft
    static uint8_t sPixel;                           // am linken ende des Strip beginnen.
    static uint8_t pixelPos;                         // absolute Position im Strip
  if (Init == true) {
     clearStrip();
     count = 0;
     sPixel = 0;
     if (Dir < 0) sPixel = strip.numPixels() -1;  // am Rechten ende des Strip beginnen.
     pixelPos = sPixel;
     Step = 1;
     Interval = 120;                               // 120 ms bis zum Nächsten Schritt (kannst Du nach Geschmack einstellen
  }
  if (count) { 
      strip.setPixelColor(pixelPos - Dir   ,strip.Color(0,0,0));       // Das letzte Pixel löschen
      strip.show(); 
  }
  else {
      strip.setPixelColor(0,strip.Color(0,0,0));                      // am untren Ende verbleibendes Pixel löschen
      strip.setPixelColor(strip.numPixels()-1,strip.Color(0,0,0));    // am oberen Ende verbleibendes Pixel löschen
      strip.show();
   }

    strip.setPixelColor(pixelPos,strip.Color(170,0,0));             // Hinteres, rotes Pixel ausgeben
    strip.setPixelColor(pixelPos + Dir,strip.Color(0,170,0));       // mitleres grünes Pixel ausgeben
    strip.setPixelColor(pixelPos + (2*Dir),strip.Color(0,0,170));   // vorderstes blaues Pixel ausgeben
    strip.show(); 
        
    pixelPos += (Dir*Step);                       // Position um schrittweite weiter (vor oder zurück)
    count += Step;                                // Zähler um schrittweite erhöhen 
   
    if (count == strip.numPixels()) {             // prüfen ob Stripende erreicht  
      pixelPos = sPixel;                          // pixelPos wieder auf Start
      count = 0;                                  // Schritt-Zaehler auf 0
    }
 Init = false;
}
//


// Funktion Lichteffekt 2
void lichtEffekt2() {
  
}
//


// Funktion Lichteffekt 3
void lichtEffekt3() {
  
}
//

LG Stefan