MobaTools Library: Version 2.1 1 mit Verwalten von Tastern/Schaltern

Hallo,
der eine oder andere hier kennt ja meine MobaTools. Bei der Ansteuerung von Steppermotoren wurde schon einige Male ( sicher zu Recht ) bemängelt, dass da keine Anfahr- und Bremsrampen möglich sind.
Das habe ich nun eingebaut.
Auch ist der Code intern aufgeteilt worden, was zu reduziertem Flash-Verbrauch führt, wenn nicht alle Features genutzt werden. Das ist für den Anwender aber transparent, er muss nichts dafür tun.

Ich habe schon möglichst gründlich getestet. Trotzdem wäre es schön, wenn sich jemand finden würde, der sich als Beta-Tester hergibt, und das Ganze auch nochmal ausprobiert. Man selbst ist ja manchmal etwas betriebsblind.
Es würde mich also freuen, wenn jemand das unabhängig testet, bevor ich das als neue Release für den Bibliotheksverwalter freigebe. Der aktuelle Source ist hier zu finden.
In den Beispielen ist auch ein Sketch dabei, mit dem man die Steppermethoden über den seriellen Monitor aufrufen kann.

Die neuen Aufrufe sind in der deutschen Doku V1.1 bereits enthalten ( die englische muss ich noch übersetzen ).
Die Rampe wird über ihre Länge in Steps und damit über die Beschleunigungs-/Bremsstrecke definiert ( Zahl der Steps von Stillstand bis zur vorgegebenen Geschwindigkeit ).

Fragen dazu oder Fehlermeldungen können hier, oder direkt in GitHub gestellt werden.

Ich werde auch im Parallelforum nachfragen, ob dort jemand Lust hat das zu testen :wink:

Release Notes:

V1.1.0
Funktionserweiterung:
Rampe für die Steppermotore. Die Länge der Rampe wird über die Anzahl Steps ( vom Stillstand bis zum Zieltempo ) definiert.
Die Zahl der Steppermotore ist per define auf 6 begrenzt. Dies ist jedoch keine harte Grenze mehr, sondern eher der Leistungsfähigkeit des verwendeten Prozessors angepasst um die IRQ-Belastung nicht zu groß werden zu lassen. Werden z.b. keine Softleds und Servos genutzt, kann dieser Wert in der MobaTools.h auch erhöht werden.

Fehlerberichtigung
moving() gab falsche Werte bei Strecken größer +/- 32768, da eine temporäre Variable mit int statt long definiert war.

Sonstiges:
Optimierter Flash-Verbrauch, wenn nur Teile der Funktionalität genutzt werden (z.B. nur Stepper-Motore amsteuern)
Dazu wurden die Softwarekomponenten auf mehrere .cpp Dateien verteilt, so dass der Linker optimieren kann. So werden jetzt nur die tatsächlich verwendeten Komponenten eingebunden. Dazu musste die ISR für Stepper und Softleds etwas umgeschrieben werden ( da beide den gleichen IRQ verwenden ). Stepper bzw Softled Funktionen sind als jeweils eigene Funktionen mit Attribut weak definiert.
In 'libraries.properties' muss die Zeile
dot_a_linkage=true
hinzugefügt werden. Damit werden erst alle *.cpp.o - Files in ein Archiv zusammengebunden bevor es an den Linker übergeben wird. Nur dann optimiert der Linker und bindet nur die .o Komponenten ein, die zum Auflösen der verwendeten Referenzen benötigt werden.
Aus Sicht des Anwenders ist dies transparent - es muss weiterhin nur die MobaTools.h eingebunden werden.

Wie groß (Millisekunden) ist der Jitter auf dem STEP-Signal? Vergleichbar mit GRBL?

