Arduino: Programmiertechniken/Entwicklung

Aufgabenstellung

Bearbeiten
  • Solange ein Taster gedrückt ist, sollen 5 WS2812 LEDs mit 1000ms blinken. Wenn der Taster losgelassen wird, soll die ggf. laufende "AN"-Phase nicht abgebrochen werden. Danach sollen die LEDs aus sein.
  • Parallel dazu soll mit einem 2. Taster eine 6. LED ein und ausgeschaltet werden können. Sie soll dabei "soft" an und aus gehen.

Um das zu lösen, bieten sich kleine Schritte an.

Benötigtes Material

Bearbeiten
  • Nano oder UNO
  • 1k Widerstand
  • 2 Taster
  • WS2812b LED Stripe mit mindestens 6 LEDs

1. Schritt: Beispiel für WS2812 LED suchen

Bearbeiten

Ein guter Weg ist immer Google. Mit der Eingabe von "ws2812b arduino sketch" kommt man zu der guten Grundlagenseite https://funduino.de[1].
Dort wird erklärt, das zuerst die "NeoPixel" Bibliothek eingebunden werden muss.
Nachdem die Bibliothek in der IDE installiert wurde, finden wir dort den folgenden Code als erstes Beispiel:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9        // Hier wird angegeben, an welchem digitalen Pin die WS2812 LEDs bzw. NeoPixel angeschlossen sind
#define NUMPIXELS 40 // Hier wird die Anzahl der angeschlossenen WS2812 LEDs bzw. NeoPixel angegeben
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int pause = 100;     // 100 Millisekunden Pause bis zur Ansteuerung der nächsten LED.

void setup(){
  pixels.begin();    // Initialisierung der NeoPixel
}

void loop(){
  pixels.setPixelColor(1, pixels.Color(0, 255, 0)); // Pixel1 leuchtet in der Farbe Grün
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
  pixels.setPixelColor(2, pixels.Color(0, 150, 0)); // Pixel2 leuchtet in der Farbe Grün
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
  pixels.setPixelColor(3, pixels.Color(0, 50, 0)); // Pixel3 leuchtet in der Farbe Grün
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
  pixels.setPixelColor(4, pixels.Color(0, 10, 0)); // Pixel4 leuchtet in der Farbe Grün
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
  pixels.setPixelColor(5, pixels.Color(0, 1, 0)); // Pixel5 leuchtet in der Farbe Grün
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.

  // Zurücksetzen aller Pixelfarben auf Stufe "0" (aus)
  pixels.setPixelColor(1, pixels.Color(0, 0, 0));
  pixels.setPixelColor(2, pixels.Color(0, 0, 0));
  pixels.setPixelColor(3, pixels.Color(0, 0, 0));
  pixels.setPixelColor(4, pixels.Color(0, 0, 0));
  pixels.setPixelColor(5, pixels.Color(0, 0, 0));
  pixels.show(); // Durchführen der Pixel-Ansteuerung
  delay (pause); // Pause, die LEDs bleiben in dieser Zeit aus
}

2. Schritt: Anpassen des Beispiels an die Aufgabenstellung

Bearbeiten

NUMPIXELS auf 6 ändern
pause auf 1000 ändern

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6 
#define pause 1000 

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup(){
  pixels.begin(); // Initialisierung der NeoPixel
}

void loop(){
  pixels.setPixelColor(0, pixels.Color(0, 255, 0)); 
  pixels.setPixelColor(1, pixels.Color(0, 255, 0)); 
  pixels.setPixelColor(2, pixels.Color(0, 255, 0)); 
  pixels.setPixelColor(3, pixels.Color(0, 255, 0)); 
  pixels.setPixelColor(4, pixels.Color(0, 255, 0)); 
  pixels.show(); 
  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
  pixels.setPixelColor(0, pixels.Color(0, 0, 0));
  pixels.setPixelColor(1, pixels.Color(0, 0, 0));
  pixels.setPixelColor(2, pixels.Color(0, 0, 0));
  pixels.setPixelColor(3, pixels.Color(0, 0, 0));
  pixels.setPixelColor(4, pixels.Color(0, 0, 0));
  pixels.show(); 
  delay (pause); 
}

Damit blinken die LEDs bereits.
Wenn jetzt aber z.B. 100 LEDs so angesteuert werden sollen sieht der Code nicht mehr gut aus.

3. Schritt: Eine erste Optimierung

Bearbeiten

Wenn sich Code wiederholt, lässt man das den µC abarbeiten. Dazu bieten sich Schleifen an.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
}

