ich verstehs nich -> zeitverhalten accel stepper

hallo,

was ich machen möchte: einen schrittmotor pro gewählter zeiteinheit einen schritt verfahren.

dabei habe folgendes verständnis problem; hier der lauffähige minimal sketch:

#include <AccelStepper.h>

boolean start = true;
AccelStepper stepper(1, 2, 3);

void setup() {
  Serial.begin(9600);
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  if (start == true) {
    for (int i = 0; i < 10; i++)
    {
      stepper.move(1);
      stepper.run();
    }
    Serial.println(stepper.currentPosition());
  }
  start = false;
}

was ich erwarten würde: der schrittmotor verfährt 10x1 schritt; demnach ist die ausgabe (currentPosition) 10.
ergebnis: ausgabe (currentPosition) ist 0.

wenn ich eine unterbrechung einfüge…

void loop() {
  if (start == true) {
    for (int i = 0; i < 10; i++)
    {
      stepper.move(1);
      stepper.run();
      delay(100);
    }
    Serial.println(stepper.currentPosition());
  }
  start = false;
}

ergebnis: ausgabe (currentPosition) ist 9.

fragen:

  1. warum gibt currentPosition() ohne delay() 0 zurück?
  2. warum gibt currentPosition() mit delay(100) etwas > 0 zurück?
  3. warum gibt currentPosition() mit delay(100) genau 9 zurück?

letztlich habe ich mit der unterbrechungszeit gespielt:
delay(1) → currentPosition() ist 0
delay(>11) → currentPosition() ist 1
delay(>24) → currentPosition() ist 2
usw.

  1. warum haben o.g. unterbrechungen unterschiedlichen einfluss auf die currentPosition()?

vielen lieben dank im voraus.

gruß

ffm65

ffm65:
was ich erwarten würde: der schrittmotor verfährt 10x1 schritt; demnach ist die ausgabe (currentPosition) 10.
ergebnis: ausgabe (currentPosition) ist 0.

Ich würde PIN1 nicht verwenden.
agmue hat recht

Moin, versuch mal folgendes:

#include <AccelStepper.h>
boolean start = true;
AccelStepper stepper(1, 2, 3);

void setup() {
  Serial.begin(9600);
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  if (start == true) {
    for (int i = 0; i < 10; i++)
    {
      stepper.move(1);
      stepper.run();
    }
  }
  start = false;
  bool laeuft = stepper.run();
  if (laeuft == false)
  {
    stepper.disableOutputs();
    Serial.println(stepper.currentPosition());
  }
}

my_xy_projekt:
Ich würde PIN1 nicht verwenden.

Falsch, das ist der Treibertyp (siehe AccelStepper.h):

DRIVER = 1, ///< Stepper Driver, 2 driver pins required

Daher ist stepper(1, 2, 3) schon richtig. Deutlicher wird es so:

#define DIR_PIN 3
#define STEP_PIN 2 
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

agmue:
Deutlicher wird es so:

Stimmt.

Ich denke, Du hast die Funktion der AccelStepper noch nicht verstanden.
Die Aufrufe der AccelStepper sind nicht blockierend, d.h. z.B. run() wartet nicht, bis ein Step ausgeführt werden muss. run() muss ständig, immer wieder aufgerufen werden, und entscheidet dann selbst, ob jetzt ein Step ausgeführt werden muss oder nicht.
Du gibst der accelStepper gar keine Chance einen Step auszuführen. Deine for-Schleife läuft mit voller Prozesossorgeschwindigkeit durch - da macht run() erstmal gar nichts, denn so schnell dürfen die Steps nicht ausgegeben werden. Und dann rufst Du run gar nicht mehr auf - also gibt es auch keine Steps.
Und da es keine Steps gibt, funktioniert auch das move(1); nicht - denn es bedeutet nicht ‘mach einen Step’ sondern ‘mach einen Step von der momentanen Position aus’. Da sich die momentane Position aber gar nicht ändert ( deine for-Schleife ist ja zu schnell ) machen deine ganzen move(1); nur insgesamt einen Step - das addiert sich nicht.
Durch deine delays() kann dann doch ab und zu ein Step ausgeführt werden, weshalb sich da dann etwas addiert. Wieviel das ist, hängt vom delay und der eingestellten Stepgeschwindigkeit ab, und ist eher Zufall.