Ich kenne GRBL nicht ( ich mache nichts mit CNC ).
Das Stepsignal basiert auf einem Timer IRQ im 200µs Takt. D.h. ein 200µs Jitter kann immer auftreten.
Ist der Prozessor nicht zu stark belastet, könnte der Takt auch noch reduziert werden ( ist ein #define ). Man muss aber bedenken, dass Interrupts in dieser Taktrate auftreten können.

Sind Beschleunigungsrampe und Bremsrampe getrennt voneinander konfigurierbar? also z..b eine lange Beschleunigungs-Rampe, aber eine kurze Brems-Rampe?

LG Stefan

200us ist schon ganz ok :slight_smile:

bin grad' am runterladen, mal schaun' ob ich die nächsten Tage zum Testen komme.

Hallo,

die Frage wäre um welche Rampe handelt es sich?
S-Rampe?

Um das zu testen bräuchte man einen entsprechenden Versuchsaufbau.
Unsere Forums-Cocktailmixerbauer könnten das sicherlich testen.

Hat damit erstmal nichts zu tun, finde ich aber cool.

Doc_Arduino:
die Frage wäre um welche Rampe handelt es sich?
S-Rampe?

Vielleicht sollte ich das Ganze doch noch etwas genauer erläutern, damit keine falschen Erwartungen/Vorstellungen an die MobaTools und und diese Erweiterung aufkommen.
Es geht nicht darum, eine vordefinierte Rampe exakt nachzufahren. Vielleicht war der Begriff 'Rampe' da auch etwas unglücklich, und man sollte besser von Bescheunigungs-/Bremsweg sprechen ( Rampe ist halt kürzer und 'griffiger' :wink: ). Es geht darum, Schrittverluste zu vermeiden, wenn sich die Steprate sprunghaft ändert, und der Motor nicht mehr nachkommt. Oder er kann die gewünschte Steprate aus dem Stand gar nicht erreichen und vibriert nur, statt sich zu bewegen.

Die MobaTools sind nach wie vor mit dem Gedanken 'Modellbau' entwickelt und da ist oftmals schon rein aus optischen Gründen ( z.B. bei einer Schiebebühne ) eine weiches Anfahren und Bremsen gewünscht, selbst wenn der Motor der Steprate auch direkt folgen könnte. Natürlich schließt das Anwendungen in anderen Bereichen nicht aus, aber für z.B. CNC-Anwendungen sind die MobaTools definitiv nicht gemacht/geeignet.

Die Characteristik der 'Rampe' ist fest, und lässt sich nicht beeinflussen. Es geht nur darum, dass sich der Schrittabstand von Schritt zu Schritt nicht zu stark ändert. ( Nur die Charakteristik der ersten/letzten Schritte aus dem Stand ließe sich durch ein #define etwas anpassen ). Grundsätzlich geht es schon in Richtung 'S-Rampe'. D.h. die Beschleunigung ist nicht konstant, sondern aus dem Stand geht es erstmal langsam los, um dann mehr Fahrt aufzunehmen.

Der 'Standardablauf' ( Beschleunigung/max.Steprate vorgeben, und dann zum Zielpunkt fahren ) ist sicher kein Problem und dürfte fehlerfrei funktionieren. Die 'Gemeinheiten' sind Änderungen an den Parametern während einer solchen Bewegung.

Wenn sich z.B. während des Bremsens die Zielposition ändert, kann es sein, dass das neue Ziel gar nicht mehr direkt erreichbar ist, weil es jetzt zu nah ist. Oder es ist weiter weg, und das Bremsen muss abgebrochen werden. Auch wenn der Bremsweg während des Bremsens verlängert wird, treten ähnliche Effekte auf.
Da kann man sich noch allerhand 'Gemeinheiten' ausdenken, um einen oder mehrere der Parameter zu einem möglichst ungünstigen Zeitpunkt zu ändern. Und ich bin mir eben nicht 100%tig sicher, ob ich da an alle Szenarien gedacht habe. In keinem Fall darf sich die Steprate sprunghaft ändern, oder sich das Programm verhaspeln. Und das letzte eingestellte Ziel muss immer zuverlässig erreicht werden. Gegebenenfalls auch dadurch, dass es zunächst darüber hinausgeht, und dann wieder zurück zum Ziel.

Hallo,

klingt doch nicht schlecht. :slight_smile: Wenn sich das Ziel während der Bewegung ändert, dann hat glaube ich jede Steuerung ein Problem. Das wäre dann eine Regelung und die kann laut meiner Meinung nicht ruckfrei arbeiten. Bspw. wie soll man 5 Steps sanft und schnell beschleunigen und bremsen. Ist einfach zu kurz. Die perfekte S-Rampe funktioniert laut meines Wissens ja nur mit festen Ziel- und Endwert ohne Änderung zwischendrin. Der Rest wäre wie du schon schreibst sanftes pendeln um den Zielwert. Wobei sich sanft mit schnell ausschließt. :slight_smile:

Ich meine für einen Portal- oder Kohlekran oder Drehscheibe ist das mehr als nur ausreichend finde ich.

Auch wenn mein Vorhaben "neue Modelleisenbahnplatte" auf Eis liegt (kein Platz) bedanke ich mich für das Update.

Hi

Ein Verhalten, wie Du Es beschreibst, zeigt die AccelStepper ebenfalls, wobei dort die Rampen linear sein müssten (ungetestet).
Wenn dort der Endpunkt während des Bremsen zu Nahe an den aktuellen Punkt gesetzt wird, bremst der Stepper auch erst 'normal' runter - kommt also am alten Endpunkt an - beschleunigt dann in Gegenrichtung (die Hälfte der Entfernung) um dann mit der Bremsrampe am Ziel anzukommen. (getestet)
Äderungen der Geschwindigkeit während der Bremserei hatte ich dort aber nicht versucht - Das liegt aber eher daran, daß die motorspeziefische Geschwindigkeit kaum während des Motorleben ändern wird - Der hat Sein Maximum und Das wird wohl eingestellt sein - sonst hätte man auch einen günstigeren Motor wählen können ;), Der ebenfalls dann an SEINEM Maximum läuft.

Für eine einzelne CNC-Achse sollten sich auch die MoBa-Tools hernehmen lassen - bei CNC ist ja 'nur' das Problem, daß alle Achsen zusammen einen Punkt ergeben und Dieser MUSS (zwingend) ziemlich genau eingehalten werden - da dort die Maschine gerade 'was machen soll'.

Hierfür bietet eine weitere Lib im Zusammenspiel mit der AccelStepper die Möglichkeit, mehrere Motoren gleichzeitig proportional zu Verfahren, dort müssten auch die Rampen mit enthalten sein - hatte Das aber nur Mal kurz angespielt, als der Hinweis hier im Forum kam und ich eh mit der AccelStepper dran war.
GrblGru sollte dort aber ggf. die bessere Wahl sein, da genau dafür entwickelt - der Entwickler war zumindest damals in der ZerspanungsBude.net aktiv, wo Er das Projekt auch vorstellte und zeitnah auf Änderungswünsche einging - war damals in dem Thema aber nur lesend unterwegs, da meine 'kleine Chinesin' per LinuxCNC befeuert wird und Das auch so bleiben soll.
Ähnlich 'kurze Dienstwege' gab's bei Christian Knüll (EstlCAM), Der Sich ebenfalls dort rumdrückte - da wurden Fehler teilweise binnen weniger Stunden ausgebügelt!!
Akut habe ich für Test-Spielereien keine Zeit (jaja ... aber schreiben kann Er in der Zeit schon :slight_smile: ), lese aber (so ziemlich) Alles mit (die ESP-Dinger gehen an mir noch eher vorbei ...)
Und wenn ich damit fertig bin, kümmere ich mich wieder um meine aktuelle Spielerei ... der Winter kommt und meine Arduino's betrachten meine Heizung noch mit anderen Augen, als ich ...

MfG

Deltaflyer:
Sind Beschleunigungsrampe und Bremsrampe getrennt voneinander konfigurierbar? also z..b eine lange Beschleunigungs-Rampe, aber eine kurze Brems-Rampe?

LG Stefan

Hallo Stefan,
das ist bisher nicht vorgesehen. Die beiden Rampen sind immer gleich lang ( es gibt nur einen Aufruf für die Rampenlänge ). Ich hatte das auch überlegt, aber das führt dann zu ein paar zusätzlichen Teufeleien, die ich mir erstmal ersparen wollte.
Um die Step-Erzeugung vom Ablauf im Sketch weitgehend unabhängig zu machen ( da kann man sogar delays verwenden ohne die Bewegung zu stören ) läuft sehr viel in der ISR. Und die ist eh schon so aufwändig und lang, dass ich da nested IRQ's zulassen muss.

OK, dann muss ich für Version 2 meines Projektes auf eine Lib für die Motorsteuerung verzichten, und es wirklich von Hand machen.

Aber das ist Ok, hab nur gedacht, wenn es inzwischen was Fertiges dafür gibt, kann ich mir diesen Teil der Arbeit sparen.

LG Stefan

postmaster-ino:
Ein Verhalten, wie Du Es beschreibst, zeigt die AccelStepper ebenfalls, wobei dort die Rampen linear sein müssten (ungetestet).

stimmt, die Accelstepper verwendet Rampen mit konstanter Beschleunigung.

Für die Anwendungen, bei denen ich die MobaTools sehe, finde ich es aber besser nicht gleich mit der vollen Beschleunigung loszulegen, sondern aus dem Stand erstmal etwas 'sanfter' anzufahren. Und beim Bremsen ist es genauso.

postmaster-ino:
Äderungen der Geschwindigkeit während der Bremserei hatte ich dort aber nicht versucht - Das liegt aber eher daran, daß die motorspeziefische Geschwindigkeit kaum während des Motorleben ändern wird

Die eingestellte Steprate hängt üblicherweise nicht von der maximal möglichen Motorgeschwindigkeit ab, sondern von den Anforderungen der Anwendung. Der Motor muß nur so gewählt werden, dass er alle erforderlichen Stepraten mitmacht. Die maximale Steprate wird aber sicher nicht immer ausgereizt. Du fährst dein Auto ja auch nicht immer mit Vollgas :wink: .

Doc_Arduino:
Wenn sich das Ziel während der Bewegung ändert, dann hat glaube ich jede Steuerung ein Problem.

Das wäre dann aber keine gute Steuerung. Damit sollte sie schon zurechtkommen.

Doc_Arduino:
wie soll man 5 Steps sanft und schnell beschleunigen und bremsen.

as geht dann halt nur langsam. In 5 Steps kannst Du die eingestellt max. Steprate natürlich nicht erreichen. Du bleibst dann eben am Anfang der Rampe stecken: Kaum losgefahren, schon wieder bremsen. Aber ruckelig wird das nicht.

Doc_Arduino:
Wobei sich sanft mit schnell ausschließt.

Da ist was dran. Aber man kann schon sanft anfahren, und danach mehr 'Gas' geben.

Doc_Arduino:
Ich meine für einen Portal- oder Kohlekran oder Drehscheibe ist das mehr als nur ausreichend finde ich.

Würde mich freuen, wenn Du es irgendwann mal nutzen kannst.

Vielleicht ist es ja auch wirklich so, dass diese 'Gemeinheiten' die ich vielleicht übersehen habe sehr seltene Sonderfälle sind, und in der Praxis kaum vorkommen. Dann wäre die Version ja für die Meisten bereits voll einsetzbar.
Komplett fehlerfreie Software gibt es ja eh nicht :wink:

Deltaflyer:
OK, dann muss ich für Version 2 meines Projektes auf eine Lib für die Motorsteuerung verzichten, und es wirklich von Hand machen.

Aber das ist Ok, hab nur gedacht, wenn es inzwischen was Fertiges dafür gibt, kann ich mir diesen Teil der Arbeit sparen.

LG Stefan

Hallo Stefan,
ich weis nicht, ob es Dir eine Vereinfachung bringt, aber Du kannst natürlich die Rampenlänge 'on the fly' ändern. Also mit einer langen Rampe anfahren, und wenn die Geschwindigkeit erreicht ist, auf eine kurze Bremsrampe umschalten. Ist vielleicht einfacher, als alles von Grund auf selbst zu programmieren.
Ist natürlich von deiner Anwendung abhängig, ob das so funktionieren würde.

Hallo,
ich habe meine MobaTools nochmal etwas überarbeitet. Der Code für die Stepperrampe ist nun einfacher, und braucht auch weniger Flash. Manchmal ist ja weniger auch mehr :sunglasses: . Der Code wurde intern auch so aufgeteilt, dass nicht genutzte Funktionalität nicht mehr eingebunden, und somit auch nicht unnütz Programmspeicher verwendet wird.
Mit einem kleinen Testautomaten ( der ist auch bei den Beispielen dabei ) habe ich das nun getestet und für gut befunden :grin: .
Diese Version ( V1.1.1 ) kann inzwischen auch über den Bibliotheksverwalter geladen werden. Die Zip-Datei gibt's hier.

Wesentliche Funktionserweiterungen:

  • Beschleunigungs- und Bremsrampe bei der Stepperfunktion. Beide Rampen sind immer gleich lang. Die Länge der Rampe wird in Steps vorgegeben ( Zahl der Steps von Stillstand bis zur eingestellten Geschwindigkeit )
  • Die Beschleunigung ist in der Rampe nicht konstant. Aus dem Stillstand wird eher 'sanft' angefahren, und dann mehr 'Gas' gegeben. Dementsprechen umgekehrt beim Bremsen. Zum Stillstand hin läuft die Rampe sanft aus. Dieses Verhalten kann mit einem #define (RAMPOFFSET) in Grenzen beeinflusst werden.
  • Standardmäßig ist die Zahl der Stepper auf 6 eingestellt. Dies ist jedoch keine harte, vom Code vorgegebene, Grenze und kann über ein #define auch verändert werden. Da aber die Steperzeugung komplett in Timer-Interrupts passiert, ist hier die Prozessorleistung zu berücksichtigen.
  • Aus dem gleichen Grund ist die maximale Steprate auf 1,2kHz begrenzt ( 800µs per Step ). Dies ergibt sich aus einem 200µs Timertakt und minimal 4 Takten / Step.
    Wird nur die Stepperfunktion genutzt, und auch nur mit wenigen Steppern, können diese Wert auch per #define angepasst werden um höhere Stepraten zu erreichen. Z.B. eine Taktrate von 100µs.
    Werden weniger Takte/Step zugelassen, steigt der Jitter entsprechen an. Unter 3 sollte man nicht gehen.

Hallo und erstmal eine Glückwunsch zur neuen Version!

Auch wenn es gelegentlich anders empfunden werden mag, so schreibe ich in tiefstem Respekt vor der Leistung des Bibliothekserstellers.

Heute erst habe ich meinen unipolaren Stepmotor 28BYJ-48 in die Hand bekommen und wer zu spät kommt ...

Dennoch erste Eindrücke:

  • In dem Beispiel Stepper_01 ist keine Rampe drin, oh wie schade.
  • setSpeed würde ich gerne um eine Rampe ergänzen, scheint aber im Gegensatz zu setSpeedSteps nicht vorgesehen zu sein. Oder?
  • Nach detach (detach from output) brennen die LEDs des Treibers weiter, sollten die Pins nicht auf Input stehen. Als Gegenprobe: Nach pinMode(j,INPUT) gehen die LEDs aus.

Drehen trotz delay ist ein gutes Argument für diese Bibliothek. Denn gelegentlich hat man ja doch mal eine kleine Blockade, die so nicht ins Gewicht fallen sollte.

Ich bleibe am Ball!

Hallo,
freut mich, dass Du dir meine Lib angeschaut hast, und danke für die Blumen 8) :slight_smile: .