void loop() {
  for (int i = 0; i < 6; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 255, 0));
  }
  pixels.show();
  delay (pause); 
  for (int i = 0; i < 6; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
  pixels.show();
  delay (pause);
}

Am Verhalten des Programmes hat sich nichts geändert. Es gibt aber immer noch nahezu gleichen Code. Den kann man in eine Funktion auslagern.

4. Schritt: Eine zweite Optimierung

Bearbeiten
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
}

void loop() {
  SetLEDStripe(pixels.Color(0, 255, 0));
  SetLEDStripe(pixels.Color(0, 0, 0));
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
  delay (pause);
}

Wie kommt man jetzt auf das uint32_t bei SetLEDStripe. Ganz einfach. Man geht in die Adafruit_NeoPixel.h und sucht dort nach "setPixelColor".
Dort findet man

  void              setPixelColor(uint16_t n, uint32_t c);

Am Verhalten des Programmes hat sich nichts geändert.

5. Schritt: Tasterabfrage

Bearbeiten

Auch hier wird man auf https://funduino.de/ fündig: funduino.de/nr-5-taster-am-arduino [2]

int LEDblau = 6; //Das Wort „LEDblau“ steht jetzt für den Wert 6.
int taster = 7; //Das Wort „taster“ steht jetzt für den Wert 7.
int tasterstatus = 0; //Das Wort „tasterstatus“ steht jetzt zunächst für den Wert 0. Später wird unter dieser Variable gespeichert, ob der Taster gedrückt ist oder nicht.

void setup() //Hier beginnt das Setup.
{
  pinMode(LEDblau, OUTPUT); //Der Pin mit der LED (Pin 6) ist jetzt ein Ausgang.
  pinMode(taster, INPUT); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
}

void loop()
{ //Mit dieser Klammer wird der Loop-Teil geöffnet.
  tasterstatus = digitalRead(taster); //Hier wird der Pin7 ausgelesen (Befehl:digitalRead). Das Ergebnis wird unter der Variable „tasterstatus“ mit dem Wert „HIGH“ für 5Volt oder „LOW“ für 0Volt gespeichert.
  if (tasterstatus == HIGH)//Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
  { //Programmabschnitt des IF-Befehls öffnen.
    digitalWrite(LEDblau, HIGH); //dann soll die LED leuchten
    delay (5000); //und zwar für für 5 Sekunden (5000 Millisekunden).
    digitalWrite(LEDblau, LOW); //danach soll die LED aus sein.
  } //Programmabschnitt des IF-Befehls schließen.
  else //...ansonsten...
  { //Programmabschnitt des else-Befehls öffnen.
    digitalWrite(LEDblau, LOW); //...soll die LED aus sein.
  } //Programmabschnitt des else-Befehls schließen.
} //Mit dieser letzten Klammer wird der Loop-Teil geschlossen.

Uns interessiert im Moment nur, wie der Taster abgefragt wird.
Dazu benötigen wir 2 Variablen

  • int taster = 7;
  • int tasterstatus = 0;

Im Setup wird der Eingang angelegt

  • pinMode(taster, INPUT);

und in der loop ausgelesen:

  • tasterstatus = digitalRead(taster);

Dann noch die Auswertung:

  • if (tasterstatus == HIGH)

Das bauen wir jetzt ein:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000

int taster = 7;
int tasterstatus = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(taster, INPUT); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
}

void loop() {
  tasterstatus = digitalRead(taster);
  if (tasterstatus == HIGH) {
    SetLEDStripe(pixels.Color(0, 255, 0));
    SetLEDStripe(pixels.Color(0, 0, 0));
  }
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
  delay (pause);
}

6. Schritt: Die nächste Optimierung

Bearbeiten

Die Variable "int taster" muss keine Variable sein. Sie wird ja nicht geändert. Daher bietet sich hier auch ein "#define" an.
Die Variable "int tasterstatus" wird nur einmal genutzt. Daher kann sie auch entfallen.
Für den Taster ist noch ein Widerstand erforderlich. Der kann auch entfallen. In µC gibt es einen zuschaltbaren Widerstand. Allerdings nur gegen +.
Wir schiessen jetzt den Taster einfach zwischen Pin 7 und GND an. "Nachteil" dieser Lösung: Der gedrückte Taster ist LOW.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 9         // Pin  WS2812 LEDs
#define taster 7
#define NUMPIXELS 6
#define pause 1000

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(taster, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
}

void loop() {
  if (digitalRead(taster) == LOW) {
    SetLEDStripe(pixels.Color(0, 255, 0));
    SetLEDStripe(pixels.Color(0, 0, 0));
  }
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
  delay (pause);
}

