Switch case Timer

Hey!

Ich habe für meine LED Eiszapfenlichterkette einen neuen Controller gebaut, den ich mit folgendem Code bestückt habe und die Kette zum laufen gebracht habe, um einen "Wassertropfeneffekt" zu bewirken.

int pins[] = {3,5,6,9};
int leds = sizeof(pins)/2;
 
void setup() {
  for(int thispin = 0; thispin < leds; thispin++) {
    pinMode(pins[thispin], OUTPUT);
  } 
}
 
void loop() {
  int shuffle= random(0, 1);

switch (shuffle){
            case 0:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(5);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(4.5);
        }         
      }
      delay(0); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(10); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 255; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(0);
        } 
        delay(0.5);
         // here ends the code for the fade out effect
      }
      Serial.println(i);
      digitalWrite(pins[i], LOW);   
  }}
  
  

  case 1:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(5);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(4.5);
        }         
      }
      delay(0); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(10); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 255; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(0);
        } 
        delay(0.5);
         // here ends the code for the fade out effect
      }
      Serial.println(i);
      digitalWrite(pins[i], LOW);   
  }}
  
  }
}

Funktioniert auch alles wunderbar. Nur möchte ich mehrere Cases einbauen (ca. 5, sind bis jetzt nur 2 zum testen), damit die Lichterkette nicht so monoton wirkt. Klappt auch alles, nur switchen die cases halt viel zu schnell und ich finde einfach nicht heraus, wie ich es hinbekomme eine bestimmte Zeit in einem Case zu bleiben.

Hat jemand da eine Ahnung wie ich am einfachsten hinbekomme?

Gruß

Hallo,
mit millis() ? Suche mal nach nachtwächter oder so.
Da gibt es ne´ Menge zu lesen.
Gruß und Spaß
Andreas
da haste

millis() habe ich mir auch schon angeschaut nur tue ich mich noch schwer damit das zu integrieren...

Hallo NachtEule,
das wird mit dem Nachtwächter nicht einfacher. millis() sind die ERSTE Wahl für so etwas.
Alleine schon, um delay() zu eleminieren.
Gruß und Spaß
Andreas

Mein Problem ist wie ich den random Status abfrage. Bekomme es nur hin, dass er jedes mal vor der random Schleife die Zeit abfragt, und dann habe ich wieder das gleiche wie ein delay().

delay(0.5);

Delay kann keine float Zaheln.

Du meinst doch bestimmt 0,5 Sekunden...
Dann muss es delay(500) heißen.

combie:
Delay kann keine float Zaheln.

Du meinst doch bestimmt 0,5 Sekunden...
Dann muss es delay(500) heißen.

Nein, sollte quasi eine halbe Millisekunde sein :stuck_out_tongue: Aber danke für den Hinweis.

Habe jetzt millis() in meinen Code integriert aber ich bleibe immer in case 2 hängen. Also er bleibt ja die eingegebenen 15 Sekunden in diesem Case aber nicht in case 0 und case 1.

Jemand ne Idee wieso bei 0 und 1 es direkt wieder zu 2 umspringt?

int pins[] = {3,5,6,9};
int leds = sizeof(pins)/2;
 int shuffle= 0;
 unsigned long timestamp=0;
void setup() {
  Serial.begin(9600);
  
  for(int thispin = 0; thispin < leds; thispin++) {
    pinMode(pins[thispin], OUTPUT);
  } 
  pinMode(3, OUTPUT);
    pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
        pinMode(9, OUTPUT);
}
 
void loop() {

 
 Serial.println(shuffle);

switch (shuffle){
  
  case 0:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(2);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(4);
        }         
      }
      delay(10); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(0); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 64; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(5);
        } 
        delay(0);
         // here ends the code for the fade out effect
      }
  
      digitalWrite(pins[i], LOW);    
     
  }
   if((millis()-timestamp)<15000){
   shuffle=0;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 2);
   timestamp = millis ();
  }
  }
  
  

  case 1:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(2);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(4);
        }         
      }
      delay(10); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(0); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 64; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(5);
        } 
        delay(0);
         // here ends the code for the fade out effect
      }
     
      digitalWrite(pins[i], LOW); 
     
      
  }
   if((millis()-timestamp)<15000){
   shuffle=1;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 2);
   timestamp = millis ();
  }
  }


case 2:{
 for(int b=0;b<leds;b++){
  digitalWrite(pins[b], HIGH); 
  }

  if((millis()-timestamp)<15000){
   shuffle=2;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 2);
   timestamp = millis ();
  }
  
 }

break;
  default:
  shuffle=random(0, 2);            
  }
  
  }

Es fehlen die 'break;' am Ende der jeweiligen case-Blöcke. Ohne die breaks gehts immer sofort mit dem nächsten case-Block weiter.

Habe den Code durch gesehen....
Leider nicht verstanden, was er tun soll.

Die Formatierung ist mir zu unübersichtlich.

