Arduino: Programmiertechniken/Entwicklung

AufgabenstellungBearbeiten

  • 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 MaterialBearbeiten

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

1. Schritt: Beispiel für WS2812 LED suchenBearbeiten

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:

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9        // Hier wird angegeben, an welchem digitalen Pin die WS2812 LEDs bzw. NeoPixel angeschlossen sind
 6#define NUMPIXELS 40 // Hier wird die Anzahl der angeschlossenen WS2812 LEDs bzw. NeoPixel angegeben
 7Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 8
 9int pause = 100;     // 100 Millisekunden Pause bis zur Ansteuerung der nächsten LED.
10
11void setup(){
12  pixels.begin();    // Initialisierung der NeoPixel
13}
14
15void loop(){
16  pixels.setPixelColor(1, pixels.Color(0, 255, 0)); // Pixel1 leuchtet in der Farbe Grün
17  pixels.show(); // Durchführen der Pixel-Ansteuerung
18  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
19  pixels.setPixelColor(2, pixels.Color(0, 150, 0)); // Pixel2 leuchtet in der Farbe Grün
20  pixels.show(); // Durchführen der Pixel-Ansteuerung
21  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
22  pixels.setPixelColor(3, pixels.Color(0, 50, 0)); // Pixel3 leuchtet in der Farbe Grün
23  pixels.show(); // Durchführen der Pixel-Ansteuerung
24  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
25  pixels.setPixelColor(4, pixels.Color(0, 10, 0)); // Pixel4 leuchtet in der Farbe Grün
26  pixels.show(); // Durchführen der Pixel-Ansteuerung
27  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
28  pixels.setPixelColor(5, pixels.Color(0, 1, 0)); // Pixel5 leuchtet in der Farbe Grün
29  pixels.show(); // Durchführen der Pixel-Ansteuerung
30  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
31
32  // Zurücksetzen aller Pixelfarben auf Stufe "0" (aus)
33  pixels.setPixelColor(1, pixels.Color(0, 0, 0));
34  pixels.setPixelColor(2, pixels.Color(0, 0, 0));
35  pixels.setPixelColor(3, pixels.Color(0, 0, 0));
36  pixels.setPixelColor(4, pixels.Color(0, 0, 0));
37  pixels.setPixelColor(5, pixels.Color(0, 0, 0));
38  pixels.show(); // Durchführen der Pixel-Ansteuerung
39  delay (pause); // Pause, die LEDs bleiben in dieser Zeit aus
40}

2. Schritt: Anpassen des Beispiels an die AufgabenstellungBearbeiten

NUMPIXELS auf 6 ändern
pause auf 1000 ändern

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9         // Pin  WS2812 LEDs
 6#define NUMPIXELS 6 
 7#define pause 1000 
 8
 9Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
10
11
12void setup(){
13  pixels.begin(); // Initialisierung der NeoPixel
14}
15
16void loop(){
17  pixels.setPixelColor(0, pixels.Color(0, 255, 0)); 
18  pixels.setPixelColor(1, pixels.Color(0, 255, 0)); 
19  pixels.setPixelColor(2, pixels.Color(0, 255, 0)); 
20  pixels.setPixelColor(3, pixels.Color(0, 255, 0)); 
21  pixels.setPixelColor(4, pixels.Color(0, 255, 0)); 
22  pixels.show(); 
23  delay (pause); // Pause, in dieser Zeit wird nichts verändert.
24  pixels.setPixelColor(0, pixels.Color(0, 0, 0));
25  pixels.setPixelColor(1, pixels.Color(0, 0, 0));
26  pixels.setPixelColor(2, pixels.Color(0, 0, 0));
27  pixels.setPixelColor(3, pixels.Color(0, 0, 0));
28  pixels.setPixelColor(4, pixels.Color(0, 0, 0));
29  pixels.show(); 
30  delay (pause); 
31}

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 OptimierungBearbeiten

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

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9         // Pin  WS2812 LEDs
 6#define NUMPIXELS 6
 7#define pause 1000
 8
 9Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