Damit ist der erste Teil der Aufgabe erfüllt.

7. Schritt: Der zweite Taster

Bearbeiten

Analog dem ersten Taster bauen wir den zweiten Taster ein. Pin definieren, Eingangsmoduls setzten.
Zum Testen spiegeln wir den Tasterzustand auf die eingebaute LED

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define taster1 7
#define taster2 8
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
  pinMode(taster2, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(taster1) == LOW) {
    SetLEDStripe(pixels.Color(0, 255, 0));
    SetLEDStripe(pixels.Color(0, 0, 0));
  }
  digitalWrite(LED_BUILTIN, digitalRead(taster2));
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
  delay (pause);
}

Beim Testen fällt auf, dass wenn der erste Taster gedrückt ist, der zweite Taster nicht sofort reagiert. Das liegt daran, das die loop durch die delay() Befehle blockiert wird.

8. Schritt: Weg mit dem delay()

Bearbeiten

Dazu wird jetzt eine Statemaschine eingesetzt, die die Zustände der Ausgänge nach Ereignissen umschaltet.
Wegen der besseren Lesbarkeit benutzen wir dazu "enum" Variablen.
delay() ersetzen wir mit millis().

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define taster1 7
#define taster2 8
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000

enum LED_1_States {
  off,               //0
  start,             //1
  blink_on,          //2
  blink_off          //3
};

LED_1_States LED_1_State = off;
unsigned long currTime = 0;
unsigned long oldTime = 0;
bool LED1_Stop;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
  pinMode(taster2, INPUT_PULLUP);
}

void loop() {
  currTime = millis();

  LED1_Stop = digitalRead(taster1);

  switch (LED_1_State) {
    case off:
      if (!LED1_Stop)
        LED_1_State = start;
      break;
    case start:
      SetLEDStripe(pixels.Color(0, 255, 0));
      currTime = millis();
      oldTime = currTime;
      LED_1_State = blink_on;
      break;
    case blink_on:
      if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 0, 0));
        LED_1_State = blink_off;
      }
      break;
    case blink_off:
      if (LED1_Stop) {
        LED_1_State = off;
      } else if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 255, 0));
        LED_1_State = blink_on;
      }
      break;
  }
  digitalWrite(LED_BUILTIN, digitalRead(taster2));
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
}

Mit diesem Umbau läuft jetzt die loop kontinuierlich, und der Taster 2 reagiert sofort.

9. Schritt: Die Softstart LED

Bearbeiten

Auch hier setzten wir wieder eine Statemaschine ein.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define taster1 7
#define taster2 8
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000
#define SoftStepTime 5

enum LED_1_States {
  off,               //0
  start,             //1
  blink_on,          //2
  blink_off          //3
};

enum LED_Soft_States {
  Soft_off,         //0
  fade_up,          //1
  Soft_on,          //2
  fade_down         //3
};

LED_1_States    LED_1_State = off;
LED_Soft_States LED_Soft_State = Soft_off;
unsigned long   currTime = 0;
unsigned long   oldTime = 0;
unsigned long   SoftTime = 0;
bool            LED1_Stop;
byte            LED2_Val = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
  pinMode(taster2, INPUT_PULLUP);
}

void loop() {
  currTime = millis();

  LED1_Stop = digitalRead(taster1);

  switch (LED_1_State) {
    case off:
      if (!LED1_Stop)
        LED_1_State = start;
      break;
    case start:
      SetLEDStripe(pixels.Color(0, 255, 0));
      currTime = millis();
      oldTime = currTime;
      LED_1_State = blink_on;
      break;
    case blink_on:
      if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 0, 0));
        LED_1_State = blink_off;
      }
      break;
    case blink_off:
      if (LED1_Stop) {
        LED_1_State = off;
      } else if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 255, 0));
        LED_1_State = blink_on;
      }
      break;
  }

  switch (LED_Soft_State) {
    case Soft_off:
      if (digitalRead(taster2) == LOW) {
        LED_Soft_State = fade_up;
      }
      break;
    case fade_up:
      if (currTime - SoftTime > SoftStepTime) {
        SoftTime = currTime;
        if (LED2_Val < 255) {
          LED2_Val++;
          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
          pixels.show();
        } else {
          LED_Soft_State = Soft_on;
        }
      }
      break;
    case Soft_on:
      if (digitalRead(taster2) == HIGH) {
        LED_Soft_State = fade_down;
      }
      break;
    case fade_down:
      if (currTime - SoftTime > SoftStepTime) {
        SoftTime = currTime;
        if (LED2_Val > 0) {
          LED2_Val--;
          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
          pixels.show();
        } else {
          LED_Soft_State = Soft_off;
        }
      }
      break;
  }
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
}

