Wo liegt der Fehler?

Hallo Leute,
ich Probiere schon eine ganze weile mit switch case herum aber es funktioniert einfach nicht.
Ich konnte das Problem schon eingrenzen, und zwar werden alle case nach dem Code in case 0 ignoriert.

(Ich weis dass wenn ich den Code aus case 0 an letzter stelle schreibe alles funktionieren würde aber ich würde gern den Fehler finden)

int button = 2;
int LED[7] {0,3,5,6,9,10,11};
unsigned long bisherigeMillis = 0;
int i = 1;
int fortschritt = 1;
int mode = 1;

int interval = 200;   // Dauer eines Schrittes (Bsp.: 500ms an, 500ms aus)

void setup() {
  Serial.begin(9600);
  pinMode (button, INPUT_PULLUP);
    
  for(int i = 1; i < 7; i++){   // initialisiert die 6 LED als OUTPUT 
    pinMode( LED[i], OUTPUT);
  };
}

void loop() {
  if (!digitalRead(button)){
    mode++;
    if (mode > 2){
      mode = 0;
    }
      digitalWrite(LED[1],LOW);
      digitalWrite(LED[2],LOW);
      digitalWrite(LED[3],LOW);
      digitalWrite(LED[4],LOW);
      digitalWrite(LED[5],LOW);
      digitalWrite(LED[6],LOW);
      i = 1; 
      bisherigeMillis = 0;
    delay(100);
      
    while(!digitalRead(button));
  }
  
  switch(mode){
    case 0:
    unsigned long aktuelleMillis = millis();
  
      if ( aktuelleMillis - bisherigeMillis >= interval) {
        bisherigeMillis = aktuelleMillis;
   
        digitalWrite(LED[i], !digitalRead(LED[i]));

        if( digitalRead(LED[i]) == LOW ){ 
          i = i + fortschritt;
             
          if( i > 5 || i < 2 ){
            fortschritt = -fortschritt;
            }
          }
        }
    break;
    
    case 1:
      digitalWrite(LED[1],HIGH);
      digitalWrite(LED[2],HIGH);
      digitalWrite(LED[3],HIGH);
      digitalWrite(LED[4],HIGH);
      digitalWrite(LED[5],HIGH);
      digitalWrite(LED[6],HIGH);
    break;
    
    case 2:
    break;
    }
    
    Serial.println(mode);
}

Ein Array der Länge N geht von 0 bis N-1. Nicht von 1 bis N

Wobei Pin 0 von der serielle Schnittstelle belegt wird. Wenn du das nicht für die LEDs brauchst, was macht es dann im Array?

Hi

Sven123:
(Ich weis dass wenn ich den Code aus case 0 an letzter stelle schreibe alles funktionieren würde aber ich würde gern den Fehler finden)

Erkläre Das bitte.
Eine festgelegte Rehenfolge, aber von Klein nach Groß, gab's, wenn ich mich recht entsinne, unter VisualBasic oder PureBasic?

Auch MUSS Dein Sketch im ersten Durchlauf die LEDs 1-6 (warum eigentlich 1 ... warum nicht 0-6?) auf HIGH setzen.
Was sagen Serial.print in den verschiedenen cases?
Vll ein 'timestamp' dabei? Hier würde sich millis() oder aktuelleMillis anbieten.

MfG

PS: Er greift ja nur bis Element 6 zu - eben nicht auf 0, aber Das sollte nicht das Problem sein.
LED[0] wird ja auch nicht zum Outpot via pinMode.

PPS: Sonst fällt mir nur das ; am Ende der FOR-Schleife in setup() auf - Das sollte außerhalb von setup() aber nicht mehr interessieren, oder?

... Quote statt Edit ... sorry

wenn ich den Code aus case 0 nehme und in case 2 verschiebe dann funktionirt alles wie erwartet.

in der Seriellen Ausgabe stand immer der korrekte wert (die Zahl des ausgewählten case)

LED[0] hab ich einfach ignoriert um nicht durcheinander zu kommen, ich hab quasi bei 1 begonnen meine LED´s zu zählen.

So wie der Code dort steht beginnt er ja mit case 1 in dem alle LED´s leuchten sollten.
Nichtmal das tuen sie.

unsigned long aktuelleMillis

definiere mal aktuelleMillis als globale Variable vor dem setup();

Ich bin gespannt, obs dann funktioniert.

Und schalte mal die Warnungen ein. Dann merkst du schon dass da was nicht passt:

warning: jump to case label crosses initialization of 'long unsigned int aktuelleMillis'

Das muss man nicht global machen. Es reicht schon einen Block darum zu machen:

case 0:
{
    unsigned long aktuelleMillis = millis();

    ...
}
break;

Hausknecht:

unsigned long aktuelleMillis

definiere mal aktuelleMillis als globale Variable vor dem setup();

Ich bin gespannt, obs dann funktioniert.

es hat wirklich funktioniert.
vielen dank erstmal dafür. :slight_smile:

ich verstehe nur nicht ganz wieso es nicht zuvor ging.
Kannst du mir das erklären?

hier ist jetzt nochmal der funktionierende Code:

int button = 2;
int LED[7] {0,3,5,6,9,10,11};
unsigned long bisherigeMillis = 0;
int i = 1;
int fortschritt = 1;
int mode = 1;
unsigned long aktuelleMillis = millis();

int interval = 200;   // Dauer eines Schrittes (Bsp.: 500ms an, 500ms aus)

void setup() {
  Serial.begin(9600);
  pinMode (button, INPUT_PULLUP);
    
  for(int i = 1; i < 7; i++){   // initialisiert die 6 LED als OUTPUT 
    pinMode( LED[i], OUTPUT);
  };
}

void loop() {
  if (!digitalRead(button)){
    mode++;
    if (mode > 2){
      mode = 0;
    }
      digitalWrite(LED[1],LOW);
      digitalWrite(LED[2],LOW);
      digitalWrite(LED[3],LOW);
      digitalWrite(LED[4],LOW);
      digitalWrite(LED[5],LOW);
      digitalWrite(LED[6],LOW);
      i = 1; 
      bisherigeMillis = 0;
    delay(100);
      
    while(!digitalRead(button));
  }
  
  switch(mode){
    case 0:
      aktuelleMillis = millis();
      
      if ( aktuelleMillis - bisherigeMillis >= interval) {
        bisherigeMillis = aktuelleMillis;
   
        digitalWrite(LED[i], !digitalRead(LED[i]));

        if( digitalRead(LED[i]) == LOW ){ 
          i = i + fortschritt;
             
          if( i > 5 || i < 2 ){
            fortschritt = -fortschritt;
            }
          }
        }
    break;
    
    case 1:
      digitalWrite(LED[1],HIGH);
      digitalWrite(LED[2],HIGH);
      digitalWrite(LED[3],HIGH);
      digitalWrite(LED[4],HIGH);
      digitalWrite(LED[5],HIGH);
      digitalWrite(LED[6],HIGH);
    break;
    
    case 2:
    break;
    }
    
    Serial.println(mode);
}

Wenn Du in einem case Variablen anlegen willst, musst Du das alles nochmal in {} kapseln / in einen lokalen Gültigkeitsbereich packen.

...
case 1:
{
  unsigned long aktMillis = millis();
  // mach was mit aktMillis
}

Gruß Tommy