Arduino Lampe switch case unterbrechen

Hallo Community,

ich habe da ein kleines Problem :wink:

Aber zunächst zu mir. Ich heiße Nils und beschäftige mich seit geraumer Zeit mit dem Arduino.

Ich habe mich mit WS2812B eine Lampe gebaut, die auf Knopfdruck die Farbe ändern soll. Das funktioniert auch soweit (bei jedem Klick eine andere Farbe).
Jetzt soll bei dem siebten Klick ein Farbwechsler aktiviert werden. Das funktioniert auch. Allerdings kann ich jetzt diesen Programmschritt nicht mehr verlassen, da er immer in diesem Modus bleibt.
Ich habe schon mit Interrupts rumprobiert aber auf keinen grünen Zweig gekommen.

Kann mir von euch bitte jemand helfen?

Gruß und Danke

Nils

//LED-Lampe

//Definieren von Variablen und Konstanten
#include "FastLED.h"

#define NUM_LEDS 56
#define DATA_PIN 5

CRGB leds[NUM_LEDS];

const int Taster=2;

int zahl=1;
int r=0;
int g=0;
int b=0;
int x=0;
int maxLED=56;
int AnzLED=56;


void setup() {
//LED-Streifen einbinden
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
//Ein- und Ausgänge definieren
pinMode (Taster, INPUT);
//Serieller Monitor
  Serial.begin(9600);
  Serial.println();
  
}

void loop()
{
  //Durch Tastendruck wird die Variable für switch/case hochgezählt
    if(digitalRead(Taster) == HIGH)
  {
    zahl=zahl+1; 
    delay(400);
    x=0;
  }
  //wenn maximale switch/case erreiche beginnt es von vorne
  if(zahl >= 8)
  {
    zahl=1; 
  }

Serial.println(zahl);
//Switch case
  switch(zahl)
  {
    //tritt im normalfall nicht ein
    case 0:
      zahl=1;
    break;
    //Alle LEDs werden rot
    case 1:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(255,0,0);
        //delay(500); 
        FastLED.show();
      }
    break;
    //Alle LEDs werden grün
    case 2:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(0,255,0); 
        FastLED.show();
      }
    break;
    //Alle LEDs werden blau
    case 3:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(0,0,255); 
        FastLED.show();
      }
    break;
    //Alle LEDs werden gelb
    case 4:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(255,255,0); 
        FastLED.show();
      }
    break;
    //Alle LEDs werden türkis
    case 5:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(0,255,255); 
        FastLED.show();
      }
    break;
    //Alle LEDs werden weiß
    case 6:
      for(int a=0; a<maxLED;a++)
      {
        leds[a] = CRGB(255,255,255);
       //delay(500); 
        FastLED.show();
      } 
    break;
    // LED Farbwechsel !!Problemstelle!!
    case 7:
      {
        if(x==0)
        {
          do
          {
            r=r+15; 
            for(AnzLED=0;AnzLED<=56;AnzLED++)
            { 
              leds[AnzLED] = CRGB(r,g,b); 
              FastLED.show();
            }
          }while(r<255);
          x=1;
         }
         
         do
         {
           g=g+15;
           for(AnzLED=0;AnzLED<=56;AnzLED++)
            {  
              leds[AnzLED] = CRGB(255,g,b); 
              FastLED.show();
            }
         }while(g<255);
         
         do
         {
           g=g-15;
           b=b+15; 
           for(AnzLED=0;AnzLED<=56;AnzLED++)
           {  
             leds[AnzLED] = CRGB(255,g,b); 
             FastLED.show();
           }
         }while(g!=0);
       
       do
       {
         g=g+15;  
         for(AnzLED=0;AnzLED<=56;AnzLED++)
         {
           leds[AnzLED] = CRGB(255,g,255); 
           FastLED.show();
         }
       }while(g<255);
       
       do
       {
         r=r-15;  
         for(AnzLED=0;AnzLED<=56;AnzLED++)
         {
           leds[AnzLED] = CRGB(r,255,255); 
           FastLED.show();
         }
       }while(r!=0);
       
       do
       {
         g=g-15;  
         for(AnzLED=0;AnzLED<=56;AnzLED++)
         {
           leds[AnzLED] = CRGB(r,g,255); 
           FastLED.show();
         }
       }while(g!=0);
       
       do
       {
         b=b-15;
         g=g+15;  
         for(AnzLED=0;AnzLED<=56;AnzLED++)
         {
           leds[AnzLED] = CRGB(r,g,b); 
           FastLED.show();
         }
       }while(g<255);
      
       do
       {
         g=g-15; 
         r=r+15; 
         for(AnzLED=0;AnzLED<=56;AnzLED++)
         {
           leds[AnzLED] = CRGB(r,g,b); 
           FastLED.show();
         }
       }while(r<255);
     }
    break;
    //tritt im normalfall nicht ein
    case 8:
      zahl=7;
    break;
  }
}