Eine kleine Verbesserung am Rande:

Statt:

int pins[] = {3,5,6,9};
int leds = sizeof(pins)/2;

void setup() {
  Serial.begin(9600);
  
  for(int thispin = 0; thispin < leds; thispin++) {
    pinMode(pins[thispin], OUTPUT);
  } 
  pinMode(3, OUTPUT);
    pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
        pinMode(9, OUTPUT);
}

Dieses:

const byte pins[] = {3,5,6,9};
const byte leds   = sizeof(pins)/sizeof(pins[0]);

void setup() 
{
  Serial.begin(9600);
  for(byte pin:pins) pinMode(pin, OUTPUT); // diese Zeile kann man weg lassen
}

Die Referenz sagt:

You do not need to call pinMode() to set the pin as an output before calling analogWrite()

Noch eine weitere Ergänzung am Rande:
Bei dieser Form der for Schleife: for(byte pin:pins)
findet der Compiler selbst die Ende-Bedingung, daher

const byte leds   = sizeof(pins)/sizeof(pins[0]);  // diese Zeile kann man auch weg lassen

Macht aber am Sketch selber keinen Unterschied, weil der Compiler das sowieso weglässt, "weil unnötig".

// diese Zeile kann man auch weg lassen

Der Rest des Codes, des TE, basiert u.A. darauf.

Sollte man später Nebenläufigkeiten benötigen, wird man nicht auf einen LedCount verzichten können.
Denn beim eliminieren der delay() müssen die Schleifen ausgerollt werden.

Macht aber am Sketch selber keinen Unterschied, weil der Compiler das sowieso weglässt, "weil unnötig".

"wenn unnötig"
Und "wenn nötig" kostet es trotzdem kein Byte Ram.

Die Variante des TE benötigt 10 Byte Ram.
Meine 4 Byte.

michael_x:
Noch eine weitere Ergänzung am Rande:
Bei dieser Form der for Schleife: for(byte pin:pins)
findet der Compiler selbst die Ende-Bedingung, daher

const byte leds   = sizeof(pins)/sizeof(pins[0]);  // diese Zeile kann man auch weg lassen

Macht aber am Sketch selber keinen Unterschied, weil der Compiler das sowieso weglässt, "weil unnötig".

Dann muss ich "leds" aber wieder neu definieren, weil wenn ich es weglasse fehlt ihm ja die Referenz dazu und kompiliert nicht.

Vielen Dank an alle für die hilfreichen Tipps und Vorschläge. Funktioniert jetzt alles so wie es sein soll :wink:
Hier der jetzige Code (Wird noch "aufgehübscht"):

const byte pins[] = {3,5,6,9};
const byte leds   = sizeof(pins)/sizeof(pins[0]);
int shuffle= 0;
unsigned long timestamp=0;


void setup() 
{
  Serial.begin(9600);
  for(byte pin:pins) pinMode(pin, OUTPUT); // diese Zeile kann man weg lassen
}

 
void loop() {

 
 Serial.println(shuffle);

switch (shuffle){
  
  case 0:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(2);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(3);
        }         
      }
      delay(10); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(0); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 64; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(5);
        } 
        delay(0);
         // here ends the code for the fade out effect
      }
  
      digitalWrite(pins[i], LOW);    
     
  }
   if((millis()-timestamp)<5000){
   shuffle=0;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 3);
   timestamp = millis ();
  }
  break;}
  
  

  case 1:{
  for(int i = 0; i < leds; i++) {
    digitalWrite(pins[i], HIGH);
      if(i == 0) { // if first led delay for x ms
         delay(2);
      }
      if(i > 0) {
        int a = i-1;
        for (int t = 64; t >= 0; t--){
          analogWrite(pins[a], t);
          delay(4);
        }         
      }
      delay(10); // change for different drop speed
      if(i == leds-1) { // if last led
       delay(0); // how long the last led stays on
          // here starts the code for the fade out effect
          for (int t = 64; t >= 0; t--){ // a fadding effect
            analogWrite(pins[i], t);
          delay(5);
        } 
        delay(0);
         // here ends the code for the fade out effect
      }
     
      digitalWrite(pins[i], LOW); 
     
      
  }
   if((millis()-timestamp)<5000){
   shuffle=1;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 3);
   timestamp = millis ();
  }
  
break;}


case 2:{
 for(int b=0;b<leds;b++){
  digitalWrite(pins[b], HIGH); 
  }

  if((millis()-timestamp)<15000){
   shuffle=2;
   Serial.println(millis()-timestamp);
  }
  else {
   shuffle=random(0, 3);
   timestamp = millis ();
  }
  
}



          
   break;}
  
  }

@combie: Der Code bewirkt, dass 4 Leds in einem "Eiszapfen" nacheinander leuchten von oben nach unten mit einem Fading Effekt und in dem switch case durch random durcheinander eine bestimmte Zeit aktiv sind :wink: