Schrittzahl bei Stepper Probleme mit Hardware

Hallo,

Ich habe mir eine Teststrecke Linearführung aufgebaut mit
NEMA 17
TB 6600
2 Endschalter
ArduinoMega

Der Testsketch zum Ausgeben und anschließendem Testen der Steps ist folgender:

#include <AccelStepper.h>

// PINBELEGUNG Stepper-Motor NEMA 17
const int enablePin = 8;
const int dirPin = 9;
const int stepPin = 10;

// PINBELEGUNG für die Endschalter der Linearführung
#define Auf 6  // rot
#define Zu 7   // rot

// Stepper initialisieren
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);

long steps[5];
long totalSteps = 0;

void tuerAuf() {
  digitalWrite(enablePin, LOW);
  stepper.moveTo(30000);
  while (digitalRead(Auf)) {
    stepper.run();
  }
  digitalWrite(enablePin, HIGH);
  digitalWrite(enablePin, LOW);
  stepper.moveTo(stepper.currentPosition() - 80);
  stepper.runToPosition();
  digitalWrite(enablePin, HIGH);
}

void tuerZu() {
  digitalWrite(enablePin, LOW);
  stepper.moveTo(-30000);
  while (digitalRead(Zu)) {
    stepper.run();
  }
  digitalWrite(enablePin, HIGH);
  digitalWrite(enablePin, LOW);
  stepper.moveTo(stepper.currentPosition() + 80);
  stepper.runToPosition();
  digitalWrite(enablePin, HIGH);
}

void setup() {
  Serial.begin(9600);

  // PINMODUS des STEPPERS Nema 17 festlegen
  pinMode(enablePin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);

  // PINMODUS für Pullup festlegen
  pinMode(Auf, INPUT_PULLUP);  // Tür auf
  pinMode(Zu, INPUT_PULLUP);   // Tür zu

  // Stepper konfigurieren und aktivieren
  digitalWrite(enablePin, LOW);   // Treiber aktivieren
  stepper.setMaxSpeed(1000);      // Maximale Geschwindigkeit
  stepper.setAcceleration(2500);  // Beschleunigung
}

void loop() {
  for (int i = 0; i < 2; i++) {
    tuerZu();
    delay(2000);
    long startPosition = stepper.currentPosition();
    tuerAuf();
    delay(2000);
    long endPosition = stepper.currentPosition();
    steps[i] = abs(endPosition - startPosition);
    totalSteps += steps[i];
    Serial.print("Durchlauf ");
    Serial.print(i + 1);
    Serial.print(": ");
    Serial.println(steps[i]);
  }

  long averageSteps = totalSteps / 2;
  Serial.print("Durchschnittliche Schritte: ");
  Serial.println(averageSteps);

  // Reset für nächsten Durchlauf
  totalSteps = 0;
  delay(5000);  // Pause vor dem nächsten Zyklus

  // ########################################################################################
  tuerZu();
  digitalWrite(enablePin, LOW);
  stepper.setMaxSpeed(500);

  // Schritte vor dem Bewegen speichern
  long startPosition = stepper.currentPosition();

  stepper.moveTo(averageSteps * 0.5);
  while (stepper.distanceToGo() != 0) {
    stepper.run();
  }

  // Schritte nach dem Bewegen speichern
  long endPosition = stepper.currentPosition();

  // Zurückgelegte Schritte berechnen und ausgeben
  long stepsMoved = endPosition - startPosition;
  Serial.print("Zurückgelegte Schritte: ");
  Serial.println(stepsMoved);

  digitalWrite(enablePin, HIGH);
  digitalWrite(enablePin, LOW);
  stepper.moveTo(stepper.currentPosition() - 50);
  stepper.runToPosition();
  digitalWrite(enablePin, HIGH);
}

Die Ausgabe auf dem ser. Monitor zeigt aber erhebliche Diskrepanz:

17:03:03.461 -> Durchlauf 1: 28141

17:04:07.262 -> Durchlauf 2: 28154

17:04:07.262 -> Durchschnittliche Schritte: 28147

17:05:46.545 -> Zurückgelegte Schritte: 31829