10
11
12void setup() {
13  pixels.begin(); // Initialisierung der NeoPixel
14}
15
16void loop() {
17  for (int i = 0; i < 6; i++) {
18    pixels.setPixelColor(i, pixels.Color(0, 255, 0));
19  }
20  pixels.show();
21  delay (pause); 
22  for (int i = 0; i < 6; i++) {
23    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
24  }
25  pixels.show();
26  delay (pause);
27}

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 OptimierungBearbeiten

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9         // Pin  WS2812 LEDs
 6#define NUMPIXELS 6
 7#define pause 1000
 8
 9Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
10
11
12void setup() {
13  pixels.begin(); // Initialisierung der NeoPixel
14}
15
16void loop() {
17  SetLEDStripe(pixels.Color(0, 255, 0));
18  SetLEDStripe(pixels.Color(0, 0, 0));
19}
20
21void SetLEDStripe (uint32_t c) {
22  for (int i = 0; i < 5; i++) {
23    pixels.setPixelColor(i, c);
24  }
25  pixels.show();
26  delay (pause);
27}

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

1  void              setPixelColor(uint16_t n, uint32_t c);

Am Verhalten des Programmes hat sich nichts geändert.

5. Schritt: TasterabfrageBearbeiten

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

 1int LEDblau = 6; //Das Wort „LEDblau“ steht jetzt für den Wert 6.
 2int taster = 7; //Das Wort „taster“ steht jetzt für den Wert 7.
 3int 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.
 4
 5void setup() //Hier beginnt das Setup.
 6{
 7  pinMode(LEDblau, OUTPUT); //Der Pin mit der LED (Pin 6) ist jetzt ein Ausgang.
 8  pinMode(taster, INPUT); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
 9}
10
11void loop()
12{ //Mit dieser Klammer wird der Loop-Teil geöffnet.
13  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.
14  if (tasterstatus == HIGH)//Verarbeitung: Wenn der Taster gedrückt ist (Das Spannungssignal ist hoch)
15  { //Programmabschnitt des IF-Befehls öffnen.
16    digitalWrite(LEDblau, HIGH); //dann soll die LED leuchten
17    delay (5000); //und zwar für für 5 Sekunden (5000 Millisekunden).
18    digitalWrite(LEDblau, LOW); //danach soll die LED aus sein.
19  } //Programmabschnitt des IF-Befehls schließen.
20  else //...ansonsten...
21  { //Programmabschnitt des else-Befehls öffnen.
22    digitalWrite(LEDblau, LOW); //...soll die LED aus sein.
23  } //Programmabschnitt des else-Befehls schließen.
24} //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:

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9         // Pin  WS2812 LEDs
 6#define NUMPIXELS 6
 7#define pause 1000
 8
 9int taster = 7;
10int tasterstatus = 0;
11
12Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
13
14
15void setup() {
16  pixels.begin(); // Initialisierung der NeoPixel
17  pinMode(taster, INPUT); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
18}
19
20void loop() {
21  tasterstatus = digitalRead(taster);
22  if (tasterstatus == HIGH) {
23    SetLEDStripe(pixels.Color(0, 255, 0));
24    SetLEDStripe(pixels.Color(0, 0, 0));
25  }
26}
27
28void SetLEDStripe (uint32_t c) {
29  for (int i = 0; i < 5; i++) {
30    pixels.setPixelColor(i, c);
31  }
32  pixels.show();
33  delay (pause);
34}

6. Schritt: Die nächste OptimierungBearbeiten

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.

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define PIN 9         // Pin  WS2812 LEDs
 6#define taster 7
 7#define NUMPIXELS 6
 8#define pause 1000
 9
10Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
11
12void setup() {
13  pixels.begin(); // Initialisierung der NeoPixel
14  pinMode(taster, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
15}
16
17void loop() {
18  if (digitalRead(taster) == LOW) {
19    SetLEDStripe(pixels.Color(0, 255, 0));
20    SetLEDStripe(pixels.Color(0, 0, 0));
21  }
22}
23
24void SetLEDStripe (uint32_t c) {
25  for (int i = 0; i < 5; i++) {
26    pixels.setPixelColor(i, c);
27  }
28  pixels.show();
29  delay (pause);
30}

Damit ist der erste Teil der Aufgabe erfüllt.

7. Schritt: Der zweite TasterBearbeiten

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

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define taster1 7
 6#define taster2 8
 7#define PIN 9         // Pin  WS2812 LEDs
 8#define NUMPIXELS 6
 9#define pause 1000
10
11Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
12
13void setup() {
14  pixels.begin(); // Initialisierung der NeoPixel
15  pinMode(LED_BUILTIN, OUTPUT);
16  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
17  pinMode(taster2, INPUT_PULLUP);
18}
19
20void loop() {
21  if (digitalRead(taster1) == LOW) {
22    SetLEDStripe(pixels.Color(0, 255, 0));
23    SetLEDStripe(pixels.Color(0, 0, 0));
24  }
25  digitalWrite(LED_BUILTIN, digitalRead(taster2));
26}
27
28void SetLEDStripe (uint32_t c) {
29  for (int i = 0; i < 5; i++) {
30    pixels.setPixelColor(i, c);
31  }
32  pixels.show();
33  delay (pause);
34}

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().

 1#include <Adafruit_NeoPixel.h>
 2#ifdef __AVR__
 3#include <avr/power.h>
 4#endif
 5#define taster1 7
 6#define taster2 8
 7#define PIN 9         // Pin  WS2812 LEDs
 8#define NUMPIXELS 6
 9#define pause 1000
10
11enum LED_1_States {
12  off,               //0
13  start,             //1
14  blink_on,          //2
15  blink_off          //3
16};
17
18LED_1_States LED_1_State = off;
19unsigned long currTime = 0;
20unsigned long oldTime = 0;
21bool LED1_Stop;
22
23Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
24
25void setup() {
26  pixels.begin(); // Initialisierung der NeoPixel
27  pinMode(LED_BUILTIN, OUTPUT);
28  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
29  pinMode(taster2, INPUT_PULLUP);
30}
31
32void loop() {
33  currTime = millis();
34
35  LED1_Stop = digitalRead(taster1);
36
37  switch (LED_1_State) {
38    case off:
39      if (!LED1_Stop)
40        LED_1_State = start;
41      break;
42    case start:
43      SetLEDStripe(pixels.Color(0, 255, 0));
44      currTime = millis();
45      oldTime = currTime;
46      LED_1_State = blink_on;
47      break;
48    case blink_on:
49      if (currTime - oldTime > pause) {
50        oldTime = currTime;
51        SetLEDStripe(pixels.Color(0, 0, 0));
52        LED_1_State = blink_off;
53      }
54      break;
55    case blink_off:
56      if (LED1_Stop) {
57        LED_1_State = off;
58      } else if (currTime - oldTime > pause) {
59        oldTime = currTime;
60        SetLEDStripe(pixels.Color(0, 255, 0));
61        LED_1_State = blink_on;
62      }
63      break;
64  }
65  digitalWrite(LED_BUILTIN, digitalRead(taster2));
66}
67
68void SetLEDStripe (uint32_t c) {
69  for (int i = 0; i < 5; i++) {
70    pixels.setPixelColor(i, c);
71  }
72  pixels.show();
73}

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

9. Schritt: Die Softstart LEDBearbeiten

Auch hier setzten wir wieder eine Statemaschine ein.

  1#include <Adafruit_NeoPixel.h>
  2#ifdef __AVR__
  3#include <avr/power.h>
  4#endif
  5#define taster1 7
  6#define taster2 8
  7#define PIN 9         // Pin  WS2812 LEDs
  8#define NUMPIXELS 6
  9#define pause 1000
 10#define SoftStepTime 5
 11
 12enum LED_1_States {
 13  off,               //0
 14  start,             //1
 15  blink_on,          //2
 16  blink_off          //3
 17};
 18
 19enum LED_Soft_States {
 20  Soft_off,         //0
 21  fade_up,          //1
 22  Soft_on,          //2
 23  fade_down         //3
 24};
 25
 26LED_1_States    LED_1_State = off;
 27LED_Soft_States LED_Soft_State = Soft_off;
 28unsigned long   currTime = 0;
 29unsigned long   oldTime = 0;
 30unsigned long   SoftTime = 0;
 31bool            LED1_Stop;
 32byte            LED2_Val = 0;
 33
 34Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 35
 36void setup() {
 37  pixels.begin(); // Initialisierung der NeoPixel
 38  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
 39  pinMode(taster2, INPUT_PULLUP);
 40}
 41
 42void loop() {
 43  currTime = millis();
 44
 45  LED1_Stop = digitalRead(taster1);
 46
 47  switch (LED_1_State) {
 48    case off:
 49      if (!LED1_Stop)
 50        LED_1_State = start;
 51      break;
 52    case start:
 53      SetLEDStripe(pixels.Color(0, 255, 0));
 54      currTime = millis();
 55      oldTime = currTime;
 56      LED_1_State = blink_on;
 57      break;
 58    case blink_on:
 59      if (currTime - oldTime > pause) {
 60        oldTime = currTime;
 61        SetLEDStripe(pixels.Color(0, 0, 0));
 62        LED_1_State = blink_off;
 63      }
 64      break;
 65    case blink_off:
 66      if (LED1_Stop) {
 67        LED_1_State = off;
 68      } else if (currTime - oldTime > pause) {
 69        oldTime = currTime;
 70        SetLEDStripe(pixels.Color(0, 255, 0));
 71        LED_1_State = blink_on;
 72      }
 73      break;
 74  }
 75
 76  switch (LED_Soft_State) {
 77    case Soft_off:
 78      if (digitalRead(taster2) == LOW) {
 79        LED_Soft_State = fade_up;
 80      }
 81      break;
 82    case fade_up:
 83      if (currTime - SoftTime > SoftStepTime) {
 84        SoftTime = currTime;
 85        if (LED2_Val < 255) {
 86          LED2_Val++;
 87          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
 88          pixels.show();
 89        } else {
 90          LED_Soft_State = Soft_on;
 91        }
 92      }
 93      break;
 94    case Soft_on:
 95      if (digitalRead(taster2) == HIGH) {
 96        LED_Soft_State = fade_down;
 97      }
 98      break;
 99    case fade_down:
100      if (currTime - SoftTime > SoftStepTime) {
101        SoftTime = currTime;
102        if (LED2_Val > 0) {
103          LED2_Val--;
104          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
105          pixels.show();
106        } else {
107          LED_Soft_State = Soft_off;
108        }
109      }
110      break;
111  }
112}
113
114void SetLEDStripe (uint32_t c) {
115  for (int i = 0; i < 5; i++) {
116    pixels.setPixelColor(i, c);
117  }
118  pixels.show();
119}

Hier laufen jetzt 2 Statemaschinen quasi parallel.

Der finale 10. SchrittBearbeiten

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.

  1#include <Adafruit_NeoPixel.h>
  2#ifdef __AVR__
  3#include <avr/power.h>
  4#endif
  5#define taster1 7
  6#define taster2 8
  7#define PIN 9         // Pin  WS2812 LEDs
  8#define NUMPIXELS 6
  9#define pause 1000
 10#define SoftStepTime 20
 11#define debouncetime 50
 12
 13enum LED_1_States {
 14  off,               //0
 15  start,             //1
 16  blink_on,          //2
 17  blink_off          //3
 18};
 19
 20enum LED_Soft_States {
 21  Soft_off,         //0
 22  fade_up,          //1
 23  Soft_on,          //2
 24  fade_down         //3
 25};
 26
 27enum ButtonStates {
 28  btnUnpressed,                  //0
 29  btnPressed,                    //1
 30  btnWaitForRelease              //2
 31};
 32
 33enum ButtonEvents {
 34  btnNone,
 35  btnClick
 36};
 37
 38LED_1_States    LED_1_State = off;
 39LED_Soft_States LED_Soft_State = Soft_off;
 40ButtonStates    bState = btnUnpressed;
 41ButtonEvents    Taster2Event = btnNone;
 42unsigned long   currTime = 0;
 43unsigned long   oldTime = 0;
 44unsigned long   SoftTime = 0;
 45unsigned long   previousMillis = 0;
 46bool            LED1_Stop;
 47byte            LED2_Val = 0;
 48
 49Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
 50
 51void setup() {
 52  pixels.begin(); // Initialisierung der NeoPixel
 53  pinMode(taster1, INPUT_PULLUP); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
 54  pinMode(taster2, INPUT_PULLUP);
 55}
 56
 57void loop() {
 58  currTime = millis();
 59
 60  LED1_Stop = digitalRead(taster1);
 61
 62  switch (bState) {
 63    case btnUnpressed:
 64      if (!digitalRead(taster2)) {
 65        bState = btnPressed;
 66        previousMillis = millis();
 67      }
 68      break;
 69    case btnPressed:
 70      if (digitalRead(taster2)) {
 71        bState = btnUnpressed;
 72      } else if (millis() - previousMillis > debouncetime) {
 73        Taster2Event = btnClick;
 74        bState = btnWaitForRelease;
 75      }
 76      break;
 77    case btnWaitForRelease:
 78      if (digitalRead(taster2)) {
 79        bState = btnUnpressed;
 80      }
 81      break;
 82  }
 83
 84  switch (LED_1_State) {
 85    case off:
 86      if (!LED1_Stop)
 87        LED_1_State = start;
 88      break;
 89    case start:
 90      SetLEDStripe(pixels.Color(0, 255, 0));
 91      currTime = millis();
 92      oldTime = currTime;
 93      LED_1_State = blink_on;
 94      break;
 95    case blink_on:
 96      if (currTime - oldTime > pause) {
 97        oldTime = currTime;
 98        SetLEDStripe(pixels.Color(0, 0, 0));
 99        LED_1_State = blink_off;
100      }
101      break;
102    case blink_off:
103      if (LED1_Stop) {
104        LED_1_State = off;
105      } else if (currTime - oldTime > pause) {
106        oldTime = currTime;
107        SetLEDStripe(pixels.Color(0, 255, 0));
108        LED_1_State = blink_on;
109      }
110      break;
111  }
112
113  switch (LED_Soft_State) {
114    case Soft_off:
115      if (Taster2Event == btnClick) {
116        LED_Soft_State = fade_up;
117      }
118      break;
119    case fade_up:
120      if (Taster2Event == btnClick) {
121        LED_Soft_State = fade_down;
122      } else if (currTime - SoftTime > SoftStepTime) {
123        SoftTime = currTime;
124        if (LED2_Val < 255) {
125          LED2_Val++;
126          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
127          pixels.show();
128        } else {
129          LED_Soft_State = Soft_on;
130        }
131      }
132      break;
133    case Soft_on:
134      if (Taster2Event == btnClick) {
135        LED_Soft_State = fade_down;
136      }
137      break;
138    case fade_down:
139      if (Taster2Event == btnClick) {
140        LED_Soft_State = fade_up;
141      } else if (currTime - SoftTime > SoftStepTime) {
142        SoftTime = currTime;
143        if (LED2_Val > 0) {
144          LED2_Val--;
145          pixels.setPixelColor(5, pixels.Color(LED2_Val, 0, 0));
146          pixels.show();
147        } else {
148          LED_Soft_State = Soft_off;
149        }
150      }
151      break;
152  }
153  
154  Taster2Event = btnNone;
155}
156
157void SetLEDStripe (uint32_t c) {
158  for (int i = 0; i < 5; i++) {
159    pixels.setPixelColor(i, c);
160  }
161  pixels.show();
162}

Jetzt haben wir 3 parallele Statemaschinen

ZurückBearbeiten

QuellenBearbeiten

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