Fazit: So wie Du da rangehst, funktioniert es prinzipiell nicht.

Eine möglich Variante zum Testen:

#include <AccelStepper.h>

boolean start = true;
#define DIR_PIN 3
#define STEP_PIN 2
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
  Serial.begin(115200);     //<<--- !!!!! Baudrate im seriellen Monitor anpassen !!!!!
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  stepper.run();      // im loop ständig aufrufen, entscheidet dann slebst, wann ein Schritt fällig ist.
  if ( stepper.distanceToGo() == 0 ) {
    // Wenn das Ziel erreicht ist, die erreichte Position ausgeben
    Serial.println(stepper.currentPosition());
    start = true;       // die nächsten 100 Schritte ausführen
  }
  if (start == true) {
    stepper.move(100);    // in 100er Schritten vorwärts, sonst wird's zu schnell für die Ausgaben
  }
  start = false;
}

@my_xy_projekt: Die Pin-Zurdnung ist schon in Ordnung. Der erste Parameter beim AccelStepper ist keine Pinnummer, sondern die Kennung für den Modus ( 1=Step/Dir Driver ).
Edit:OK, agmue war schneller :wink: Hab’s auch noch nach seinem Vorschlag angepasst, das ist auf jeden Fall die bessere Variante, an der man erkennt was Sache ist.

Nochmal Edit: Wenn man mit der AccelStepper arbeitet, sollte man delay() grundsätzlich vermeiden und blockadefrei programmieren.
P.S. hab’ noch ein paar Kommentare eingefügt

Hier noch die Kurz-Variante :wink: , denn das ‘start’ braucht man eigentlich nicht:

#include <AccelStepper.h>
#define DIR_PIN 3
#define STEP_PIN 2
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
  Serial.begin(115200);     //<<--- !!!!! Baudrate im seriellen Monitor anpassen !!!!!
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  stepper.run();      // im loop ständig aufrufen, entscheidet dann slebst, wann ein Schritt fällig ist.
  if ( stepper.distanceToGo() == 0 ) {
    // Wenn das Ziel erreicht ist, die erreichte Position ausgeben
    Serial.println(stepper.currentPosition());
    stepper.move(100);    // in 100er Schritten vorwärts, sonst wird's zu schnell für die Ausgaben
  }
}

Hallo,
@Franz-Peter was der T0 eigendlich wollte, 10 x in bestimmten Zeitabständen je einen Schritt verfahren. Und dann die absolute Position ausgeben.

Gruß Heinz

Hallo Heinz,

Rentner:
10 x in bestimmten Zeitabständen je einen Schritt verfahren.

Dann hätte ich das falsch verstanden. Aber von den 'bestimmtem Zeitabständen' habe ich nichts gesehen. Die delay() hat er ja erst eingefügt, wie das in der ersten Variante nicht funktioniert hat.

So wie ich das verstanden habe, wollte er die AccelStepper ausprobieren, hat aber die Funktion noch nicht richtig verstanden, weshalb er das falsch eingesetzt hat.
Aber warten wir halt ab, bis er sich meldet.

MicroBahner:
Hallo Heinz,Dann hätte ich das falsch verstanden. Aber von den ‘bestimmtem Zeitabständen’ habe ich nichts gesehen. Die delay() hat er ja erst eingefügt, wie das in der ersten Variante nicht funktioniert hat.

So wie ich das verstanden habe, wollte er die AccelStepper ausprobieren, hat aber die Funktion noch nicht richtig verstanden, weshalb er das falsch eingesetzt hat.
Aber warten wir halt ab, bis er sich meldet.

Hallo,

ich glaube auch nicht das er das wirlich wollte, es sei denn er will einen Uhrzeiger bauen, ansonsten macht sowas ja wenig Sinn. Mal sehen was er antworte. :wink:

Gruß Heinz

Rentner:
ich glaube auch nicht das er das wirlich wollte, es sei denn er will einen Uhrzeiger bauen, ansonsten macht sowas ja wenig Sinn.

Naja, ich hab auch das eine oder andere mal mit ausprobiert, was möglich ist und bin auch an/auf Grenzen gestossen, die sich mir nicht auf den ersten Blick erschlossen.
Manchmal sind es eben reine timingfragen…