FASTLED_Test.ino (3.71 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Setze deinen Sketch bitte direkt ins Forum und den in Code-Tags.
Schaltfläche </> oben links im Editorfenster.
Dann kann den Sketch jeder lesen und du hast mehr Helfer.

nilo013:
ich habe da ein kleines Problem :wink:

Die Zeilen

   case 8:
     zahl=7;
   break;

sehen „interessant“ aus. Insbesondere in Kombination mit

//wenn maximale switch/case erreiche beginnt es von vorne
 if(zahl >= 8)
 {
   zahl=1; 
 }

Gruß

Gregor

Hi

Dein Problem ist, daß Du in dem State 'RGB-Farbwechsel' (Deiner Nummer 7) dutzende FOR/WHILE-Schleifen hast - Die brauchen 'ewig' - obwohl Du eigentlich bestenfalls eine Kleinigkeit JETZT gerade abzuändern hättest - oder eben nicht.

Du musst die ganzen FORs/WHILEs zerlegen.
Merke Dir, wo Du gerade bist (den Status/die Nummer der Animation) und wie weit Du darin bist, wie auch, wann Du das letzte Mal was geändert hast.
Nun prüfst Du jedes Mal, ob die Zeit um ist, also, ob Du wieder etwas machen musst.
Wenn nein, dann eben nicht - loop() wird direkt erneut gestartet, Du kannst auf Tastendrücke reagieren.
Wenn doch, greift die aktuelle Animation, dort wird geprüft, ob wir mit dem jetzigen Schritt fertig wären.
Ja -> auf zur nächsten Animation - Das hat ebenfalls keine Zeit gebraucht!
Nein -> Diese Animation einen Schritt weiter, die LEDs mit neuen Farben füllen, .show(), Zeit merken, fertig.
Auch Das war recht fix, Du kannst jederzeit auf den Tastendruck reagieren, da Du quasi IMMER auch den Taster auswertest.
Ok - nicht immer - aber so schnell hintereinander, daß Das für den Bediener 'immer' ist.

MfG

Hallo postmaster-ino,

Danke schonmal für deine Hilfe, aber ich versteh nicht ganz wie du das meinst.

Kannst du mir das bitte mal an einem Beispiel zeigen?

Danke

AARRGG …

Ok, wenn man unbedingt einen Link aus den Lesezeichen haben will … in NEUEM TAB … fluch

Lies Dir bitte combies Liste zum Thema State-Maschine durch.

Aktuell machst Du ungefähr das:

switch (var){
   case rgb-animation: FOR (byte t=0;t<200;t++){
                                   tu_was_mit_t;
                                }
                                For (byte b=0;b<32;b++){
                                   tu_was_mit_b;
                                }
                                ...
                                break;

Das sollte aber eher in diese Richtung gehen:

switch (var){
   case rgb-animation:
                                static byte animationsnummer=0;
                                static byte temp=-1; //könnte eine Warnung werfen, da byte keine negativen Zahlen kennt
                                temp++; //erhöht die temporäre Variable (unser Arbeitstier) bei jedem Durchlauf um 1
                                switch (animationsnummer){
                                  case 0:
                                       if (temp<200){
                                          tu_was_mit_t; //hier temp
                                       }else{
                                          temp=0;
                                          animationsnummer++;
                                       }
                                       break;
                                  case 1:
                                       if (temp<32){
                                          tu_was_mit_b; //hier temp
                                       }else{
                                          temp=0;
                                          animationsnummer++;
                                       }
                                       break;
                                  case 2:
                                       animationsnummer=0;
                                       break;

Besser verständlich?
Du bist nur für einen einzigen Schritt in diesem Case unterwegs - wenn dieser Schritt ausgeführt ist, gehen wir aus dem switch/case raus, loop() beginnt erneut, fragt z.B. den Taster ab um das Programm zu Wechseln - dann kommen wir wieder in das switch/case - wenn die Animation geblieben ist, kommen wir erneut hier hin - nur ist jetzt bereits die Variable ‘temp’ um 1 hochgezählt.
Unser Aufruf ‘tu_was_mit_t’ wird also mit dem wert 1 ausgeführt - nur diese eine Nummer!
Danach, wenn wir Das gemacht haben (die LEDs wurden neu berechnet/gesetzt/per .show() angezeigt) beenden wir wieder den switch/case bis zur nächsten Runde.
Auch kannst Du darin warten - Du musst Dir nur merken, wann die Wartezeit begonnen hat und solange Die nicht vorüber ist, machen wir hier NIchts.

                                uint32_t lastaction=millis(); //static und mit Startwert
                                switch (animationsnummer){
                                  case 0:
                                       if (temp<200){
                                          tu_was_mit_t; //hier temp
                                       }else{
                                          temp=0;
                                          animationsnummer++;
                                          lastaction=millis();
                                       }
                                       break;
                                  case 1:
                                       if (millis()-lastaction>wartezeit){
                                          //hier kommen wir erst hin, wenn mindestens die Wartezeit vorbei ist
                                          if (temp<32){
                                          ...

MfG

nilo013:
Kannst du mir das bitte mal an einem Beispiel zeigen?

Das Modell eines Endlichen Automaten wird nicht immer auf Anhieb verstanden - postmaster_ino beschreibt aber ungefähr, worauf es ankommt. Eine sehr gute Erklärung ist hier zu finden. Ansonsten habe auch ich mal meine Gedanken dazu ins Netz gekippt.

HTH

Gregor

Hallo postmaster-ino,

Danke hat super geklappt!

Gruß
Nils