Wie /Wo millis() funktion?

Hallo!
Brauche hilfe mit millis funktion. ein paar sachen habe ich von anderen beispielen vom englischen forum reinkopiert und ausprobiert. ich weiss aber nicht genau wie das funktionien soll.

in meinem projekt gibt es verschiedene stufen. wenn man eine stufe erreicht hat kann man sie mit einem knopf ausschalten. wenn man das innerhalb eines intervals nicht tut, geht es zur nächsten stufe weiter.

stufen:
0. alles auf off.

  1. licht 1 geht an.
  2. licht 2 geht auch an.
  3. sound geht auch an.
  4. alles auf aus. schaltet sich endgültig aus.

hier der code bei jetzigem stand.

int Button = 10;                 //define the 10th digital pin for button brick
int LED = 11;                    //define the 11th digital pin for LED brick
int LED2 = 9;                    //define the 9th digital pin for LED2 brick
int speakerPin = 8;              // Analog output to speaker
int state = 0;
unsigned long currentTime  = 0; //this variable will be overwritten by millis() each iteration of loop
unsigned long pastTime     = 0; //no time has passed yet
int wait = 0; //no need to wait, nothing has happened yet
int buttonState;                // variable to hold the button state



void setup()
{
  
        pinMode(LED,OUTPUT);           //set the LED pin for digital output
        pinMode(LED2,OUTPUT);          //set the LED2 pin for digital output
        pinMode(Button,INPUT);         //set the Button pin for digital input
        pinMode(speakerPin, OUTPUT);   //set the Button pin for digital input
        Serial.begin(9600);           // Set up serial communication at 9600bps
        
}
        

void loop()
{  
  
           pastTime = currentTime; //currentTime at this point is the current time from the previous iteration, this should now be pastTime
           currentTime = millis();    //currentTime is now the current time (again).
           unsigned long timePassed = currentTime - pastTime; //this is roll-over proof, if currentTime is small, and pastTime large, the result rolls over to a small positive value, the time that has passed
  
          if(state == 0){
            delay(2000);                   // So und so viele Stunden Schlaf (muss vor dem Schlafen eingestellt werden)
            
            digitalWrite(LED,LOW);
            digitalWrite(LED2,LOW);
            digitalWrite(speakerPin, LOW);
            
            state = 1;
            
          }
             
          if(state == 1){
            digitalWrite(LED,HIGH); 
            
            if(digitalRead(Button)){     // if button press

              digitalWrite(LED,LOW);     // LED turns off
              digitalWrite(LED2,LOW);     // LED turns off
              digitalWrite(speakerPin, LOW);
                        
              state = 4;  

              }
            
            if(timePassed = currentTime - pastTime){     
              currentTime = 4000;
              state = 2;
            }
            
          }
          
          if(state == 2){
            digitalWrite(LED,HIGH); 
            digitalWrite(LED2,HIGH);    
            
            if(digitalRead(Button)){     // if button press
            wait = 4000;
              digitalWrite(LED,LOW);     // LED turns off
              digitalWrite(LED2,LOW);     // LED turns off
              digitalWrite(speakerPin, LOW);
            
              state = 4;
            
              }
          
            if(timePassed = currentTime - pastTime){     
              currentTime = 4000;                
              state = 3;
            }
      
          }    
                  
         if(state == 3){
            digitalWrite(LED,HIGH); 
            digitalWrite(LED2,HIGH);  
            digitalWrite(speakerPin, HIGH); 
            
            if(digitalRead(Button)){     // if button press
            digitalWrite(LED,LOW);     // LED turns off
            digitalWrite(LED2,LOW);     // LED turns off
            digitalWrite(speakerPin, LOW);
            
            state = 4;
            
            }
            
         }    
                          
         if(state == 4){
                 
         }      
        
}

ein paar sachen habe ich von anderen beispielen vom englischen forum reinkopiert

Definitiv... :slight_smile:

Entschuldige, wenn ich das so sage, aber das ist viel zu konfus.

Was genau willst Du erreichen?

konfus stimmt schon mal :slight_smile:

also, das erste licht schaltet sich ein. wenn man innerhalb 4 sek den knopf nicht drückt (alles auf off => state = 4) schaltet sich das licht 2 ein. wenn man wiederum innerhalb der nächsten 4 sek denselben knopf nicht drückt, schaltet sich der sound an. danach kann man wann man will den knopf drücken und alles geht auf off (state = 4).
ein bisschen klarer?

reinkopiert ist übrigens nur die zeitfunktionen. ich kann zwar englisch aber millis erklärungen dazu find ich ziemlich verwirrend...

Also ich würd in dem Fall nicht unbedingt mit Delays arbeiten, da Dein Buttondruck sonst nur beim Wechsel der Zustände geprüft wird.

Du kannst also quasi nach einer Sekunde nachdem das Licht an ging auf den Knopf drücken, ihn zwei Sekunden halten und dann loslassen, und eine Sekunde später, wenn der erste State durch ist, weiß das System trotzdem nicht, dass Du gedrückt hast...

Ist das so Absicht?

eigentlich sollten state 1 und 2 es so funtionieren wie beim state 3. einmal knopf drücken und loslassen und dann zu state 4 übergehen. mit delay hab ichs auch schon versucht. dabei müsste man allerdings während den 4 sek den knopf gedrückt halten, das soll aber nicht so sein.

Achso, ok. Dann würd ich aber an Deiner Stelle im setup() die aktuelle Zeit abspeichern, und dann nur noch mit Differenzen dazu arbeiten...

Vielleicht was in der Art...

int nextState = 0;

void setup() {
  [...]
  currentTime = millis();
  [...]
}

