> Und zwar geht es darum das ich 3 Magnetventile habe die ich gerne
> zu unterschiedlichen Zeitpunkten schalten möchte nachdem ich einmalig
> einen Taster betätigt habe. Das ganze funktioniert auch schon mittels
> der delay Funktion, nur möchte ich diese ersetzen.
Löblich
> Zur Umsetzung meiner Idee möchte ich meiner Hauptschleife eine
> feste Taskzeit zuweisen. Meine Idee hierfür sieht wie folgt aus:
Machs nicht so kompliziert.
Das Arduino Basissystem stellt dir in Form der Funktion millis() schon
alles zur Verfügung was du brauchst. Du musst nur weg vom Gedankengang
des 'Zeiten werden gemessen, indem man so lange Däumchen dreht'.
Statt dessen benutzt du millis() genauso wie du die Sache mit einer Uhr
mit Sekundenzeiger angehen würdest. Kommt das StartEreignis genau dann,
wenn der Sekundenzeiger auf 28 steht, dann kannst du dir ausrechnen,
dass bei einer gewünschten Einschaltdauer von zb 8 Sekunden du bei 28 +
8 gleich 36 wieder ausschalten musst. Und genau das tust du dann
laufend: Neben anderen Dingen beobschtest du auch immer kurz den
Sekundenzeiger und wenn der auf 36 steht, dann schaltest du wieder aus.
1 | unsigned long Zeit1;
|
2 | unsigned long Zeit2;
|
3 |
|
4 | void loop()
|
5 | {
|
6 | unsigned long now = millis();
|
7 |
|
8 | if( now > Zeit1 )
|
9 | {
|
10 | digitalWrite(ledpin1, digitalRead(ledpin1) ^ 1);
|
11 | Zeit1 = now + 2000;
|
12 | }
|
13 |
|
14 | if( now > Zeit2 )
|
15 | {
|
16 | digitalWrite(ledpin2, digitalRead(ledpin2) ^ 1);
|
17 | Zeit1 = now + 3000;
|
18 | }
|
19 | }
|
Im Beispiel blinken die LED alle 2 Sekunden bzw. 3 Sekunden, weil bei
jedem Umschalten der LED berechnet wird, zu welchem Zeitpunkt die LED
das nächste mal umzuschalten ist. Und das eine mal ist das dann eben 2
Sekunden (2000 Millisekunden) später und bei der anderen LED sind es
eben 3 Sekunden (3000 Millisekunden).
Die Hauptschleife loop hat dann nur noch die Aufgabe laufend zu
überprüfen, ob die so errechneten Zeitpunkte erreicht sind und wenn ja
die entsprechenden Aktionen einzuleiten.
eine andere Technik, die weniger Probleme beim Rollover von millis()
haben wird, ist die, dass du die Differenz zum Startzeitpunkt
feststellst und wenn die die von dir gewünschte Zeitdauer erreicht hat,
schaltest du wieder ab.
1 | unsigned long Zeit1;
|
2 | unsigned long Zeit2;
|
3 |
|
4 | void loop()
|
5 | {
|
6 | unsigned long now = millis();
|
7 |
|
8 | if( ( now - Zeit1 ) >= 2000 )
|
9 | {
|
10 | digitalWrite(ledpin1, digitalRead(ledpin1) ^ 1);
|
11 | Zeit1 = now;
|
12 | }
|
13 |
|
14 | if( ( now - Zeit2 ) >= 3000 )
|
15 | {
|
16 | digitalWrite(ledpin2, digitalRead(ledpin2) ^ 1);
|
17 | Zeit2 = now;
|
18 | }
|
19 | }
|
Jetzt gibt es dann auch keine Probleme mehr, wenn nach rund 49 Tagen der
Zahlenwert von millis() auf einen Schlag von "sehr groß" auf 0
überläuft. Die unsigned Rechnung gleicht das wieder aus, die Differenz
stimmt trotz dieses Überlaufs immer noch.
Und weil du jetzt keine Warteschleifen mehr hast, kannst du jetzt neben
(in diesem Beispiel) den beiden LED noch andere Sachen machen. Die LED
blinken trotzdem im vorgegebenen Takt weiter. Bei dir ist das dann eben
eine Einmalaktion und es sind keine LED sondern Ventile, aber die
grundlegende Technik, wie man Zeiten abarbeitet, ist genau die gleiche.