Moingsen Gemeinde.
Ich habe mir eine kleine Steuerung für Fenster gebaut, Arduino Nano,
Temp-Sensor, Relaisboard und Linearmotor mit Endschalter.
Das Ganze funktioniert daher will ich es funktioneller machen.
Die Fenster werden in 3 Schritten geöffnet, das der Linearmotor
insgesamt 10 sec lang läuft, erst 2 sec, steigt die Temp weiter nochmal
4 sec und bei weiter steigender Temp noch einmal 4, dann ist das Fenster
komplett geöffnet und der Motor geht an den Endschalter und aus.
Diese Funktionalität habe ich bisher wie Folgt gelöst:
Der zaehler fungiert als Status analog zur Fensteröffnung und wird
nach jeder Teilöffnung mit hochgezählt, beim Schließen entsprechend
runter. D.h. zaehler == 0 Fenster sind geschlossen, bei zaehler == 1
ist die obige Teilschleife abgearbeitet. Die LED´s sind Status-LED´s um
zu sehen, da passiert was.
Ich will das jetzt umstellen, vom delay auf millis, weis nur eben nicht
so recht um das wie dahinter.
Relevant als Hintergrund dürfte sein, das die Motoren nicht alle auf
einmal laufen können, wegen der max Stromlast und daher nacheinander
angesteuert werden.
Vielleicht hat ja jemand von euch einen Vorschlag.
Mach das doch mit einer statemachine und den Millisekunden. Oder auf
Deutsch, einer Schrittkette.
Sinngemäß:
Schritt 1 Motor an
Wenn Zeit abgelaufen, weiterschalten
Schritt 2 Motor stoppen
usw.
Stefan ⛄ F. schrieb:> Xaver M. schrieb:>> Ich will das jetzt umstellen, vom delay auf millis, weis nur eben nicht>> so recht um das wie dahinter.>> Dort steht wie es geht.> http://stefanfrings.de/multithreading_arduino/index.html
Hervorragendes Beispiel, danke, das Beispiel passt sehr gut, bis auf das
"gleichzeitig" bei mir nicht geht, weil ich nicht über 6A Anlaufstrom
gehen kann.
Gibt es da eine Parallele zu dir?
Xaver M. schrieb:> Hervorragendes Beispiel, danke, das Beispiel passt sehr gut, bis auf das> "gleichzeitig" bei mir nicht geht
Dann setze es halt mit nur einem Thread um. Das wichtigste für die
Planung ist das Zustandsdiagramm oder die Tabelle.
Stefan ⛄ F. schrieb:> Xaver M. schrieb:>> Hervorragendes Beispiel, danke, das Beispiel passt sehr gut, bis auf das>> "gleichzeitig" bei mir nicht geht>> Dann setze es halt mit nur einem Thread um. Das wichtigste für die> Planung ist das Zustandsdiagramm oder die Tabelle.
Genau, ein Thread der nacheinander die Motoren ansteuert.
In dem letzten Beispiel am Ende auf der Seite müsste meinem Verständnis
nach das Intervall
1
intervalle=intervalle+1;
hochgezählt werden, bis
1
if(intervalle>=10)
Fehlt das in der Schleife? oder checke ich es doch nicht?
Xaver M. schrieb:> Fehlt das in der Schleife?
Der Thread hat seinen eigenen Intervall-Zähler. Deswegen ist die
Variable static. Die Idee ist, dass jeder Thread (wen mehrere
existieren) für sich zählt.
Man kann die Intervalle natürlich alternativ zentral zählen, aber dürfen
die Threads die Variable nicht auf 0 setzen. Das müsste man dann auch
noch umschreiben - dann wäre es am Ende nicht mehr einfacher, als das
Beispiel darüber.
Ist schon geändert.
Eine Rückfrage ist beim Umschreiben entstanden.
In der Teil-Schleife oben, wird das Fenster 2000ms lang geöffnet, von
insgesamt 10.000 ms. Ergo gibt es noch 2 weitere Teilschleifen deren
Öffnungszeit in Summe 10.000ms ergibt, das gleich nochmal zum schließen.
Kann ich die Öffnungszeit (aus diesem Bsp 378 ms) auch aus der Loop
übergeben?
1
switch(zustand)
2
{
3
caseAUS:
4
if(millis()-warteSeit>=378)
5
{
6
digitalWrite(LED_GRUEN,HIGH);
7
warteSeit=millis();
8
zustand=EIN;
9
}
10
break;
ich sehe da nämlich Konfliktpotential aufgrund der Startparameter
Hallo,
ich kann dir bei der letzten Frage nicht ganz folgen, dass ist mir dann
doch zu zerstückelt und unvollständig. Aber laut deinem
Eingangscodeschnipsel soll alles nacheinander und nicht parallel
abgearbeitet werden. Dafür habe ich ein Bsp. wie man das machen könnte.
Die Funktion wartezeit() wird mit 2 Parametern aufgerufen, die intern
nur auf "Zeit ist um" oder "nicht um" verglichen werden
Demententsprechend wird true oder false zurückgegeben. Wenn 'true' wird
der 'lastMillis' aktualisiert für den nächsten Vergleich im switch case.
Die Cases kannste nach dem Schema beliebig ausbauen. Die Funktion
'steuerung()' läuft damit ohne Blockierung wie man am Kontrollblinker
heartbeat() sieht.
Ich sehe da jetzt nicht den großen Unterschied in den Switch-Cases, bin
allerdings auch kein Programmierer um das genauer Beurteilen zu können.
Deine Einschätzung, Veit, ist richtig, ich habe 3 Motoren die ich
NACHEINANDER ansteuern muss.
Gerade bin ich dabei zu überlegen, ob ich die Zeit, die sie Motoren
angesteuert werden, aus dem Loop an die Switch-Case-Bedingung übergeben
kann, weil ich andernfalls 3 Switch-Cases zum Öffnen brauche (es sind 3
Teilöffnungen bis zur Gesamtöffnung), und das gleiche nocheinmal zum
Schließen, oder es bequemerweise in jeweils 3 gleich große
Öffnungszeiten aufteile;-) die dann auch 3 mal 1/3 = ein ganzes ergeben.
Hallo,
den Zeitvergleich im case kannste auch machen wie du es geschrieben
hast, dann fällt der wartezeit() Funktionsaufruf weg. Erstmal egal.
Wichtig ist, dass war glaube ich deine Frage, dass die Variable
'warteSeit' bzw. 'lastMillis' lokal static ist, dann gibts erstmal keine
Konflikte.
Die Intervallzeiten kannste natürlich bspw. der Funktion 'steuerung()'
als Parameter übergeben und verwenden.
Wenn das alles noch mehr ausarten soll, dann wäre es ratsam eine Klasse
zu schreiben, wenn alles nach gleichen Schema funktioniert.
Ja, Öffnen und Schließen der Fenster Funktioniert nach Schema F, öffnen
über 3 Pins, schließen über 3 andere, das ganze steuert dann Relais mit
einer H-Brücke an, um die Polarität der Motoren zu steuern.
Bis ich mich mit Klassen beschäftige wird es noch ein wenig dauern.
Die Öffnungsintervalle/-zeiten habe ich jetzt mal gleich gemacht (immer
1/3tel, so das immer die gleiche Funktion aufgerufen wird. Ich glaube
nicht das es einen großen Unterschied machen wird bei 1/10tel
Unterschied, evtl. wird an kalten und sonnigen Tagen das Fenster
zwischendurch mal geschlossen.
Um das zu überprüfen werde ich die Temp und Feuchte mal auf einer
SD-Karte mitloggen und dann ggf. neu entscheiden.
Im Moment ist das alles noch im Prototypenstadium und wird entsprechend
getestet.
Danke für alle Hinweise zur Lösung.
Ich konnte es schlußendlich erfolgreich umsetzen, auch wenn es einige
Zeit und Mühe gekostet hat.
Zustandsautomat ist von der Erklärung nicht so schwer zu verstehen,
dafür hat es die Umsetzung in einen Code als Anfänger in sich.
@ Stefanus: dein Link hat mir, nach dem es zwar in der Loop
funktionierte aber nicht als ausgelagerte Funktion, gezeigt wie ich es
in eine Fkt auslagern muss damit es eigenständig funktioniert. Danke
dafür.
@devil-elec: mal sehen ob ich es jetzt in eine Klasse auslagern kann.