Wenn der TO das mit dem Timing und den Ausgaben sehen will:

#include <AccelStepper.h>
boolean start = true;
AccelStepper stepper(1, 2, 3);

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  bool laeuft = stepper.run();
  if (start && !laeuft) {
    stepper.move(1);
  }
  if (stepper.currentPosition() == 9) {
    start = false;
    stepper.disableOutputs();
  }
  Serial.println(stepper.currentPosition());
  if (start == false) while (1);
}

Der code bleibt dann endlos stehen, wenn die 9 ausgegeben wurde.
Im Seriellen Monitor den Zeitstempel mit aktivieren reicht schon.

hallo,

zunächst möchte ich mich für die in so kurzer zeit eingegangenen hilfreichen beiträge bedanken!

my_xy_projekt:
Ich würde PIN1 nicht verwenden.
agmue hat recht

ihr seid alle schneller gewesen als ich. und ja, dass

ffm65:
AccelStepper stepper(1, 2, 3);

ist’n schlechter stil und nicht eindeutig; danke agmue für den hinweis.

@my_xy_project:
(sketch 01.03 05:11) was war denn deine erwartung was letztendlich bei der ausgabe heraus kommt (bei mir 1)? ich verstehe den ansatz von 2x run() nicht.

MicroBahner:
Ich denke, Du hast die Funktion der AccelStepper noch nicht verstanden.

das hast du vollkommen richtig erkannt ;). dank deiner ausführungen ist es mir jetzt zumindest klarer, wenn auch noch fragen offen bleiben. ich bin davon ausgegangen, wenn die currentPosition() des motors 0 ist und ich

move(1)

befehlige, dass dann laut

run() “Poll the motor and step it if a step is due, …”

ein schritt due, fällig ,ist. du schreibst, so schnell dürfen schritte nicht ausgegeben werden → wie schnell dürfen denn schritte ausgegeben werden bzw. welche zeit zwischen zwei move() befehlen muss mindestens vorhanden sein damit er mit dem run() zurecht kommt?

am sketch (01.03. 11:05) von my_xy_project - welcher das ganz gut umsetzt was ich eigentlich mit meinem minimalbeispiel vor hatte, nämlich wirklich am ende der 10 schritte zu wissen wo steh ich - habe ich auch schon wieder ein verständnisproblem mit der bibliothek.

void loop() {
  bool laeuft = stepper.run();
  if (start && !laeuft) {
    stepper.move(1);
  }
  if (stepper.currentPosition() == 10) {
    start = false;
    stepper.disableOutputs();
    Serial.println(stepper.currentPosition());
  }
  if (start == false) while (1);
}

ich hab die ausgabe nur in die if geschoben. warum dauert es so lange (~2sec) bis die ausgabe 10 da ist; bei currentPositon() == 100 (~10 sec)? ein motor müsste doch die 10 schritte im <ms bereich gefahren sein.

ffm65:
der motor müsste doch die 10 schritte im <ms bereich gefahren sein.

Wie kommst Du da drauf? Du hast eine Steprate von 1000Steps/Sec eingestellt. Das wäre 1 Step/ms. Und aufgrund der Beschleunigungsfunktion sind die ersten Steps auch noch deutlich langsamer.

ffm65:
@my_xy_project:
(sketch 01.03 05:11) was war denn deine erwartung was letztendlich bei der ausgabe heraus kommt (bei mir 1)? ich verstehe den ansatz von 2x run() nicht.

Ich bin (fälschlicherweise) noch davon ausgegangen, das die lib intern jeden Schritt hochaddiert und selbst nachschaut, ob der Schritt erfolgt ist.
Das macht sie nicht - war mir nicht bekannt.

Hintergrund des Codeansatz war,
a) im for dafür zu sorgen, das sich der der Stepper bewegt (run)
b) als auch im loop() das was dann noch fehlt aufzuholen.
Da das auf einer falschen Einschätzung beruht, ist das Makulatur - also vergiss es schnell. Du wolltest aber eine Erklärung :wink:

