Stepper Motor mit Fußschalter steuern

linda89:
Kannst du mir sagen was genau die 4 Zahlen beim Speed angeben?

Kennst Du die Sprach-Referenz? Da wird auch map() erklärt.

linda89:
Ich habe mal ein Foto beigefügt, welche ich meine.

Nur als Hinweis für das nächste Mal: Es ist immer ungünstig Code oder Codeteile als Foto einzustellen. Kopiere sowas immer direkt in deinen Post - eingeschlossen in CodeTags ( das </> links oben im Editor ). Das sieht dann so aus ( wie der Code von Uwe auch ) und Du kannst auch noch eine Kommentar dazuschreiben:

  pd = map((analogRead(spd)), 0, 1023, 2000, 50); // <<-- Das verstehe ich nicht
  setdir = !digitalRead(reverseSwitch);  //LOW ist Rechtsdrehung; Erhöht Schritte.
  if ( !(IstSchritte <= 0 && !setdir) || !(IstSchritte >= MaxSchritte && setdir))  // erlaubt Schritte von 0 bis Maximale Schrittanzahl

In diesem Fall ginge es auch farbig:

pd = map((analogRead(spd)), 0, 1023, 2000, 50);

Die Funktionsreferenz Arduino Reference - Arduino Reference erklähren viele Arduino-spezifische Funktionen und ein wenig C-Funktionen.
Die Referenz gibt es auch (nicht verlinkt) in deutsch: Arduino-Referenz - Arduino-Referenz

Dazu hilft ein Buch / Referenz von C/C++.

Grüße Uwe

Guten Abend zusammen,
Bei meiner Anwendung steuer ich ja den schrittmotor per fußschalter.
Ein seil wird bei Betätigung des fußschalters eingezogen und beim loslassen ausgerollt.
Jetzt habe ich angefangen endlagenschalter einzubauen, um das einziehen bzw abrollen zu begrenzen.
Mein Ziel war es, z.b. beim einziehen des seils bei einem Punkt den Motor zu stoppen und beim loslassen des fußschalters wird wieder abgerollt. Heißt also der Motor bleibt an, nur die drehbewegung wird gestoppt.

Leider klappt es nicjt. Bleiben wir beim Beispiel seileinzug. Wird der Endlagenschalter aktiviert, bleibt der Motor nicht stehen sondern ändert die drehbewegung... rollt das seil also ab. Also der selbe Impuls als wenn ich den fußschalter loslassen würde....

Wenn ich den endlagensxhalter aber mit der Stromversorgung koppel, wird bei Aktivierung der Strom unterbrochen und der Motor bleibt stehen. Super Ziel erreicht...
Nein falsch gedacht... Beim loslassen des fußschalters passiert ja gar nichts mehr da kein Strom da ist...

Man da bin ich in der Zwickmühle. Habt ihr Ideen zur korrekte Umsetzung?
Danke euch vorab.

linda89:
Habt ihr Ideen zur korrekte Umsetzung?

Bei einem Schrittmotor benötigst Du einen Refernzpunkttaster, alle weiteren Positionierbewegungen lassen sich über das Zählen der Schritte programmieren. Alleine Notaustaster könnten noch sinnvoll sein, um mechanische Zerstörungen zu verhindern.

Die MobaTools wurden Dir schon mal vorgeschlagen, denn die enthalten das Entprellen mechanischer Kontakte, das Ausführen einer Aktion nach Ablauf eines Intervalls, wie auch die Ansteuerung eines Schrittmotors. Damit reduziert sich das Programm auf relativ wenige Zeilen (getestet mit UNO und DRV8825):

#define MAX8BUTTONS
#include <MobaTools.h>
const byte pinArray [] = { 2 };          // Fußschalter
const byte pinCount = sizeof(pinArray);
const byte potiPin = A0;                 // Poti fuer Seillänge
MoToButtons Taster( pinArray, pinCount, 30, 5000 );
MoToTicker Intervall;                    // Zeitinterval zum Auslesen des Seillängenpotentiometers
MoToStepper Step(200, STEPDIR);          // Schritte pro Umdrehung
uint16_t schritte = 2000;                // Schritte bis zur Endposition

