wie schon aus meinem anderen Thread ersichtlich, bastele ich gerade an einer über ein Uno gesteuerte, pneumatische Kartschaltung.
Die Abfolge mit Setzen der benötigten Ausgänge wollte ich eigentlich über while-Schleifen realisieren.
Nun möchte ich aber gerne die Zeitdauer der Schleifen für den Fall mechanischer Störungen (Endlage wird nicht erreicht, also Schleifenabbruch, wenn vorgang zu lange dauert) begrenzen und dann wieder in eine sichere Ausgangslage (Mittelstellung des Pneumatikzylinders) zurückfahren.
Hier erstmal mein Code:
time=millis();
while (AS_unten == LOW && time<safetime) {
digitalWrite(Sp_runter, HIGH); // Pneumatikzylinder Runterschalten aktivieren
digitalWrite(Sp_hoch, LOW); // Pneumatikzylinder Hochschalten deaktivieren
digitalWrite(ZUE, HIGH); // Zündunterbrechung weiter aktiv
}
while (AS_mitte_unten == LOW) {
digitalWrite(Sp_runter, LOW); // Pneumtakikzylinder Runterfahren wieder deaktivieren
digitalWrite(Sp_hoch, HIGH); // Pneumtakikzylinder wieder Hochfahren in Mittelstellung aktivieren
digitalWrite(ZUE, LOW);
}
3 Fragen hätte ich dazu:
Kann die Zeitdauer für den Vorgang auch noch ausgelesen werden, während der Controller in bereits in der While Schleife "festhängt"? Die Schleife als bei Überschreiten der vorgebenen Zeitdauer verlassen werden?
Funktioniert das Auslesen der Bedingung für die While-schleife (Eingang == LOW) überhaupt ohne den digitalread-Befehl?
Arbeitet das Programm wie in meiner Abfolge vorgesehen die verschiedenen While-Schleifen nacheinander ab und überspringt nicht, wenn die Bedingung für die 2. While-Schleife bereits erfüllt ist, "versehentlich" die erste Schleife?
Sry, für meine wahrscheinlich blöden fragen, aber bin eigentlich kein Programmierer und noch Arduino-Einsteiger.
Wenn ihr eine bessere Variante für meine Ablaufsteuerung als die while-Schleifen habt, dann bitte immer her damit. Die prinzipiellen Abläufe sind folgendermaßen: Schalten bis Endlage erreicht ist, dann Umschalten bis neue Endlage erreicht ist.
Wie immer vielen Dank für eure Hilfe im Voraus und
Freundliche Grüße
Marius
eine while Schleife wird solange durchlaufen, solange ihre Eintrittsbedingung wahr ist. Das mußte verinnerlichen.
Das bedeutet, wenn Du die Variable safetime mit zur Bedingung machst, mußt Du diese auch in der Schleife aktualisieren, sonst nützt sie dir nicht zum Notausstieg während der Schleife. Denn die Gültigkeit von safetime würde sich für die while Schleife sonst nie mehr ändern. Ohne durchdachte Prüfung in while besteht die Gefahr zur Endlosschleife.
ja so meinte ich das. Ich war zu sehr in while verguckt.
Wenn Du aber nur auf
AS_unten == LOW
wartest, dann kannst Du das bestimmt in einer if Abfrage erledigen.
Etwas anderes wäre es, Du erweiterst while mit der Abfrage der Position Deiner Zylinder. Und Du mußt warten bis sie in Position sind und gleichzeitig gibts Du eine maximale Zeit vor in der das erfolgen muß. Dann macht while wieder Sinn, wenn Du die eine Aktion startest, wartest bis das erledigt ist und dann erst weiter machen möchtest.
Ja.
Eine Schleife mit Seitenausstiegen ist aber sehr unschön.
Das riecht schon etwas wie ein GOTO, oder mehreren Return in einer Funktion.
Und ist hier ganz und gar unnötig.
(aus meiner bescheidenen Sicht auf die Dinge)
Wenn ihr eine bessere Variante für meine Ablaufsteuerung als die while-Schleifen habt, dann bitte immer her damit.
Bedingungen, soweit ich sie verstanden habe:
Zündung wird während der Schaltvorgänge abgeschaltet.
Schaltung bleibt für eine Mindestzeit in Ruhestellung
Schaltvorgänge werden nach einer Zeit ober bei erreichen des Endschalters abgebrochen
Schalthebelrückstellung erfolgt per Federkraft
Das Programm könnte so aus sehen, wenn ich es schreiben wollte/müsste:
const bool on = true;
const bool off = false;
const int upschalter = 2;
const int downschalter = 3;
const int upzylinder = 4;
const int downzylinder = 5;
const int upendschalter = 6;
const int downendschalter = 7;
const int ignition = 8;
const unsigned long schaltzeit = 100; // zeit für Schaltvorgang
const unsigned long ruekstellzeit = 300; // zeit für schalthebelrückstellung
unsigned long lastHit; // Zeitstempel
typedef enum SchaltStatus{S_Start,S_Ruhestellung,S_GoUp,S_GoDown};
SchaltStatus schaltstatus = S_Start;
void handleSchaltAutomat()
{
switch(schaltstatus)
{
case S_Start : digitalWrite(upzylinder,off);
digitalWrite(downzylinder,off);
digitalWrite(ignition,on);
schaltstatus = S_Ruhestellung;
lastHit = millis();
break;
case S_Ruhestellung : if(millis()-lastHit > ruekstellzeit) // warte auf Rückstellzeit
{
if(digitalRead(upschalter))
{
digitalWrite(upzylinder,on);
// digitalWrite(downzylinder,off);
digitalWrite(ignition,off);
lastHit = millis();
schaltstatus = S_GoUp;
}else if(digitalRead(downschalter))
{
// digitalWrite(upzylinder,off);
digitalWrite(downzylinder,on);
digitalWrite(ignition,off);
lastHit = millis();
schaltstatus = S_GoDown;
}
}
break;
case S_GoUp : if(digitalRead(upendschalter)|| (millis()-lastHit > schaltzeit))
{
schaltstatus = S_Start;
}
break;
case S_GoDown: if(digitalRead(downendschalter)|| (millis()-lastHit > schaltzeit))
{
schaltstatus = S_Start;
}
break;
}
}
void setup()
{
pinMode(upschalter,INPUT);
pinMode(downschalter,INPUT);
pinMode(upzylinder,OUTPUT);
pinMode(downzylinder,OUTPUT);
pinMode(upendschalter,INPUT);
pinMode(downendschalter,INPUT);
pinMode(ignition,OUTPUT);
}
void loop()
{
handleSchaltAutomat();
}
ungetestet und vermutlich sowieso noch unvollständig
Wie man sieht, geht das ganze auch ohne While().
while ist kompakter, rein vom leserlichen her. Dafür hat alles ohne while, wie Du schön gezeigt hast, den großen Vorteil, dass der Code nicht blockiert. Er kann also noch währenddessen auf andere zusätzliche Ereignisse reagieren. Zum Bsp. einen Not-Aus.
Doc_Arduino:
Hallo,
jetzt hast Du auch mehrere break's drin.
Ich sachte ja auch:
Eine Schleife mit Seitenausstiegen ist aber sehr unschön.
Und ich vermute mal, dass switch() jetzt nicht gerade als Schleife durch geht.
Es geht auch ohne switch().
z.B. mit einer Tabelle/Array mit Funktionspointern
Oder mit Funktionspointern, ohne Array.
Oder mit einem großen IF Geschlingel, dann würde sogar goto wieder Sinn machen. Aber schön wird das nicht....
Dafür hat alles ohne while, wie Du schön gezeigt hast, den großen Vorteil, dass der Code nicht blockiert. Er kann also noch währenddessen auf andere zusätzliche Ereignisse reagieren.
vielen Dank für eure Anregungen. Werde mich demnächst, wenn wieder Zeit ist, genauer mit allen möglichkeiten befassen.
@ combie:
Punkt 4 deiner Annahme ist falsch: Die Schalthebelrückstellung erfolgt NICHT durch Federkraft, sondern durch komplettes Umschalten eines 5/3-Wege-Ventils, welches zur Richtungsumkehr des doppeltwirkenden Pneumatikzylinders führt. Gehalten (in Mittelstellung) wird der Zylinder dadurch, dass einfach keine Spule des Wege-Ventils bestromt wird (beide Ventilstränge sind gesperrt). So kann der Zylinder theoretisch in jeder beliebigen Stellung gehalten werden.
In der Mittelstellung gibt es 2 Positionssensoren (einer der Schaltet, wenn der Zylinder die Mittelstellung von unten erreicht, einer bei Erreichen der Mittelstellung aus der oberen Endlage. Anders war das nicht machbar, da Reedschalter ja leider keinen definierten Schaltpunkt sondern einen Schaltbereich haben. Für die Endlagen ja kein Problem, nur die Mittelstellung lässt sich damit leider nicht exakt erfassen. Deshalb dieser etwas umständliche Weg der Auswertung.
Du möchtest Dir also eine Art Automatikgetriebe ins Kart bauen? So ein Go-Kart oder was ist das? Macht das Zusatzgewicht denn nicht alles wieder zu Nichte? Oder ist das nur zum Spass ob's funktioniert?
SchaltRinge am Lenkrad sind schon typisch.
Aber per Seilzug Kraft aufwändig und recht zäh zu bedienen.
Und das Problem der Schubabschaltung, beim schalten, ist damit auch noch nicht erledigt.
Zumindest beim hochschalten kann man damit problemlos auf die Kupplung verzichten.
ja ist nur zum spaß und freude am basteln, obs funktioniert. Es gibt ein kommerzielles System dazu, kostet aber um die 1000€, was den wert meines karts übersteigt.
@ all: ist vom prinzip her ein motorradmotor, aber eben speziell für kartsport. Die kupplung wird hier standardmäßig eh nur zum anfahren genutzt. Hochgeschaltet wird im Normalfall mit gas kurz lupfen (Fuß vom Gas), beim runterschalten ist man eh auf der bremse und gibt kein gas, erfolgt also auch ohne kupplung. Normalerweise alles manuell mit einem schaltknüppel.
Das gas lupfen beim hochschalten will ich mir halt durch zündunterbrechung sparen, so wirds beim kommerziellen system auch gemacht. So kann man sich das gas lupfen sparen, was vielleicht ne zehntel sekunde und jede menge rennsportfeeling bringt.
runterschalten könnte wie schon beschrieben auch ohne zündunterbrechung ohne kupplung erfolgen, da man da eh vom gas runter ist.
automatisches schalten wär ein projekt für nexten winter (drehzahlerfassung über arduino fehlt dazu noch), ist aber eher spielerei und gehört eigentlich nicht zum schaltkart fahren. Dann kann man auch gleich auf einen getriebelosen motor zurückgreifen.
Thema Druckminderer: aus der HP-Paintballflasche gehts bis der fülldruck soweit abgesunken ist mit max 58bar in den vordruckminderer. Dieser druckminderer kommt aus ner einweg-schweißgasflasche (inertgas, z.B. Argon) welcher max. 120bar vordruck kann und dann auf die für den pneumatikzylinder benötigten max. 6 bar ausgangsdruck reduziert zum einsatz. Das "mechanische" System ist auch schon soweit getestet und funktioniert einwandfrei.
Fehlt halt nur noch die Steuerung dazu...
ich finde das echt cool. Die Autoindustrie nennt sowas "drive by wire".
Nur solltest wissen, dass es wirklich nur ein Spass Projekt sein wird. Denn auf einer Rennstrecke dürfest du mit einer Gasflasche am Kart nie fahren. Wegen "zum Geschoß werden ...". Ich denke jedoch Du weist was Du machst, deshalb bin ich mal gespannt was daraus wird ...