Hier laufen jetzt 2 Statemaschinen quasi parallel.

Der finale 10. Schritt

Bearbeiten

Beim testen fällt auf, das die Soft LED immer erst bis zum Ende läuft bevor sie wieder auf den Taster reagiert. Außerdem sollte sie ja mit einem Tastendruck ein und ausgeschaltet werden können.
Also noch eine Statemaschine für den Taster.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define taster1 7
#define taster2 8
#define PIN 9         // Pin  WS2812 LEDs
#define NUMPIXELS 6
#define pause 1000
#define SoftStepTime 20
#define debouncetime 50

enum LED_1_States {
  off,               //0
  start,             //1
  blink_on,          //2
  blink_off          //3
};

enum LED_Soft_States {
  Soft_off,         //0
  fade_up,          //1
  Soft_on,          //2
  fade_down         //3
};

enum ButtonStates {
  btnUnpressed,                  //0
  btnPressed,                    //1
  btnWaitForRelease              //2
};

enum ButtonEvents {
  btnNone,
  btnClick
};

LED_1_States    LED_1_State = off;
LED_Soft_States LED_Soft_State = Soft_off;
ButtonStates    bState = btnUnpressed;
ButtonEvents    Taster2Event = btnNone;
unsigned long   currTime = 0;
unsigned long   oldTime = 0;
unsigned long   SoftTime = 0;
unsigned long   previousMillis = 0;
bool            LED1_Stop;
byte            LED2_Val = 0;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin(); // Initialisierung der NeoPixel
  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
  pinMode(taster2, INPUT_PULLUP);
}

void loop() {
  currTime = millis();

  LED1_Stop = digitalRead(taster1);

  switch (bState) {
    case btnUnpressed:
      if (!digitalRead(taster2)) {
        bState = btnPressed;
        previousMillis = millis();
      }
      break;
    case btnPressed:
      if (digitalRead(taster2)) {
        bState = btnUnpressed;
      } else if (millis() - previousMillis > debouncetime) {
        Taster2Event = btnClick;
        bState = btnWaitForRelease;
      }
      break;
    case btnWaitForRelease:
      if (digitalRead(taster2)) {
        bState = btnUnpressed;
      }
      break;
  }

  switch (LED_1_State) {
    case off:
      if (!LED1_Stop)
        LED_1_State = start;
      break;
    case start:
      SetLEDStripe(pixels.Color(0, 255, 0));
      currTime = millis();
      oldTime = currTime;
      LED_1_State = blink_on;
      break;
    case blink_on:
      if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 0, 0));
        LED_1_State = blink_off;
      }
      break;
    case blink_off:
      if (LED1_Stop) {
        LED_1_State = off;
      } else if (currTime - oldTime > pause) {
        oldTime = currTime;
        SetLEDStripe(pixels.Color(0, 255, 0));
        LED_1_State = blink_on;
      }
      break;
  }

  switch (LED_Soft_State) {
    case Soft_off:
      if (Taster2Event == btnClick) {
        LED_Soft_State = fade_up;
      }
      break;
    case fade_up:
      if (Taster2Event == btnClick) {
        LED_Soft_State = fade_down;
      } else if (currTime - SoftTime > SoftStepTime) {
        SoftTime = currTime;
        if (LED2_Val < 255) {
          LED2_Val++;
          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
          pixels.show();
        } else {
          LED_Soft_State = Soft_on;
        }
      }
      break;
    case Soft_on:
      if (Taster2Event == btnClick) {
        LED_Soft_State = fade_down;
      }
      break;
    case fade_down:
      if (Taster2Event == btnClick) {
        LED_Soft_State = fade_up;
      } else if (currTime - SoftTime > SoftStepTime) {
        SoftTime = currTime;
        if (LED2_Val > 0) {
          LED2_Val--;
          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
          pixels.show();
        } else {
          LED_Soft_State = Soft_off;
        }
      }
      break;
  }
  
  Taster2Event = btnNone;
}

void SetLEDStripe (uint32_t c) {
  for (int i = 0; i < 5; i++) {
    pixels.setPixelColor(i, c);
  }
  pixels.show();
}

Jetzt haben wir 3 parallele Statemaschinen

  1. https://funduino.de/nr-17-ws2812-neopixel
  2. [https://funduino.de/nr-5-taster-am-arduino