Zu deinen Anmerkungen:

agmue:
In dem Beispiel Stepper_01 ist keine Rampe drin, oh wie schade.

Stimmt, die Beispiele sollte ich auch um die Rampenfunktion ergänzen. Das kommt auf die ToDo-Liste für die nächste Version

agmue:
setSpeed würde ich gerne um eine Rampe ergänzen, scheint aber im Gegensatz zu setSpeedSteps nicht vorgesehen zu sein. Oder?

setSpeed ist ja nur eine andere Art die Geschwindigkeit vorzugeben ( in Umdr/min ). Die aktuell eingestellte Rampe gilt da genauso. Letzendlich wird der Wert auch nur in eine Steprate umgerechnet, und dann intern setSpeedSteps aufgerufen.
Man kann allerdings die Rampenlänge nicht in einem Aufruf direkt mitgeben, sondern müsste sie danach mit einem eigenen Aufruf setzen, das stimmt. ( Oder man belässt es einfach bei der aktuell gültigen Rampe )

agmue:
Nach detach (detach from output) brennen die LEDs des Treibers weiter, sollten die Pins nicht auf Input stehen. Als Gegenprobe: Nach pinMode(j,INPUT) gehen die LEDs aus.

Das stimmt wieder. Die Pins werden nur 'intern' getrennt und er greift nicht mehr darauf zu.
Da sie aber beim attach auch selbständig auf OUTPUT gestellt werden, würde es wohl Sinn machen, beim detach wieder auf INPUT zu stellen. Wäre dann auch ein Fall für die ToDo Liste.

