Funktioniert alles. Setze mich die Tage dann mal dran den nächsten Servo einzubinden. Melde mich dann nochmal!
Posts by Colonn
Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
Mach mit und werde Teil unserer Community!
-
-
Gut also das Problem hat sich gelöst war wohl ein wackler oder sowas. Komisch ist nur: Wenn ich den Schalter auf OFF stelle dreht der Servo sofort ohne Verzögerung. Wenn ich dann auf ON stelle wartet er die gewünschte Zeit. Eigentlich sollte es aber andersrum sein. HIGH und LOW tauschen ist nur wenig sinnig, da damit ja die folgenden Aktionnen verknüpft sind wie Relais ein/aus, etc. oder?
Habe gerade mal überall eine Verzugszeit reingeschrieben, aber selbst da geht der Servo bei OFF direkt zurück.
-
So die Version mal länger getestet. Nach ca 2 Minuten macht sich der Servo selbstständig und öffnet/schließt ohne Signal. Schalter habe ich mal abgeklemmt damit ich den ausschließen kann. Ein Softwareproblem oder eher Hardware?
-
Das scheint es schon gewesen zu sein. Danke!
-
Code
Display More#include <Servo.h> Servo Blastgate1; int Tellerschleifer = 1; int Relais = 13; int zustand_tellerschleifer = 0; int schliesszeit_tellerschleifer = 0; void setup() { Blastgate1.attach(8); pinMode(Tellerschleifer, INPUT); pinMode(Relais, OUTPUT); } void loop() { if (zustand_tellerschleifer == 0) { if (digitalRead(Tellerschleifer) == HIGH) { digitalWrite(Relais, HIGH); Blastgate1.write(90); zustand_tellerschleifer = 1; } } if (zustand_tellerschleifer == 1) { if (digitalRead(Tellerschleifer) == LOW) { zustand_tellerschleifer = 2; schliesszeit_tellerschleifer = millis()+3000; } } if (zustand_tellerschleifer == 2) { if (millis() > schliesszeit_tellerschleifer) { digitalWrite(Relais, LOW); Blastgate1.write(120); zustand_tellerschleifer = 0; } }}
-
So habe jetzt mal wieder Zeit gehabt. Habe das Programm getestet und es funktioniert... für eine halbe Minute ungefähr. Dann geht erstmal garnichts mehr am Servo. Nach einer weiteren halben Minute geht der Servo zwar wieder, aber es gibt beim schließen plötzlich keine Verzugszeit mehr. Sowohl auf als auch zu geht direkt.
-
Guten Tag Colonn,
Noch ein Hinweis zu den millis():
Irgendwann nach einigen Monaten läuft auch diese Variable mal über, das heißt der Zählwert beginnt wieder bei 0 ( Null).
Nun weis ich nicht, ob dein Arduino im Dauerbetrieb und ständig unter Strom bleibt, und ob dieser Überlauf-Effekt bei dir auftreten könnte.
Darum prüfe ggf ob der Startwert aus millis() ausgelesen Plus der Verweilzeit überhaupt erreicht werden kann. Nicht dass das Programm dann in eine Endlosschleife festhängt, ohne das die Abschaltbedingung erreicht werden kann.
Wenn dieses Steuer-Arduino nur dann unter Spannung ist, wenn du in der Werkstatt / Garage arbeitest, dann betrachte diese Anmerkung als Gegenstandslos.Das mit den millis sollte kein Problem sein. Wenn die Werkstatt abgeschlossen ist, dann ist alles stromlos sprich der Arduino aus. Aber trotzdem danke für den Hinweis.
-
Also welchen Strom die ziehen habe ich noch nicht gemessen. Aber mit der externen Spannungsquelle funktioniert das genau so wie ich es mir vorgestellt habe.
Danke schonmal! Morgen erweitere ich den Code dann für die anderen beiden Servos und schaue mal.
-
Habe ja auch deinen genommen.
-
Haha
jetzt geht es auch. Der Servo lässt den Arduino also für Millisekunden abstürzen und deswegen hatte ich das Problem. Code funktioniert jetzt. Werde das mal mit den zwei weiteren probieren ob es dann immernoch funktioniert.
-
Kann mir vorstellen das mein Servo einen zu großen Strom zieht. Das würde zumindest erklären warum es so unzuverlässig läuft. Muss dem mal eine eigene Spannung beereitstelleen.
-
schalter
-
Der Arduino zählt die Millisekunden von seinem Start an. Die Zahl kannst du mit millis() abfragen. Du fragst also die Zahl ab und erhältst zum Beispiel 1453812, dann rechnest du 2000 ms drauf (also 2 Sekunden) und prüfst in der Schleife immer wieder, ob milis() größer ist als diese Zielzeit (1455812). Wenn das der Fall ist, schaltest du den Servo, weil dann die 2 Sekunden um sind.
Habe gerade schon ein wenig Hoffnung verspürt. Es geht kurz einmal aber dann wenn man es ein zweites mal probiert fährt der Servo nurnoch andeutend die 90 an aber bricht ab. Als wenn ein Befehl kommen würde fahre zurück obwohl er nichtmal angekommen ist.
-
Hier mein "Versuch":
C
Display More#include <Servo.h> // Definitionen #define Tellerschleifer (20) #define Sauger (21) #define Kapp (22) #define Relais (23) #define servo1Pin (10) #define servo2Pin (11) #define servo3Pin (12) #define angleOff (120) #define angleOn (90) // Globale Objekte Servo servo1; Servo servo2; Servo servo3; // digitalRead liefert ein HIGH oder LOW zurück // in der Doku habe ich nicht gefunden, welcher Datentyp das ist // ich gehe mal von bool aus, könnte aber auch ein int sein oder // irgendwas anderes bool currentState[] = {false, false, false}; void setup() { servo1.attach(servo1Pin); servo1.attach(servo2Pin); servo1.attach(servo3Pin); pinMode(Tellerschleifer, INPUT); pinMode(Sauger, INPUT); pinMode(Kapp, INPUT); pinMode(Relais, OUTPUT); } // alle Eingänge einlesen und in array currentState speichern void readInputs() { currentState[0] = digitalRead(Tellerschleifer); currentState[1] = digitalRead(Sauger); currentState[2] = digitalRead(Kapp); } // hier die Logik void logic() { // Abbruchbedingung zuerst if (currentState[0] == LOW and currentState[1] == LOW and currentState[2] == LOW) { digitalWrite(Relais, LOW); servo1.write(angleOff); servo2.write(angleOff); servo3.write(angleOff); return; // alle eingänge sind false // Funktion wird verlassen } // wenn nicht alle Eingänge false sind. if (currentState[0]) { servo1.write(angleOn); digitalWrite(Relais, HIGH); } // hier kein delay if (currentState[1]) { servo2.write(angleOn); digitalWrite(Relais, HIGH); } // hier kein delay if (currentState[2]) { servo3.write(angleOn); digitalWrite(Relais, HIGH); } } void loop() { readInputs(); logic(); delay(2000); }
Als Bibliothek habe ich diese verwendet: https://www.arduino.cc/reference/en/libraries/servo/
Bei C habe ich immer das Gefühl, dass man alles machen soll/darf, was in Python nicht gern gesehen wird.
Ob das mit den Definitionen so gut ist, weiß ich auch nicht.
Jedenfalls wird alles mit #define vor dem Kompilieren des Quellcodes durch die Zahlen ersetzt.
Es handelt sich nicht um Varia
Ich habe den Code mal hochgeladen und meine Pins eingesetzt. Da passiert bei mir garnichts dann
-
Der Ansatz von Willi ist schon im Prinzip der Richtige, sofern man es mit einfachen Mitteln macht. Das nennt man "Superloop".
Die Main-Schleife wird in kurzen Zyklen durchlaufen und beinhaltet keine Delays. Wo pausen gebraucht werden, schaut man sozusagen auf die Uhr, addiert die gewünschte Pausenzeit dazu und lässt die Schleife weiter laufen. Irgendwo prüft man die voranschreitende Uhrzeit bei jedem Schleifendurchlauf und wenn die Zielzeit erreicht ist, führt man das Gewünschte (Servomotor zurückstellen) aus.
Um das übersichtlicher zu machen, lagert man meist die Arbeitsschritte in Funktionen aus.
Der Einfachheit halber könntest du hier mit drei Zuständen deines Servos arbeiten: auf = 1, zu = 0, warten (auf schließen) = 2.
Code
Display MoreIf (zustand_tellerschleifer == 0 { if (digitalRead(Tellerschleifer) == HIGH) { digitalWrite(Relais, HIGH); Blastgate1.write(90); zustand_tellerscheifer = 1; } } If (zustand_tellerschleifer == 1 { if (digitalRead(Tellerschleifer) == LOW) { zustand_tellerscheifer = 2; schliesszeit_tellerschleifer = millis()+2000; } } If ((zustand_tellerschleifer == 2) { if (millis() > schliesszeit_tellerschleifer) { digitalWrite(Relais, LOW); Blastgate1.write(120); zustand_tellerscheifer = 0; } }
So ungefähr könnte es aussehen. Ich hab die Bedingungen verschachtelt, damit es übersichtlich ist, du kannst natürlich auch mit && arbeiten.
Die Zustandsvariable hab ich zustand_tellerschleifer genannt - du kannst sie natürlich auch var1 nennen.
Die einzelnen Blöcke kannst du auch in Funktionen auslagern, damit die Main-Loop klein bleibt. Dann musst du aber drauf achten, dass die Variablen, die in den Funktionen verwendet werden, erhalten bleiben. Das kannst du mit globalen Variablen machen - auch wenns nicht so elegant ist - oder mit "static" Variablen, die ihren Wert behalten, auch wenn die Funktion beendet wird und dann erneut aufgerufen wird (was du hier ja machen würdest).
Wenn du dir das hier anschaust, siehst du, dass das Programm immer nur einen der drei Blöcke überhaupt ausführt. Und den dann auch nur dann bis zum Ende, wenn die Bedingung in der zweiten Zeile auch noch zutrifft. Pro Schleifendurchlauf werden also oft nur vier If-Bedingungen geprüft. Bei drei Servos also nur insgesamt 12 pro Schleifendurchlauf. Die Schleife ist also recht schnell, weil da meist effektiv nichts passiert, außer Bedingungen zu prüfen, die nur ganz selten überahupt erfüllt sind. Das nennt man Superloop - eine schnelle Schleife, in der größtenteils nicht passiert außer zu prüfen, ob irgendeine Akton nötig ist - und die wird dann (aber eben NUR DANN) ausgeführt. Und Warten ist sozusagen auch eine solche Prüfung - eben daraufhin, ob die Zeit schon rum ist und die Aktion somit fällig ist.
Tüftel halt mal ein bisschen rum. Probieren geht über studieren und letztlich versteht man es erst, wenn man alles mal gemacht (und vor allem, alles mal falsch gemacht) hat.
Okay aber was hat es mit den millis auf sich? Das habe ich noch nicht ganz verstanden.
-
Wenn ich all die Antworten hier lese bin ich langsam überfordert was ich probieren soll
Weerde mal schauen was so geht
-
#include <Servo.h>
das ist das Einzige was ich anfangs geetan habe. Die gibt es in der Arduino Software vorgegeben die Library.
-
Code
Display More#include <Servo.h> Servo Blastgate1; Servo Blastgate2; Servo Blastgate3; int Tellerschleifer = 1; int Sauger = 2; int Kapp = 3; int Relais = 13; int var1 = 0; int var2 = 0; int var3 = 0; void setup() { Blastgate1.attach(8); Blastgate2.attach(9); Blastgate3.attach(10); pinMode(Tellerschleifer, INPUT); pinMode(Sauger, INPUT); pinMode(Kapp, INPUT); pinMode(Relais, OUTPUT); } void loop() { if (digitalRead(Tellerschleifer) == HIGH) { var1++; digitalWrite(Relais, HIGH); Blastgate1.write(90); } if (digitalRead(Sauger) == HIGH) { var2++; digitalWrite(Relais, HIGH); Blastgate2.write(90); } if (digitalRead(Kapp) == HIGH) { var3++; digitalWrite(Relais, HIGH); Blastgate3.write(90); } if ((digitalRead(Tellerschleifer) == LOW) && (var1 >= 1)) { var1 = 0; delay(2000); digitalWrite(Relais, LOW); Blastgate1.write(120); } if ((digitalRead(Sauger) == LOW) && (var2 >= 1)) { var2 = 0; delay(2000); digitalWrite(Relais, LOW); Blastgate2.write(120); } if ((digitalRead(Kapp) == LOW) && (var3 >= 1)) { var3 = 0; delay(2000); digitalWrite(Relais, LOW); Blastgate3.write(120); } }
-
Doch mache ich gerne nur wie lade ich das hoch?
-
Hey
danke erstmal für die zahlreichen Kommentare. Mit den Variablen habe ich versucht das Problem zu lösen, dass auch wenn ein Gerät ausgeschaltet aber zuvor auch nicht angeschaltet war die If Schleife für LOW trotzdem durchlaufen werden würde.
Mein Problem ist das der Servo nicht direkt angesteuert wird, sondern erst nach einer gewissen Zeit. Das er beim ausschalten verzögert ist klar. Durch die Variablen dürften sich die Zeiten auch nicht addieren.
Wäre für andere Lösungsansätze oder ein komplett anderes Programm offen. Die Funktion ist mittlerweile sicherlich bekannt: Nach Schalter High soll Servo angesteuert werden, nach LOW wieder nach 2 Sekunden zurückgesetzt. Das ganze mit drei verschiedenen Servos/Schaltern.
Danke schonmal!