Hallo,
ich bin grad am programmieren meines Arduino Uno für eine Kameraschiene.
Jedoch bin ich grad auf das Problem gestoßen, dass ich die zeitlichen Abläufe nicht über die delay()-Funktion machen kann, da beispielsweise so keine Tasteneingaben mehr möglich sind.
Mein Ablauf schaut wie folgt aus:
Taster schaltet die Funktion ein
Ausgang A (Motor) wird für eine bestimmte Zeit 1 eingeschaltet
Nach Ablauf dieser Zeit 1, wird eine Verzögerung Zeit 2 aktiviert
Nach Ablauf von Zeit 2 wird Ausgang B (DSLR) für eine bestimmte Zeit 3 aktiviert
Nach Ablauf von Zeit 3 folgt eine Verzögerung von Zeit 4 und das Programm wiederholt sich
Ich bin Arduino-Anfänger und habe zunächst die delay()-Funktion als Verzögerung eingesetzt. Da jedoch immer ein delay aktiviert ist, kann ich keine Eingaben über meine Taster machen.
Wie kann ich am einfachsten die o.g. Funktion realisieren? Ich hatte mir schon die BlinkWithoutDelay und ein paar timer-Libraries angeschaut. Jedoch zwar nichts dabei, was bei mehreren Timern einigermaßen übersichtig bzw. einfach aussau.
Am besten vergegenwärtigt man sich das Verhalten des Controllers mit einem Endlichen Zustandsautomaten (Endlicher Automat – Wikipedia). Bedingungen für Zustandswechsel sind dann nicht nur externe Ereignisse, sondern könnten dann auch abgelaufene Zeitperioden sein. Beispiel: Ausgangszustand sei A. Nach 5 Sekunden soll Zustand B eingenommen werden: Bei betreten von Zustand A berechnet man die neue Zielzeit aus der aktuellen Zeit plus 5 Sekunden. Wenn die Zielzeit erreicht ist, wird der Zustand auf B gewechselt.
Das BlinkWithoutDelay-Beispiel hatte ich mir schon angeschaut.
Ich als absoluter Programmier-Anfänger, weiß aber nicht, wie ich z.B. unterschiedliche Zeiten für das Ein/Aus einstellen kann. Das Beispiel schaltet ja die LED 1 Sekunde aus, und 1 Sekunde ein. Ich bräuchte aber beispielsweise 1 Sekunden ein und 5 Sekunden aus.
Außerdem verstehe ich nicht, wie ich mehrere dieser Timer aktiviere und benutze.
Für eine normales Ein/Aus mag das Beispiel zwar geeignet sein. Sobald aber mehrere Timer genutzt werden sollen, finde ich, dass das Beispiel viel zu wenig beschrieben ist.
Das BlinkWithoutDelay-Beispiel funktioniert folgendermaßen.
Die Funktion millis() gibt die Millisekunden zurück, die vergangen sind seitdem Arduino eingeschaltet oder resetiert wurde.
Du speicherst die Startzeit ab un kontrolliest durch subtrahieren der Startzeit von der jetztzeit ob die Wartezeit schon vorbei ist.
Wenn Du mehrere solche Abläufe kontrollieren willst ( 2 LED unterschiedlich blinken) dann verwende mehrere variablen für die Startzeiten.
... und außerdem brauchst du wohl eine Variable, die dir sagt in welchem Schritt du grade bist.
int Schritt;
unsigned long Dauer;
unsigned long previousMillis;
...
void loop ()
{
unsigned long currentMillis = millis();
...
if ( currentMillis - previousMillis > Dauer )
{
Schritt++; // nächster Schritt
switch (Schritt)
{
case 1:
// Motor Ein
Dauer = 5000; // sec warten
break;
case 2:
// Motor aus
Dauer = 1000; // Pause zeit 2
break;
// .... Beliebig weitere Schritte definieren
default:
Schritt = 0;
Dauer = 1; // Schrittfolge wieder von vorn
}
previousMillis = currentMillis; // "Delay" neu starten
}
// hier evtl. Tasterabfragen, um die Schrittfolge zu ändern oder Wartezeiten abzubrechen o.ä.
}
Schon richtig, aber das Problem mit "Blink without Delay" ist, dass die Leute sagen: prima, aber an/aus Blinken reicht mir nicht...
Und eine "State-Machine" ist auch richtig, aber abschreckend ...
@Michael: Vielen Dank, dein Code ist genau das was ich gesucht habe, funktioniert genauso wie ich es wollte.
Jedoch habe ich da noch eine Frage:
Die Funktion soll nur dann ablaufen, wenn der Einschalter auf 1 steht und der Endlageschalter auf 0. Sobald sich einer dieser Werte ändert, soll der Ablauf gestoppt werden.
Mein Ansatz mit der if-Bedingung:
if (endlageValue == 0 && einaus == 1)
{
...
}
Wenn ich den Endschalter betätigt (=1) und Einschalter(einaus=1), passiert nichts. Wenn ich den Endschalter loslasse, startet die Funktion. Also genau so wie ich es will. Wenn jedoch die Funktion abläuft und ich den Endschalter oder Einschalter betätige, dann läuft die Funktion immer noch weiter bzw. wird am momentanen Schritt gestoppt und der Schritt läuft im Dauermodus.
Was muss ich ändern, damit die Funktion beim Ändern der Bedingungen sich resettet bzw. stoppt?