void setup() {
  for (byte j = 0; j < pinCount; j++) {
    pinMode(pinArray[j], INPUT_PULLUP);  // Taster-Pins als Input definieren (gedrückt = LOW)
  }
  Step.attach( 7, 6 );                   // stepPin, dirPin
  Step.setSpeed( 1500 );                 // = 150 U/Min
  Step.setRampLen(50);                   // Beschleunigung
  Step.setZero();                        // Referenzpunkt setzen
  Intervall.setTicker( 100 );            // 100ms Tickerzeit
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  Taster.processButtons();
  if ( Intervall.ticker() ) {            // Seillänge alle 100ms neu einlesen und setzen
    schritte = map((analogRead(potiPin)), 0, 1023, 200, 2000);
  }
  if (Taster.pressed(0)) {
    Step.writeSteps(schritte);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  if (Taster.released(0)) {
    Step.writeSteps(0);
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Das Referenzieren habe ich weggelassen, da ich davon ausgehe, der Schrittmotor steht beim Einschalten in der Startposition.

uwefed:
Du kannst das auch ohne Bibliothk machen.
Ich presentiere hier mal meine Lösung obwohl eigentlich hier weitgehen kein Sketch geliefert wird sondern geholfen wird zum Sketch zu kommen.

Ich nehme mal an der Schrittmotor macht 200 Schritte pro Umdrehung.
Hab mal versucht den Sketch nach deinen Vorgaben zu ändern. Er kompiliert fehlerlos, ich weiß aber nicht ob er funktioniert.
Versuch mal zu verstehen was ich da gemacht habe.
Bei Fragen bin ich da.

Ich zähle die Schritte mit.
Ein Schritt darf nur gemacht werden wenn die Schrittanzanl ab Start zwischen 0 und Maximalwert liegt bzw wenn die Bewegung vom Limit weg in den Bereich hinein führt. Das erreicher ich hoffentlich mit dem
if ( !(IstSchritte <= 0 && !setdir) || !(IstSchritte >= MaxSchritte && setdir))

Um weitere if zu vermeiden wende ich etwas Matematik an:
setdir = !digitalRead(reverseSwitch);
Setdir wird LOW wenn der Eingang HIGH ist und umgekehrt. Es ist kein if notwendig sondern nur eine Zuweisung und ein Negieren (Zeichen ! ) des Zustandes. Alternativ könnte als Negation am Fußschalter auch der NC Kontakt statt des NO verwendet werden.

IstSchritte += (1 - (setdir * 2));
Hier wird 1 dazugezählt oder weggezählt je anch Wert von setdir.
Ist setdir LOW, was 0 entspricht, wird daraus +1.
Ist setdir HIGH, was 1 Entspricht wird daraus 2 und 1 -2 ergibt -1.
Mit += spare ich mir die Variable nochmal zu schreiben. a+=1 entspricht a=a+1; ( kleines C einmaleins).

Grüße Uwe

// Defin pins

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;    // Potentiometer

// Variables

int pd = 500;      // Pulse Delay period
boolean setdir = LOW; // Set Direction;  LOW = Rechts bzw erhöht Anzahl Schritte

int IstSchritte = 0; //Aktuell gemachte Schritte.
int MaxSchritte = 2000; // limit maximale schritte ( zb 10 Umdrehungen a 200 schritte pr umdrehung = 2000)

void setup()
{
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);
}

void loop()
{
  pd = map((analogRead(spd)), 0, 1023, 2000, 50);
  setdir = !digitalRead(reverseSwitch);  //LOW ist Rechtsdrehung; Erhöht Schritte.
  if ( !(IstSchritte <= 0 && !setdir) || !(IstSchritte >= MaxSchritte && setdir))  // erlaubt Schritte von 0 bis Maximale Schrittanzahl
  {
    IstSchritte += (1 - (setdir * 2)); // inkementiert oder dekrementiert die Schritte.
    digitalWrite(driverDIR, setdir);
    digitalWrite(driverPUL, HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL, LOW);
    delayMicroseconds(pd);
  }
}

Guten Abend Uwe und Franz-Peter,
jetzt habe ich endlich die Zeit gefunden das Sahnehäubchen von meinem Scrip anzugehen :slight_smile:
Danke für eure Hilfe und die erste Idee zur Umsetzung.
Nochmal für euch als Zusammenfassung: Schrittmotor wird jetzt mit einem Fußschalter gesteuert (links bzw rechts Dreh) und ich kann die Geschwindigkeit einstellen :slight_smile:
Die “hoffentlich” letzte Umsetzungsidee ist ja die Dauer der Drehrichtung zu begrenzen. Momentan dreht der Motor endlos in eine oder andere Richtung.
Ich habe Uwe´s Scripidee aufgespielt, aber leider funktioniert es nicht. Der Motor dreht endlos weiter. Auch habe ich ein bisschen an den Zahlen rumgespielt. Aber es tut sich leider nichts. Als wenn keine Begrenzung da wäre…
Könntet ihr bitte nochmal einen Blick drauf werfen und mich unterstützen? Danke euch vorab.

// Defin pins
 int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer

// Variables

int pd = 500;       // Pulse Delay period

const int highSpeed = 250;
const int lowSpeed = 750;
boolean setdir = LOW; // Set Direction;   LOW = Rechts bzw erhöht Anzahl Schritte

int IstSchritte = 0; //Aktuell gemachte Schritte.
int MaxSchritte = 2000; // limit maximale schritte ( zb 10 Umdrehungen a 200 schritte pr umdrehung = 2000)

void setup()
{
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);
}

void loop()
{

   if (digitalRead(spd)) pd=highSpeed; else pd=lowSpeed;
   setdir = !digitalRead(reverseSwitch);  //LOW ist Rechtsdrehung; Erhöht Schritte.
  if ( !(IstSchritte <= 0 && !setdir) || !(IstSchritte >= MaxSchritte && setdir))  // erlaubt Schritte von 0 bis Maximale Schrittanzahl
  {
    IstSchritte += (1 - (setdir * 2)); // inkementiert oder dekrementiert die Schritte.
    digitalWrite(driverDIR, setdir);
    digitalWrite(driverPUL, HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL, LOW);
    delayMicroseconds(pd);
  }
}

agmue:
Bei einem Schrittmotor benötigst Du einen Refernzpunkttaster, alle weiteren Positionierbewegungen lassen sich über das Zählen der Schritte programmieren. Alleine Notaustaster könnten noch sinnvoll sein, um mechanische Zerstörungen zu verhindern.

Die MobaTools wurden Dir schon mal vorgeschlagen, denn die enthalten das Entprellen mechanischer Kontakte, das Ausführen einer Aktion nach Ablauf eines Intervalls, wie auch die Ansteuerung eines Schrittmotors. Damit reduziert sich das Programm auf relativ wenige Zeilen (getestet mit UNO und DRV8825):

#define MAX8BUTTONS

#include <MobaTools.h>
const byte pinArray = { 2 };          // Fußschalter
const byte pinCount = sizeof(pinArray);
const byte potiPin = A0;                 // Poti fuer Seillänge
MoToButtons Taster( pinArray, pinCount, 30, 5000 );
MoToTicker Intervall;                    // Zeitinterval zum Auslesen des Seillängenpotentiometers
MoToStepper Step(200, STEPDIR);          // Schritte pro Umdrehung
uint16_t schritte = 2000;                // Schritte bis zur Endposition

void setup() {
 for (byte j = 0; j < pinCount; j++) {
   pinMode(pinArray[j], INPUT_PULLUP);  // Taster-Pins als Input definieren (gedrückt = LOW)
 }
 Step.attach( 7, 6 );                   // stepPin, dirPin
 Step.setSpeed( 1500 );                 // = 150 U/Min
 Step.setRampLen(50);                   // Beschleunigung
 Step.setZero();                        // Referenzpunkt setzen
 Intervall.setTicker( 100 );            // 100ms Tickerzeit
 pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
 Taster.processButtons();
 if ( Intervall.ticker() ) {            // Seillänge alle 100ms neu einlesen und setzen
   schritte = map((analogRead(potiPin)), 0, 1023, 200, 2000);
 }
 if (Taster.pressed(0)) {
   Step.writeSteps(schritte);
   digitalWrite(LED_BUILTIN, HIGH);
 }
 if (Taster.released(0)) {
   Step.writeSteps(0);
   digitalWrite(LED_BUILTIN, LOW);
 }
}



Das Referenzieren habe ich weggelassen, da ich davon ausgehe, der Schrittmotor steht beim Einschalten in der Startposition.

Guten Abend Agmue,
dir auch vielen Dank für deine Unterstützung.
Bei deiner Umsetzungsidee werden leider immer Fehler angezeigt.
Das Arduino meckert bei diesen Zeilen:

MoToButtons Taster( pinArray, pinCount, 30, 5000 );
MoToTicker Intervall;                    // Zeitinterval zum Auslesen des Seillängenpotentiometers
MoToStepper Step (200, STEPDIR);

Dieses “MoTo” does not name a type…

Dann hast Du die MobaTools nicht installiert oder nicht included.

Gruß Tommy

ahhh ok, dann suche ich mal danach. danke dir für den Hinweis

Das war ein sehr wichtiger und guter Hinweis. Danke dir.
Leider funktioniert das Script so nicht. Es werden diverse Fehler angezeigt...

Und die Fehler nebst Sketch sollen wir uns jetzt auswürfeln?

Gruß Tommy

Edit: Bei 39 Posts solltest Du das schon begriffen haben.

Hallo Linda,
in dem Sketch stimmen ein paar Namen nicht. Die hatte ich mal ein einer Zwischenversion so, in der endgültigen Version dann aber umbenannt:
MoToTicker → MoToTimebase
Intervall.setTicker → Intervall.setBasetime
Interval.ticker → Intervall.tick

So sollte es fehlerfrei kompilieren:

#define MAX8BUTTONS
#include <MobaTools.h>
const byte pinArray [] = { 2 };          // Fußschalter
const byte pinCount = sizeof(pinArray);
const byte potiPin = A0;                 // Poti fuer Seillänge
MoToButtons Taster( pinArray, pinCount, 30, 5000 );
MoToTimebase Intervall;                    // Zeitinterval zum Auslesen des Seillängenpotentiometers
MoToStepper Step(200, STEPDIR);          // Schritte pro Umdrehung
uint16_t schritte = 2000;                // Schritte bis zur Endposition

void setup() {
  for (byte j = 0; j < pinCount; j++) {
    pinMode(pinArray[j], INPUT_PULLUP);  // Taster-Pins als Input definieren (gedrückt = LOW)
  }
  Step.attach( 7, 6 );                   // stepPin, dirPin
  Step.setSpeed( 1500 );                 // = 150 U/Min
  Step.setRampLen(50);                   // Beschleunigung
  Step.setZero();                        // Referenzpunkt setzen
  Intervall.setBasetime( 100 );            // 100ms Tickerzeit
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  Taster.processButtons();
  if ( Intervall.tick() ) {            // Seillänge alle 100ms neu einlesen und setzen
    schritte = map((analogRead(potiPin)), 0, 1023, 200, 2000);
  }
  if (Taster.pressed(0)) {
    Step.writeSteps(schritte);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  if (Taster.released(0)) {
    Step.writeSteps(0);
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Guten Morgen Franz-Peter,
ich danke dir, du bist klasse. Ich werde das Script zeitnah ausprobieren und mich wieder bei dir melden.

Tommy56:
Und die Fehler nebst Sketch sollen wir uns jetzt auswürfeln?

Gruß Tommy

Edit: Bei 39 Posts solltest Du das schon begriffen haben.

Da hast du Recht Tommy, entschuldigung bitte.

linda89:
Bei deiner Umsetzungsidee werden leider immer Fehler angezeigt.

Franz-Peter ist manchmal so kreativ, daß ich nicht hinterherkomme. Ich bitte um Nachsicht 8)

Guten Abend Franz-Peter,
sooooo ich bin fleißig am ausprobieren.

Der Sketch aus Post 52 ist fehlerfrei und lässt sich ohne Probleme aufspielen.
Leider funktioniert es nicht so wie gedacht oder gehofft.

Ich kann nur einmal den Motor vor und dann wieder zurück drehen lassen. Danach funktioniert der Ablauf nicht mehr. Egal ob ich den Fußschalter betätige oder nicht. Bei Betätigung leuchtet nur das gelbe Lämpchen vom Arduino und der Motor summt ganz leise. Aber ohne dass ich nur eine winzige Drehung feststellen kann.
Wenn ich dann im Script an den Zahlen spiele und ausprobiere, macht der Motor manchmal gar nichts. Obwohl ich nur die Schrittanzahl vergrößert habe oder die Geschwindigkeit erhöhen wollte.
Auch benötige ich das langsame Erhöhen der Geschwindigkeit nicht. Ich brauche nur zwei Geschwindigkeiten.

Auch habe ich es nicht geschafft aus deiner vorherigen Hilfe die beiden festen Geschwindigkeiten und das Begrenzen der Umdrehungen einzubauen :frowning:

Es war ein Versuch von mir deine beiden Sketche zu verbinden. Sketch kann ich aufspiele, Geschwindigkeiten etc funktionieren, nur die Anzahl der Umdrehungen kann ich nicht festlegen. Der Motor dreht unendlich.

// Defin pins
#define MAX8BUTTONS
#include <MobaTools.h>

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer
MoToTimebase Intervall;                    // Zeitinterval zum Auslesen des Seillängenpotentiometers
MoToStepper Step(200, STEPDIR);          // Schritte pro Umdrehung
uint16_t schritte = 10000;             // Schritte bis zur Endposition
const byte pinCount = sizeof(reverseSwitch);
// Variables

int pd = 500;       // Pulse Delay period

const int highSpeed = 175;
const int lowSpeed = 500;
boolean setdir = LOW; // Set Direction

void setup() {
for (byte j = 0; j < pinCount; j++)
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);
  Step.setZero();                        // Referenzpunkt setzen
  Intervall.setBasetime( 100 );            // 100ms Tickerzeit
}
void loop() {
 if ( Intervall.tick() )
    if (digitalRead(spd)) pd=highSpeed; else pd=lowSpeed;
    if (digitalRead(reverseSwitch)) setdir=0; else setdir=1;
    digitalWrite(driverDIR,setdir);
    digitalWrite(driverPUL,HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL,LOW);
    delayMicroseconds(pd);
}

Gerne höre ich von dir.

Hallo Linda,
deine Probleme mit dem Sketch von agmue kann ich nicht nachvollziehen. Ich habe das mal testweise aufgebaut, und da funktioniert es problemlos - auch immer wieder hin- und her.

linda89:
Auch benötige ich das langsame Erhöhen der Geschwindigkeit nicht. Ich brauche nur zwei Geschwindigkeiten.

Das hat aber schon Vorteile. Wenn Du gleich mit ‘Full Speed’ loslegst, kann es durchaus sein, dass sich der Schrittmotor ‘verschuckt’ und Schritte verliert, oder garnicht mehr losläuft, sondern nur noch summt. Das hängt dann von der eingestellten Geschwindigkeit ab ob’s geht oder nicht. Mit einer kleinen Rampe gibt’s dieses Problem nicht.

Beim letzten Sketch hast Du die Ansteuerung mit MobaTools und deine eigene direkte Steuerung der Step-Pins vermischt. Da musst Du dich schon entscheiden, wie Du den Motor ansteuern willst.

Hallo Franz-Peter,
danke für deinen Austausch.

Ich bin ganz offen & ehrlich zu dir. Ich möchte dich nämlich auch nicht verärgern.
Ich bin mit meinem momentanen Script sehr zufrieden. Es passt alles perfekt und läuft super. Ich habe zwei Geschwindigkeiten (die ich manuell im Script anpassen kann) und steuere den Schrittmotor mit einem Fußschalter (links bzw rechtsdreh).

Nur die Begrenzung der Schritte, also nur Bewegung zwischen Startposition und Endposition fehlt noch.
Also Motor steht bei Startposition (0) und kann bei Betätigung des Fußschalters max bis zur festgelegten Endposition drehen (z.b. 100) und beim loslassen des Fußschalters dreht der Motor zurück bis zur Startposition (0). Und das der Motor halt immer weiß wie viele Schritte er noch in den jeweilige Richtig machen “kann”. Da es auch passieren kann, wenn der Motor von der Endposition (100) “zurück zur Startposition (0) dreht”, dass z.b. in der Mitte (50) der Fußschalter wieder betätigt wird. Dann dürfen auch nur noch 50 Schritte bis zur Endposition gemacht werden.

Würdest du mir helfen es bei meinem Script zu versuchen? Oder ist das zu kompliziert etc, da der Aufbau des Scriptes doof ist?
So sieht es ja momentan aus:

[color=#222222]// Defin pins

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer

// Variables

int pd = 500;       // Pulse Delay period[/color]
[color=#222222]const int highSpeed = 10;
const int lowSpeed = 500;
boolean setdir = LOW; // Set Direction

void setup() {

  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);
}
void loop() {[/color]
[color=#222222]    if (digitalRead(spd)) pd=highSpeed; else pd=lowSpeed;
    if (digitalRead(reverseSwitch)) setdir=0; else setdir=1;
    digitalWrite(driverDIR,setdir);
    digitalWrite(driverPUL,HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL,LOW);
    delayMicroseconds(pd);
}[/color]

Ich hoffe ich höre von dir :slight_smile:

linda89:
Ich möchte dich nämlich auch nicht verärgern.

Womit solltest Du mich verärgert haben?
Niemand muss die MobaTools einsetzen - alles freiwillig :wink: :wink: :smiley:

Um den Weg des Steppers zu begrenzen, musst Du ja nur die Schritte mitzählen. z.B. so

// Defin pins

int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Speed-Schalter

// Variables
const uint16_t stepMax = 2000;
uint16_t stepCount = 0;

int pd = 500;       // Pulse Delay period[/color]
const int highSpeed = 10;
const int lowSpeed = 500;
boolean setdir = LOW; // Set Direction

void doOneStep () {
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
}

void setup() {

  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode (reverseSwitch, INPUT_PULLUP);
  pinMode (spd, INPUT_PULLUP);
}
void loop() {
  if (digitalRead(spd)) pd = highSpeed; else pd = lowSpeed;
  if (digitalRead(reverseSwitch)) setdir = 0; else setdir = 1;
  digitalWrite(driverDIR, setdir);

  if ( setdir ==1 && stepCount <= stepMax ) {
    // Endpunkt beim Vorwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount++;
    doOneStep();
  }

  if ( setdir ==0 && stepCount > 0 ) {
    // Endpunkt beim Rückwärtsdrehen noch nicht erreicht -> 1 Step ausführen
    stepCount--;
    doOneStep();
  }
}

Ich weis jetzt nicht, wie Du deinen Speed-Schalter angeschlossen hast - es ist ja wohl kein Potentiometer mehr? Ich hab den mal genau so initiiert, wie den reverseSwitch ( INPUT_PULLUP ).

Was mich etwas wundert ist der Wert für ‘highSpeed’. Das Tempo macht mein Stepper ( mit Microsteps und ohne Belastung!) aus dem Stand nicht mit. Wenn sich bei dir die Endpositionen bei mehrmaligem Hin- und Herfahren verschieben, dann kann das dein Stepper auch nicht ohne eine Rampe.