Dass die Steperzeugung weitgehend unabhängig vom Ablauf im loop ist, war ein wesentlicher Beweggrund für diese Lib. Solange man im loop die Interrupts nicht länger aussperrt, oder den Prozessor anders mit Interrupts 'zunagelt' kann man da eigentlich treiben was man will.
Nachteil ist dann halt die HW-Abhängigkeit, da ja ein HW-Timer genutzt wird. Derzeit läuft die Lib daher nur auf den AVR ATmega und den STM32F1 Prozessoren. Der Due steht noch auf der ToDo-Liste, hat bisher aber keine Prio.

Wenn dir noch was auffällt - immer her damit. Die nächste Version steht schon in den Startlöchern, da im Stummiforum eine Anforderung aufkam. Die Stepper-Klasse wird dann auch einen 'enable' Ausgang steuern können, um gegebenenfalls den Motorstrom bei Stillstand abschalten oder reduzieren zu können.

MicroBahner:
Stimmt, die Beispiele sollte ich auch um die Rampenfunktion ergänzen.

Ich hätte da einen Vorschlag, basierend auf Bounce der AccelStepper-Bibliothek.

Da ich delay() in den Beispielen nicht gut finde, habe ich es mit einer switch/case-Schrittkette realisiert.

/*  Demo zum Anschluß eines unipolaren Stepmotors 28BYJ-48 
 *  mit Verwendung einer Beschleunigungsrampe
*/
#include <MobaTools.h>
Stepper4 Step1(4096);           // HALFSTEP ist default

