IF/ELSE in Setup?

Hallo,

ich möchte einen Motor so lange drehen lassen, bis ein Endstop erreicht wird und dann eine Variable setzen.

Das soll nur 1x nach dem einschalten passieren, aber da SETUP nur einmal durchläuft funktioniert das so nicht:

if (digitalRead(EndstopA)==HIGH) { stepper.move(20000); } else { stepper.stop(); }

Wenn der Eingang vor dem einschalten Low ist, dreht sich nichts. Wenn er High ist, dreht sich der Motor 20000 Steps.

Wenn aber während dem drehen der Eingang Low wird, dreht der Motor trotzdem weiter.

Logisch, Setup läuft nur 1x durch....

Aber wie löst man das? Am besten so simpel wie möglich!

Danke

Ich gehe mal davon aus, dass der Motor auch sonst angesteuert wird. Aber im Fall des Starts nur eine bestimmte Position anfahren soll...

Man könnte es z.b. so lösen, dass du eine Variable definierst, der du z.b. "1" zuweist. In der loop() rufts du mit if /Variable == 1) eine Funktion für den Start auf. In dieser Funktion setzt du deine Aufgabe für den Motor um- und wenn er in die gewünschte Position gefahren ist, setzt du Variable = 0;. Wenn du diese Variable dann im ganzen Programm nicht mehr anfaßt, ist auch nie wieder die Bedingung für deine Startfunktion erfüllt. Erst beim Neustart ist die Variable wieder auf "1" gesetzt und deine Startbedingung erfüllt.

(aber du kannst diese Startfunktion alternativ auch im Setup aufrufen)

Ja der Motor wird sonst im Loop gesteuert und läuft abhängig von externen Signalen endlos.

Mir war nur nicht klar, was der einfachste Weg für eine Referenzfahrt ist.

Deine Idee lass ich mir mal durch den Kopf gehen, danke schon mal für den Vorschlag.

Prinzipiell lagerst du diese Aufgabe einfach in einer eigenen Funktion aus... dann ist es auch leichter zu spielen und zu probieren von wo aus man diese Funktion aufruft und an welche Bednigungen es geknüpft ist...

Bender2k: Wenn der Eingang vor dem einschalten Low ist, dreht sich nichts. Wenn er High ist, dreht sich der Motor 20000 Steps.

Wenn aber während dem drehen der Eingang Low wird, dreht der Motor trotzdem weiter.

Das macht er in jedem Fall, da du die Anweisung "stepper.move(20000);" gegeben hast. Das kannst du so erst mal nicht stoppen. Es sei denn, deine verwendete Hardware hat einen speziellen Eingan dafür.

Edit:

Ok, evtl. liege ich hier auch falsch, wenn er mit "stepper.stop" zu stoppen ist.

Okay verstehe, dann hilft die Variable auch nichts.

Wie kann ich den Stepper dann anhalten, wenn ein Eingang kommt? (Einfach verständlich) Ich kenne mich noch nicht gut aus aus und habe bisher nur die AccelStepper Libary verwendet.

Bender2k:
Wenn der Eingang vor dem einschalten Low ist, dreht sich nichts. Wenn er High ist, dreht sich der Motor 20000 Steps.

Wenn aber während dem drehen der Eingang Low wird, dreht der Motor trotzdem weiter.

Dann mach doch ne while-Shleife und innerhalb der Schleife immer nur wenige Schritte, bis der Eingang nicht mehr HIGH ist,

void setup()
{

   while (digitalRead(EndstopA)==HIGH)
  {
    stepper.move(20);
  }
   stepper.stop();
}

Ich bin mir nicht ganz sicher - aber ich denke wenn du auch den Eingang im Setup schon abfragst kann man einen Stopp darüber realisieren...

Aber so oder so- in einer separaten Funktion- mit der Abfrage des Eingangs und/oder anderer relevanter Größen ist es aus meiner Sicht besser aufgehoben. Dann hast du auch die Möglichkeit- falls erforderlich - auch im laufenden Programm die Funktion mal aufzurufen- z.b. mit einer Taste oder bei bestimmten Ereignissen.

