Taster abfragen während loop läuft

Man kann Interrupts benutzen, löst aber i.d.R. einen ziemlichen Shitstorm im Forum aus :wink:

Der Hintergrund ist das erforderliche "Debouncing/Entprellen" mechanischer Taster, da diese dazu tendieren beim Umschalten sehr häufig zwischen Kontakt/kein Kontakt hin- und herzuschwingen. Damit kann man per Interrupt den Controller unschön beschäftigen ...

Für Deine Aufgabe sollte es genügen, auf eine Schleife zu verzichten und stattdessen das Takten per Zeitabfrage zu erledigen. Am Einfachsten mit der millis()-Funktion, man kann auch micros() verwenden, wenn es "schneller" gehen muss .

Hier nur ein Ausschnitt:

unsigned long beginToWait = 0;
const int wait1s   =  1000;

boolean TimeIsOver(unsigned long TimeToWait){
   if(millis()-beginToWait > TimeToWait) {
          return true;
   } else return false;
}  

void loop(){
    if (TimeIsOver(wait1s)){
          // Do something
           beginToWait = millis();
   } 
} 

Man muss allerdings etwas umdenken, und Schleifen durch zeitlich getaktete und ggf. durch boolsche Variable gegenseitig verriegelnde Routinen ersetzen ... Und man braucht ggf. je eine eigene Variable "beginToWait" für jede parallel zu taktende Funktion . Um die Routine nicht mehrfach zu schreiben, kann man dafür ein Array beginToWait[3] o.ä. nehmen, desse Index man in TimeIsOver() einarbeitet:

const byte NoOfTimes = 3;
unsigned long beginToWait[NoOfTimes];
const int wait1s   =  1000;
const int wait3s   =  3000;

boolean TimeIsOver(int Index, unsigned long TimeToWait){
   if(millis()-beginToWait[Index] > TimeToWait) {
          return true;
   } else return false;
}  

void setup(){
  for (int i=0; i< NoOfTimes;i++) beginToWait[i] = 0;
}

void loop(){
    if (TimeIsOver(0, wait1s)){
          // Do something
           beginToWait[0] = millis();
   } 
    if (TimeIsOver(1, wait3s)){
          // Do something
           beginToWait[1] = millis();
   } 
}

P.S.: (Ungetester Code, da hier direkt hineingeschrieben :wink: ).

1 Like