17:07:47.454 -> Durchlauf 1: 28288

averageSteps * 0.5 sollte doch eigentlich etwa 14.000 sein?

Steppertreiber TB6600:

16 | 3200 OFF OFF ON

2A

Wo liegt das Problem/ der Fehler?

Moin @Eibenger,

möglicherweise liegt Dein Problem darin, dass

  • stepper.moveTo(averageSteps*0.5);

nicht averageSteps*0.5 Schritte sondern die Position averageSteps*0.5 vorgibt?

Probier es doch mal mit

  long startPosition = stepper.currentPosition();
  stepper.moveTo(startPosition+averageSteps*0.5);

ec2021

Über dein Schrittproblem kann ich Dir nichts sagen.

NEMA 17 sagt nichts über die elektrischen Daten aus.
Darum kann niemand Dir sagen ob 2A die richitige Einstellung für den unbekannten Motor ist.
Auch sagst Du nichts über die Versorgungsspannung für den Motor.

Das ist nicht der Grund Deines Problems aber möglicherweise ein weiteres Problem.

Grüße Uwe

wenn man Enable ausmacht, kann Motor frei bewegt werden. vermulich fliegt er weiter nach der Bewegung oder wird mit eigenem Kabel zurück gezogen

Das ist ein Unterschied von 13 Schritten, macht bei 1000 Schritten/Sek einen Zeitunterschied von 13ms. Bist Du sicher, das deine Endschalter so genau reproduzierbar reagieren?

So sollte man Accelstepper nicht nutzen. Du ziehst im sozusagen den Boden unter den Füssen weg, und die Beschleunigungs- und Bremsrampe funktioniert nicht. Dann brauchst Du auch erst garnicht mit Beschleunigung und Bremsen fahren.

Wie dann? Die Endschalter sind von der verlängerten Achse eines ausgedienten 3D Druckers ENDER, haben bis zuletzt ihren Dienst akkurat getan.
Für mein anderes Projekt habe ich deine Hilfestellungen und konkreten Codeschnipsel zu den MobaTools implementiert. Mit den MobaTools funktioniert es auch ganz gut.
Jetzt will ich in einem anderen Projekt meine bescheidenen Kenntnisse zur AccelStepper Lib. anwenden. Die Differenz ist irrelevant, es kommt hier nicht so sehr auf das exakte Ergebnis an, sondern meine Frage nach der Diskrepanz zu den gemessenen Werten und der falschen Interpretation zu * stepper.moveTo(averageSteps*0.5);
[ec2021] hat es auf den Punkt gebracht, mein Fehler!

Damit wäre die Frage beantwortet.

Dann wäre es aber auch richtig, den Beitrag von @ec2021 als Lösung zu markieren...

1 Like

Mit den Endschaltern hat das nichts zu tun, es geht um stepper.run().

Dann solltest Du die etwas aufpolieren :slightly_smiling_face: :joy:

stepper.run() ist eine Funktion die man immer und so oft wie möglich aufrufen sollte, wenn man mit Positionierung und Beschleunigung arbeiten will. Und zwar unabhängig davon ob der Stepper gerade drehen soll oder nicht. Sonst funktioniert das alles nicht sauber. Die Bewegung steuert man dann mit stepper.move(), stepper.movTo() oder stepper.stop() .
Ohne Positionierung und Beschleunigen ist stepper.runSpeed() richtig. Das ruft man dann nur auf, wenn der Motor sich drehen soll ( dann aber auch so oft wie möglich ). Da machen dann aber move, moveTo oder stop keinen SInn.

Das wichtigste Faktum zu AccelStepper ist:
es gibt blockierende Funktionen
es gibt nicht blockierende Funktionen die aber zwingend erforderlich machen dass man stepper.run() schneller = öfter aufruft als die höchste auftretende Schrittfrequenz

Der große Vorteil der MobaTools ist, dass die Schrittimpulse durch einen Timer-Interrupt erzeugt werden. Nur deshalb kann sich das restliche Programm Zeit lassen.

Nicht blockierende AccelStepper-functions erzwingen eine sehr kurze loop()-Durchlaufzeit