Ich habe es jetzt so gelöst:

int REFPOS = 0;

void loop() {

if ((REFPOS==0) && (digitalRead(EndstopA)==HIGH)) { stepper.move(5); } else { REFPOS=1; //Komplette Motor-Code/AccelStepper Befehle abhängig von externen Eingängen }

}

Ich mache das erst seit ein paar Tage und das ist wahrscheinlich größer Pfusch (Vor allem wegen dem ganzen Code im "else"), aber es läuft. Abgesehen davon, dass der Motor in der if-Schleife mit den 5 Steps sehr langsam und ruckelig läuft. Zum einmaligen EndStop suchen sollte es reichen.

Danke für die Ideen.

Bender2k: Mir war nur nicht klar, was der einfachste Weg für eine Referenzfahrt ist.

Mit einer Refernzfahrt habe ich das System noch nicht angewendet, aber mit anderen Dingen:

Ich würde mir eine Bool-Variable erstellen, die aussagt, ob die Referenzfahrt schon durchgeführt wurde. Diese wird im Setup auf false gesetzt. Loop muss dann "nur noch" die Variable auswerten und entsprechend reagieren. Wurde die Refernzfahrt durchgeführt, geht die Variable auf true. Wird für die Refernzfahrt mehrere loop-Schleifendurchläufe gebraucht, müsstest du dir evtl. auch eine Hilfsvariable setzen, dass die Refernzfahrt gerade im Gang ist. Das kommt aber auf deine Programmierung an.

Hätte zudem den Vorteil, dass du, sollte dir mal der Stepper davonlaufen, auch mal mittendrin eine Refernzfahrt machen kannst, in denn du die Variable wieder auf false setzt.

(Vor allem wegen dem ganzen Code im "else")

Du könntest das ganze, wenn du das schöner findest auch umdrehen:

if ((!REFPOS) && (!digitalRead(EndstopA)))
{
   //normaler Programmablauf
}
else
{
   //Refernzfahrt
}

Erklärung: Bool müssen in einer if Abfrage nicht auf true abgefragt werden, da sie schon true/false sein können (If interessiert sich nur für das Gesamtergebnis des Terms). Mit "!" wird das ganze inventiert.

Normalerweise müsste auch !((REFPOS) && (digitalRead(EndstopA))) klappen. Probiers einfach mal.

Ich habe mit programmieren bisher nichts am Hut, vielleicht sollte ich doch mit den Basics anfangen :slight_smile:

Vermutlich wäre es sauberer mit einer Funktion, da muss ich mich mal einlesen wie man so eine Funktion schreibt und aufruft.

Dass ich mit meinem Code nie wieder die IF-Bedingungen erfüllen kann macht nichts. (Ausser mit einem INPUT der REFPOS wieder auf 0 setzt)
Wenn ich neu Referenzieren will drücke ich einfach den Reset am Board.

Im Moment bin ich mit meiner Lösung zufrieden.
Die Beiträge hier haben mir geholfen drauf zu kommen, DANKE!

Das ist schon mal ein guter Angang. Leider allzu selten, dass sich Neulinge selbst auferlegen, die Basics zu lernen. Dafür gibt es ein Karma.

Und das mit den Funktionen ist nicht schwer.

Z.B.

// alle Definitionen

void Setup() 
{

// alle Setupeinträge

}

// deine Funktion

void meineFunktion()
{

// alle Anweisungen die hier ausgeführt werden müssen

}


void Loop()
{

// alle Anweisungen die in der Loop ausgeführt werden müssen und
// Aufruf der Funktion(en)

meineFunktion();

}

So könnte das mit den Funktionen aussehen. Beispielcode ! Variable, die du in der Loop und auch in der Funktion benutzen willst, sollten global (also ganz oben) definiert werden.