void setup() {
  Step1.attach( 4, 5, 6, 7 ); // Anschluß an digitalen Ausgängen; Treiber IN1,IN2,IN3,IN4
  Step1.setSpeed( 240 );      // = 24 U/Min
  Step1.setRampLen(500);      // Beschleunigung
  Step1.setZero();            // Referenzpunkt für Motor 1 setzen
}

void loop() {
  uint32_t jetzt = millis();        // aktuelle Zeit
  static uint32_t vorhin = jetzt;   // gemerkte Zeit
  static byte status;               // Schrittkettenstatus

  switch (status) {
    case 0:
      Step1.write(360);               // 1 Umdrehung vorwärts
      status++;
      break;
    case 1:
      if ( !Step1.moving() ) {          // warten bis die Bewegung abgeschlossen ist
        vorhin = jetzt;                 // Zeit merken
        status++;
      }
      break;
    case 2:
      if ( jetzt - vorhin >= 1000 ) {   // 1 Sekunde warten
        status++;
      }
      break;
    case 3:
      Step1.write(0);                 // 1 Umdrehung zurück
      status++;
      break;
    case 4:
      if ( !Step1.moving() ) {          // warten bis die Bewegung abgeschlossen ist
        vorhin = jetzt;                 // Zeit merken
        status++;
      }
      break;
    case 5:
      if ( jetzt - vorhin >= 1000 ) {   // 1 Sekunde warten
        status++;
      }
      break;
    default:
      status = 0;
  }
}

