Multitasking

Servus,
Ich arbeite momentan an einem Projekt was Multitasking erfordert. Hierbei habe ich die millis() Methode
verwendet. Dies hat für einfache Aktionen einwandfrei funktioniert doch für das folgende "Problem" habe ich bis jetzt noch keine passenden Lösung gefunden. Ich möchte einen Lüfter alle 20 Sekunden für 5 Sekunden anschalten und dabei kein delay() verwenden. Anbei findet ihr den Snippet des nicht funktionierenden Sketches.
Vielen Dank

if (millis() - previousVentilationMillis >= 20000) {
    previousVentilationMillis = millis(); 
    
    digitalWrite(transistorFanPin, HIGH);   //turns on fan
    fanState = true; 
  }

  if (millis() >= previousVentilationMillis + 5000) {
    digitalWrite(transistorFanPin, LOW);   //turns off  fan
    fanState = false;
  }

Du suchst nach einer Ablaufsteuerung = Schrittkette = finite state machine = endlicher Automat.

  1. Schritt: 20 s warten
  2. Schritt: 5 s einschalten

Oder Du versucht mal sowas:

if ((millis() - previousVentilationMillis >= 20000) && !fanState) {
    digitalWrite(transistorFanPin, HIGH);   //turns on fan
    fanState = true;
  }

  if (millis() - previousVentilationMillis >= 25000) {
    previousVentilationMillis = millis();
    digitalWrite(transistorFanPin, LOW);   //turns off  fan
    fanState = false;
  }

Ich mach sowas mit einfachen Timern.
Du benutzt das blink-without-delay-Prinzip.

Den Timer stellst du so ein, dass er die kleinste Zeiteinheit, die du brauchst, misst-hier also 5s.
Den Rest kannst du dann mit einfachen Zählern machen:

-jedes Mal, wenn der Timer einen "Tick" gibt, wird ein Zähler erhöht (erreicht er 6, wird er wieder auf 0 gestellt) und nun kannst du den Zähler einfach auswerten: bei 1 wird der Lüfter eingeschalten, bei 2 aus, bei den anderen Werten passiert nix.

Solche Timer kann man noch für weit komplexere Abläufe benutzen, da man den Zähler wie eine ISR behandeln kann- der blockiert praktisch nix.
Und in der Hauptschleife guckt man dann einfach jedes Mal nach, welchen Stand er hat- und lässt entsprechende Dinge tun.

Vielen Dank euch beiden!
Ich werde mal schauen welche Option sich in meinem Fall am besten anbietet.
LG

Hi

Ist Dir denn bewusst geworden, warum Dein Snipped nicht funktioniert hat?
Da beide Abfragen NUR die abgelaufene Zeit beinhalteten, wurde nach 5 Sekunden immer der Lüfter ausgeschaltet und die Startzeit neu gesetzt.
Fünf Sekunden später, waren wieder diese 5 Sekunden um - und obwohl der Lüfter gar nicht an war, wird Er wieder ausgeschaltet - und wir merken uns die neue Startzeit.

In agmue's Snipped ist bei der kürzeren Wartezeit noch der Status in der Abfrage enthalten - so greift die kürzere Zeit nur, wenn auch der dafür passende Status gerade aktuell ist.
Die längere Zeit würde immer greifen - nur wird die Startzeit halt vorher wieder neu gesetzt - und dann ignoriert die obere Abfrage, da der Status nicht passt.

MfG