void loop() {
  if (millis()-currentTime < 4000) { // Innerhalb der ersten vier Sekunden
    if (digitalRead(Button)) {
      nextState = 4;
    }
  }
  if (millis()-currentTime >= 4000 && state==0 && nextState!=0) {
    state = nextState;
  }
}

Natürlich nur so ungefähr. :wink:

danke.
kannst mir mal erklären was im setup das currentTime und millis() genau macht, oder besser für was sie stehen? das currentTime die momentane Zeit ist weiss ich, aber wie funktioniert das im zusammenhang mit millis()?

Naja, wenn Du die Variable currentTime auf den Wert von millis() setzt, dann wird "millis()-currentTime" eine Sekunde später "1000" ausspucken. :slight_smile:
Weil, millis() ist dann ja 1000 Millisekunden weiter...

Somit kannst Du dann in der Loop immer sagen, wieviel Zeit vergangen ist, und zwar ohne mit Delay das ganze Zeug anhalten zu müssen...

hast du das so gemeint?
leuchtet erst das erste licht auf, und der knopf reagiert noch nicht, wahrscheinlich ein tipp fehler?

int Button = 10;                 //define the 10th digital pin for button brick
int LED = 11;                    //define the 11th digital pin for LED brick
int LED2 = 9;                    //define the 9th digital pin for LED2 brick
int speakerPin = 8;              // Analog output to speaker
int state = 0;
int nextState = 4;
int currentTime = 0;


void setup()
{
  
        pinMode(LED,OUTPUT);           //set the LED pin for digital output
        pinMode(LED2,OUTPUT);          //set the LED2 pin for digital output
        pinMode(Button,INPUT);         //set the Button pin for digital input
        pinMode(speakerPin, OUTPUT);   //set the Button pin for digital input
        Serial.begin(9600);           // Set up serial communication at 9600bps
        currentTime = millis();
        
}


void loop()
{  
    
          if(state == 0){
            delay(2000);                   // So und so viele Stunden Schlaf (muss vor dem Schlafen eingestellt werden)
            
            digitalWrite(LED,LOW);
            digitalWrite(LED2,LOW);
            digitalWrite(speakerPin, LOW);
            
            state = 1;            
          }
           
  
          if(state == 1){
            digitalWrite(LED,HIGH); 
                        
              if(millis()-currentTime < 4000) { // Innerhalb der ersten vier Sekunden
                 if (digitalRead(Button)) {
                  nextState = 4;
                 }
              }            
          }
              
          if(millis()-currentTime >= 4000 && state==1 && nextState!=4) { // Zeit nach 4 Sekunden
            state = 2; 
          }          
          
          if(state == 2){
            digitalWrite(LED,HIGH); 
            digitalWrite(LED2,HIGH);    
            
            if(millis()-currentTime < 8000) 
               if (digitalRead(Button)) {
                nextState = 4;
               }      
          }    
          
          if(millis()-currentTime >= 8000 && state==2 && nextState!=4) {
            state = 3; 
          }
         
          if(state == 3){
            digitalWrite(LED,HIGH); 
            digitalWrite(LED2,HIGH);  
            digitalWrite(speakerPin, HIGH); 
            
            if(millis()-currentTime < 12000) { 
               if (digitalRead(Button)) {
                nextState = 4;
               }
            }                                    
          }
         
          if(millis()-currentTime >= 12000 && state==3 && nextState!=4) {
            state = 4; 
          }
                                          
          if(state == 4){ 
            nextState = 4;          
          }           
      
          if(nextState == 4){
        
          }    
        
}

Ich glaub, so langsam komme ich dahinter, was Du eigentlich haben willst... :wink:

Etwas in der Art...?

int Button = 10;            //define the 10th digital pin for button brick
int LED = 11;                  //define the 11th digital pin for LED brick
int LED2 = 9;                  //define the 9th digital pin for LED2 brick
int speakerPin = 8;            // Analog output to speaker
int state = 0;
int currentTime = 0;

void setup()
{
      pinMode(LED, OUTPUT);                  //set the LED pin for digital output
      pinMode(LED2, OUTPUT);            //set the LED2 pin for digital output
      pinMode(Button, INPUT);                  //set the Button pin for digital input
      pinMode(speakerPin, OUTPUT);      //set the Button pin for digital input
      Serial.begin(9600);                        // Set up serial communication at 9600bps

      // Pins resetten, zur Sicherheit...
      digitalWrite(LED, LOW);
      digitalWrite(LED2, LOW);
      digitalWrite(speakerPin, LOW);
}

void loop()
{
      if (state == 0) {
            // So und so viele Stunden Schlaf (muss vor dem Schlafen eingestellt werden)
            delay(2000);

            // Am Besten erst jetzt die "Stunde Null" festlegen, wegen dem unbekannten "Schlaf"!
            currentTime = millis();

            // Erste LED einschalten
            digitalWrite(LED, HIGH);
            state = 1;
      }

      if (state==1 && millis()-currentTime >= 4000) {
            // Nach 4 Sekunden die zweite LED einschalten
            digitalWrite(LED2,HIGH);
            state = 2;
      }

      if (state == 2 && millis()-currentTime >= 8000) {
            // Nach weiteren 4 Sekunden den Lautsprecher einschalten
            digitalWrite(speakerPin, HIGH);
            state = 3;
      }

      if (digitalRead(Button) == HIGH) {
            digitalWrite(LED, LOW);
            digitalWrite(LED2, LOW);
            digitalWrite(speakerPin, LOW);
            state = 4; // Innerhalb der States 1-3 jederzeit alles Ausschalten!
            // Man koennte hier aber z.B. auch zu State 0 wechseln, wenn man woellte... ;)
      }
}

PS: Es kann sein, dass da noch der ein oder andere kleine Fehler drin ist, hab ich hier kurz in einem Texteditor zusammen geschrieben und konnte es nicht testen...