Angeregt durch ein anderes, leider abgebrochenes Thema:

/*  Demo zum Anschluß eines unipolaren Stepmotors 28BYJ-48
    mit Verwendung einer Beschleunigungsrampe
    Slider-Minimalprogramm: Endposition - Startposition - Bewegung von Start- zu Endposition
*/
#include <MobaTools.h>
Stepper4 Step1(4096);           // HALFSTEP ist default
const byte linksPin = 8, rechtsPin = 9, weiterPin = 10;

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  pinMode(8, INPUT_PULLUP);   // aktiv LOW
  pinMode(9, INPUT_PULLUP);   // aktiv LOW
  pinMode(10, INPUT_PULLUP);  // aktiv LOW
  Step1.attach( 4, 5, 6, 7 ); // Anschluß an digitalen Ausgängen; Treiber IN1,IN2,IN3,IN4
  Step1.setSpeed( 60 );       // = 6 U/Min
}

void loop() {
  enum {ENDPOSITION, STARTPOSITION, BEWEGUNG};
  static byte status;               // Schrittkettenstatus
  static bool alt = digitalRead(weiterPin), akt = digitalRead(weiterPin);
  alt = akt;
  akt = digitalRead(weiterPin);
  if (alt != akt) {
    delay(30);                // einfaches Entprellen
  }

  switch (status) {
    case ENDPOSITION:
      if (!digitalRead(linksPin)) {
        Step1.doSteps(10);
      } else if (!digitalRead(rechtsPin)) {
        Step1.doSteps(-10);
      } else if (alt && !akt) {
        Step1.setZero();              // Endpunkt für Motor 1 setzen
        Serial.println("STARTPOSITION");
        status++;
      } else {
        Step1.stop();
      }
      break;
    case STARTPOSITION:
      if (!digitalRead(linksPin)) {
        Step1.doSteps(10);
      } else if (!digitalRead(rechtsPin)) {
        Step1.doSteps(-10);
      } else if (alt && !akt) {
        Step1.setSpeed( 240 );      // = 24 U/Min
        Step1.setRampLen(500);      // Beschleunigung
        Step1.write(0);               // Bewegung zu Endpunkt
        Serial.println("BEWEGUNG");
        status++;
      } else {
        Step1.stop();
      }
      break;
    case BEWEGUNG:
      if ( !Step1.moving() ) {          // warten bis die Bewegung abgeschlossen ist
        Step1.setSpeed( 60 );      // = 6 U/Min
        Step1.setRampLen(0);      // Beschleunigung
        Serial.println("ENDPOSITION");
        status = 0;
      }
      break;
    default:
      status = 0;
  }
}

Wenn Du was magst, kannst Du es gerne übernehmen.

Hallo agmue,
danke für deine Demos. Die übernehme ich gerne in meine Beispiele.
Für die 1.1 muss ich noch ein Update machen, da ich noch einen Bug gefunden habe. Da kommen die dann schon rein :slight_smile:

Ich bin etwas sparsam mit Kommentaren, könntest Du noch ergänzen. SPI kann ich mangels Hardware nicht testen.