das hast du vollkommen richtig erkannt ;). dank deiner ausführungen ist es mir jetzt zumindest klarer, wenn auch noch fragen offen bleiben. ich bin davon ausgegangen, wenn die currentPosition() des motors 0 ist und ich
move(1)
befehlige, dass dann laut
run() “Poll the motor and step it if a step is due, …”
ein schritt due, fällig ,ist.

Ja. Das ist auch so.
ABER: Bedenke, das Du selbst die Zeiten festlegst, mit der sich das Teil in Beqwegung setzt etc. Je kleiner die Zeiten, desto genauer ist der. Sind Deine Zeiten zu hoch, schiesst Du evtl. übers Ziel hinaus und “übersieht” einen Step, weil weiter gedreht als soll.

du schreibst, so schnell dürfen schritte nicht ausgegeben werden → wie schnell dürfen denn schritte ausgegeben werden bzw. welche zeit zwischen zwei move() befehlen muss mindestens vorhanden sein damit er mit dem run() zurecht kommt?

Das ist die Frage!
Die Antwort liegt in der Anzahl der Steps und der Zeit die dafür benötigt wird.

am sketch (01.03. 11:05) von my_xy_project - welcher das ganz gut umsetzt was ich eigentlich mit meinem minimalbeispiel vor hatte, nämlich d.h. wirklich am ende der 10 schritte zu wissen wo steh ich - habe ich auch schon wieder ein verständnisproblem mit der bibliothek.

ich hab die ausgabe nur in die if geschoben. warum dauert es so lange (~2sec) bis die ausgabe 10 da ist; bei currentPositon() == 100 (~10 sec)? der motor müsste doch die 10 schritte im <ms bereich gefahren sein.

Ich versuch das mal unorthodox:

Mache Tür auf - schmeiss einen Holzscheit rein - Mache Tür zu - Fange an vorn Vorn bis 10 Scheite drin sind
ist was anderes als:
Mache Tür auf - schmeisse 10 Holzscheit rein - Mache Tür zu.

[Microbahner hat “Tür auf” und “Tür zu” schön erklärt :wink: ]

danke euch nochma für die schnelle rückmeldung

my_xy_projekt:
Mache Tür auf - schmeiss einen Holzscheit rein - Mache Tür zu - Fange an vorn Vorn bis 10 Scheite drin sind
ist was anderes als:
Mache Tür auf - schmeisse 10 Holzscheit rein - Mache Tür zu.

[Microbahner hat “Tür auf” und “Tür zu” schön erklärt :wink: ]

das hatte ich eigentlich gedacht schon vorher verstanden zu haben ;). ich glaub bei mir liegt da noch ein grundlagen problem bzgl. der ansteuerung von schrittmotoren vor…

der move() befehl lässt den motor doch in einer rampenfunktion bezogen auf die geschwindigkeit in die neue position verfahren. dazu brauch er ne zeit um auf die geschwindigkeit (1000 schritte/sec) zu beschleunigen und ne zeit um wieder auf 0 geschwindigkeit abzubremsen.

deshalb ist mir schon klar, das move(10) schneller abgearbeitet ist als 10x move(1). da er ja nur einmal positiv beschleunigen und abbremsen muss als das ganze 10x zu machen.

MicroBahner:
Wie kommst Du da drauf? Du hast eine Steprate von 1000Steps/Sec eingestellt. Das wäre 1 Step/ms. Und aufgrund der Beschleunigungsfunktion sind die ersten Steps auch noch deutlich langsamer.

<ms war ein wenig zu optimistisch.
nehmen wir an, in dem beispiel wäre die beschleunigung 1000 schritte/sec^2. nach 1sec hätten wir also die geschwindigkeit von 1000 schritte/sec erreicht. würde dann 1 schritt 2,01sec benötigen; is das so oder hab ich da nen knick in der optik?

gedankenexperiment: positive und negative beschleunigung ist unendlich; geschwindigkeit 1000 schritte/sec. dann wären die 10 schritte aber in 10ms durch, oder?

btw wie verhält sich das denn mit dem runSpeed() befehl? der müsste ja die 10ms bei 10xmove(1) einhalten? bei dem ist ja die geschwindigkeit konstant, also sind keine beschleunigungsphasen dabei. dann bekomme ich aber mit einer hohen geschwindigkeit evtl. probleme mit schrittverlusten (die bib schreibt ja >1000schritte/sec ist unzuverlässig)?

ffm65:
nehmen wir an, in dem beispiel wäre die beschleunigung 1000 schritte/sec^2. nach 1sec hätten wir also die geschwindigkeit von 1000 schritte/sec erreicht. würde dann 1 schritt 2,01sec benötigen; is das so oder hab ich da nen knick in der optik?

Keine Ahnung.
Ausprobieren? Annähernd damit:

#include <AccelStepper.h>
boolean start = true;
AccelStepper stepper(1, 2, 3);

void setup() {
  Serial.begin(115200);
  Serial.println(F("Start...."));
  stepper.setMaxSpeed(1000); //steps / second
  stepper.setAcceleration(1000); //steps /(second)^2
}

void loop() {
  unsigned int i = 0;
  while (stepper.run()); // das Ding muss false sein
  unsigned int lastpos = stepper.currentPosition();
  unsigned long startmillis = millis();
  stepper.move(1);
  while (stepper.run()); // das Ding muss erneut false werden
  unsigned long endmillis = millis();
  unsigned int aktualpos = stepper.currentPosition();
  Serial.print(F("Nach einem Schritt: "));
  Serial.println(endmillis - startmillis);
  Serial.print(F("Letzte Position / aktuelle Position: "));
  Serial.print(lastpos); Serial.print("\t"); Serial.println(aktualpos);
  Serial.println(F("Mit 10 Einzel-Schritten...."));
  i = 0;
  while (stepper.run()); // das Ding muss false sein
  lastpos = stepper.currentPosition();
  startmillis = millis();
  while (i < 10)
  {
    stepper.move(1);
    while (stepper.run()); // das Ding muss erneut false werden
    i++;
  }
  endmillis = millis();
  aktualpos = stepper.currentPosition();
  Serial.print(F("Nach 10 Einzelschritten: "));
  Serial.println(endmillis - startmillis);
  Serial.print(F("Letzte Position / aktuelle Position: "));
  Serial.print(lastpos); Serial.print("\t"); Serial.println(aktualpos);
  Serial.println(F("Mit 10 Schritten am Stück...."));
  while (stepper.run()); // das Ding muss false sein
  lastpos = stepper.currentPosition();
  startmillis = millis();
  stepper.move(10);
  while (stepper.run()); // das Ding muss erneut false werden
  endmillis = millis();
  aktualpos = stepper.currentPosition();
  Serial.print(F("Nach 10 Schritten am Stück: "));
  Serial.println(endmillis - startmillis);
  Serial.print(F("Letzte Position / aktuelle Position: "));
  Serial.print(lastpos); Serial.print("\t"); Serial.println(aktualpos);
  while (1);
}

MEINE Ausgabe:

21:23:31.985 -> Start....
21:23:32.039 -> Nach einem Schritt: 29
21:23:32.039 -> Letzte Position / aktuelle Position: 0	1
21:23:32.039 -> Mit 10 Einzel-Schritten....
21:23:32.317 -> Nach 10 Einzelschritten: 299
21:23:32.317 -> Letzte Position / aktuelle Position: 1	11
21:23:32.317 -> Mit 10 Schritten am Stück....
21:23:32.451 -> Nach 10 Schritten am Stück: 146
21:23:32.451 -> Letzte Position / aktuelle Position: 11	21

Die Angaben der Zeit sind in ms

my_xy_projekt:
Bedenke, das Du selbst die Zeiten festlegst, mit der sich das Teil in Beqwegung setzt etc. Je kleiner die Zeiten, desto genauer ist der. Sind Deine Zeiten zu hoch, schiesst Du evtl. übers Ziel hinaus und "übersieht" einen Step, weil weiter gedreht als soll.

Was meinst Du damit? Von welchen Zeiten redest Du?
Die Zeit, die zwschen 2 Steps vergehen muss, ergibt sich aus der Endgeschwindigkeit und der Beschleunigung. Die Zeit zwischen run() muss auf jeden Fall kleiner sein, als die kleinste Zeit zwischen 2 Steps. Häufiger aufrufen ist kein Problem. Wird run() zu selten aufgerufen, dreht der Motor langsamer als er sollte. Mit der Zahl der ausgeführten Steps hat das aber nichts zu tun - übers Ziel schießt er so nie hinaus.

ffm65:
deshalb ist mir schon klar, das move(10) schneller abgearbeitet ist als 10x move(1). da er ja nur einmal positiv beschleunigen und abbremsen muss als das ganze 10x zu machen.

Bei move(1) kann es gar kein Beschleunigen und Abbremsen geben. Da ist er immer am Anfang der Beschleunigung mit der größten Steplänge. Deshalb dauert das dann dementsprechend auch länger, da die Steps nie schneller werden.

ffm65:
nehmen wir an, in dem beispiel wäre die beschleunigung 1000 schritte/sec^2. nach 1sec hätten wir also die geschwindigkeit von 1000 schritte/sec erreicht. würde dann 1 schritt 2,01sec benötigen; is das so oder hab ich da nen knick in der optik?

Wie kommst Du auf die 2Sek? Ich hab's auch mal nachgemessen, er macht alle 30ms einen Schritt, dh. 0,3 Sekunden für die 10 Schritte. Und soviel Zeit liegt dann bei dem Sketch von my_xy_projekt zwischen Start, und der Ausgabe von Schritt 10. Ich hab' da keine 2 Sekunden dazwischen.

ffm65:
gedankenexperiment: positive und negative beschleunigung ist unendlich; geschwindigkeit 1000 schritte/sec. dann wären die 10 schritte aber in 10ms durch, oder?

Im Prinzip ja. Aber warum Gedankenexperiment? Man kann die Beschleunigung ja entsprechend hoch setzen, und dann erkennt man, dass die Lib bei mov(1) durchaus ein Problem mit der Stepgeschwindigkeit hat. Sie macht ja gar keine 2 Schritte, zwischen denen sie die Stepzeit berechnen kann.

ffm65:
btw wie verhält sich das denn mit dem runSpeed() befehl? der müsste ja die 10ms bei 10xmove(1) einhalten?

Der macht das dann tatsächlich richtig.

ffm65:
dann bekomme ich aber mit einer hohen geschwindigkeit evtl. probleme mit schrittverlusten (die bib schreibt ja >1000schritte/sec ist unzuverlässig)?

Die Schrittverluste sind aber ein Problem des Motors und nicht der Lib. Der Hinweis in der Lib bezieht sich eher darauf, dass es dann (zumindest bei den AVR-Prozessoren ) schwierig ist, run() zuverlässig häufig genug aufzurufen.

Hast ja Aufwand betrieben für der ganzen Beantworterei…

MicroBahner:
Was meinst Du damit? Von welchen Zeiten redest Du?

Verändere ich die Beschleunigung, ändert sich das Zeitverhalten.
Gegeben jetzt 2000 - Ausgabe: 21(1) / 211(10*1) / 101(10)

Ich glaub ich hab mich nur unglücklich ausgedrückt…

OK, aber auch bei einer hohen Beschleunigung schießt der Stepper nicht übers Ziel hinaus, sondern verliert eher Schritte oder kommt gar nicht mehr mit und bleibt stehen.

nen sketch um die zeiten zu messen war ich auch gerade am zusammenbauen. ich bin mal so frech und hör bei mir auf und nutze einfach deinen.

ok, falsch gelegen mit den 2,01sec pro schritt.

MicroBahner:
Wie kommst Du auf die 2Sek?

kannst du mir vllt. erklären oder nen verweis auf ne gute literaturquelle geben warum es bei move(1) kein beschleunigen und abbremsen geben kann und was die steplänge ist (ist das die 1 oder ist das ne zeit) und warum die am anfang am größten ist. ich glaub dann klärt sich einiges bei mir auf.
bei move(1) würde ich erwarten, dass er die beschleunigungsphase beginnt, die dann aber vorzeitig abbricht weil ja der nächste schritt schon ansteht.

Steplänge = Zeit zwischen 2 Steps.
Die Beschleunigung ergibt sich daraus, dass die Steplänge, als die Zeit zwischen 2 Steps von Schritt zu Schritt kleiner wird. Der Motor bewegt sich bei jedem Schritt immer um den gleichen Drehwinkel. Je kürzer die Zeit zwischen 2 Schrittimpulsen, umso schneller dreht er.
Mache ich nur einen Schritt, kann ich auch nichts beschleunigen.