AccelStepper - Probleme mit Schrittmotor

Hallo Leute,

ich wollte - wie viele andere bereits - einen Schrittmotor mit der Accelstepper Bibliothek laufen lassen.
Dazu habe ich mich im Forum umgesehen und geschaut wie der Code aussehen könnte.

Ich benutze einen Schrittmotor der 24V und 1A/Phase braucht und eine Basisschrittweite von 1,8° hat. Als Motortreiber habe ich einen A4988. Zunächst habe ich die Spannung am A4988 eingestellt um den Strom korrekt zu begrenzen. Die Spannung habe ich auf 0,8V gestellt (Vref = 1A * 8 * 0,1 Ohm). Der Rs Widerstand auf meinem Board ist mit R100 (100 mOhm angegeben).

Nun zu meinem Code:

#include <AccelStepper.h>

AccelStepper Stepper1(1,7,6); //pin 7 = step, pin 6 = direction, 1 is the "external driver" mode (A4988)

const int MS1 = 8; 
const int MS2 = 9; 
const int MS3 = 10; 

void setup() 
{
  pinMode(MS1,OUTPUT);
  pinMode(MS2,OUTPUT);
  pinMode(MS3,OUTPUT);
  Stepper1.setMaxSpeed(200); //set max speed the motor will turn (steps/second)
  Stepper1.setAcceleration(200); //set acceleration (steps/second^2)
}

void loop() 
{
      digitalWrite(MS1,LOW); // defines the step width
      digitalWrite(MS2,LOW); // 
      digitalWrite(MS3,LOW); // 3x LOW = 1.8°
      Stepper1.move(200); //set how many steps the stepper moves next. 200 steps * 1.8° = 360°
      delay(1000);
 
  Stepper1.run(); //run the stepper. this has to be done over and over again to continously move the stepper
}

Anhand des oben beschriebenen Codes hätte ich nun erwartet, dass der Motor eine volle Umdrehung innerhalb einer Sekunde macht, dann eine Sekunde pausiert und dann wieder eine Umdrehung, usw…

Das Problem nur ist, dass der Motor genau so nicht verfährt. Stattdessen macht er ruckartig kleine Schritte (schätzungsweise 5° oder sowas, scheint zu ruckartig für meinen optischen Encoder zu sein).

Ich habe bereits eine Variation der Parameter vorgenommen, aber ein wirklich brauchbares Ergebnisse erziele ich leider nicht.

Benutze ich hingegen einen Code mit delayMicroseconds…

      for(int x = 0; x < 200; x++)         
      {
          digitalWrite(stepPin,HIGH); 
          delayMicroseconds(2000); 
          digitalWrite(stepPin,LOW); 
          delayMicroseconds(2000); 
      }

dann läuft der Motor seine Umdrehungen. Nur leider nicht genau genug. Deshalb habe ich im Internet gelesen, dass AccelStepper wohl genauer sein soll.

Hat jemand Tipps und Ideen?

Vielen Dank.

der A4988 ist für diesen Motor nicht geeignet.
Grüße Uwe

Hallo und danke für die Antwort.

Wieso ist der A4988 denn nicht geeignet?

Lt. Datenblatt liefert der A4988 1A/Phase konstant und bis 2A/Phase bei guter Kühlung.
Die nutzbare Motorspannung wird mit 8-35V angegeben.

Ich benutze einen Schrittmotor der 24V und 1A/Phase

Die Daten sind nicht ausreichend(oder zu falsch), um das beurteilen zu können.

Ein 2 bis 3V Motor wäre genau das richtige für den Treiber.
Der Treiber darf dann durchaus mit 24V versorgt werden.

Das ist der eingesetzte Motor:

https://de.rs-online.com/web/p/schrittmotoren/8787761/

Gut!
Es ist also ein 4.1V Motor!
Nix 24V
(siehe letzte Seite im Datenblatt)
Und Ausrechnen kann man es sich auch: 4,1ohm*1a = 4,1v

Also, dann sollte er doch zu deinem Treiberbaustein passen.

Welches Netzteil verwendest du?
Genügend großer Stützkondensator vorgesehen?

Okay!

Wieso steht denn dann da 24V? Kannst du mir den Unterschied erklären? Bin noch “neu”.

Als Kondensator ist ein 100µF C zwischen Vmot und GND zwischengeschaltet. Als Netzteil habe ich ein "Manson Switching Mode Power Supply 1-35VDC 10A HCS-3202) zur Verfügung gestellt bekommen.

Den Code habe ich in der Zwischenzeit auch angepasst:

#include <AccelStepper.h>

AccelStepper Stepper1(1,7,6); //pin 7 = step, pin 6 = direction, 1 is the "external driver" mode (A4988)

const int MS1 = 8; 
const int MS2 = 9; 
const int MS3 = 10;
int pos = 3200;

void setup() 
{
  Serial.begin(9600);
  pinMode(MS1,OUTPUT);
  pinMode(MS2,OUTPUT);
  pinMode(MS3,OUTPUT);
  digitalWrite(MS1,HIGH); // defines the step width
  digitalWrite(MS2,HIGH); // 
  digitalWrite(MS3,HIGH); // 3x HIGH = 0.1125°
  
  Stepper1.setMaxSpeed(1000); //set max speed the motor will turn (steps/second) 
  Stepper1.setAcceleration(3000); //set acceleration (steps/second^2)
}

void loop() 
{

      if (Stepper1.distanceToGo() == 0)
      {
      //Stepper1.moveTo(pos); //set how many steps the stepper moves next
      Stepper1.move(pos); //set how many steps the stepper moves next
      delay(2000);
      }
      Stepper1.run(); //run the stepper. this has to be done over and over again to continously move the stepper
      
      int pos = pos+3200;
}

Dieser Code funktioniert. Der Motor dreht sich. J
edoch auch ungenau. Lt. meinem Encoder ca. 5° Versatz pro Umdrehung. Optisch sieht man ebenfalls, dass der Motor nicht immer an der selben Stelle stoppt.

Wieso steht denn dann da 24V? Kannst du mir den Unterschied erklären? Bin noch “neu”.

Ich verstehe das als Empfehlung für den Treiber, damit man da ein einigermaßen hohes Drehmoment raus bekommt.

Die 24V sind dem Datenblatt nicht unmittelbar zu entnehmen.
Mit dem passenden Treiber, kann man den Motor sicherlich auch an 48V stabil betreiben.

Habe dein Programm mal leicht umgebaut.
(aber nicht testen können)

#include <AccelStepper.h>

AccelStepper Stepper1(AccelStepper::DRIVER,7,6); //pin 7 = step, pin 6 = direction, 1 is the "external driver" mode (A4988)

const byte MS1 = 8; 
const byte MS2 = 9; 
const byte MS3 = 10;
long pos = 0;
unsigned long zeitmerker;

void setup() 
{
  Serial.begin(9600);
  pinMode(MS1,OUTPUT);
  pinMode(MS2,OUTPUT);
  pinMode(MS3,OUTPUT);
  digitalWrite(MS1,HIGH); // defines the step width
  digitalWrite(MS2,HIGH); // 
  digitalWrite(MS3,HIGH); // 3x HIGH = 0.1125°
  
  Stepper1.setMaxSpeed(1000); //set max speed the motor will turn (steps/second) //good 1000
  Stepper1.setAcceleration(3000); //set acceleration (steps/second^2) /good 3000
  zeitmerker = millis();
}

void loop() 
{
     if(millis()-zeitmerker > 10000)
     {
      zeitmerker = millis();
      pos += 3200;
      Stepper1.move(pos);
     }

      Stepper1.run(); //run the stepper. this has to be done over and over again to continously move the stepper
      

}

Wallibo:
Okay!

Wieso steht denn dann da 24V? Kannst du mir den Unterschied erklären? Bin noch "neu".

Ok der Treiber paßt mit dem Motor zusammen.

Der A4988 ist ein Microstep-Stromtreiber. Er begrenzt den Strom der Wicklungen auf den eingestellten Wert indem der Strom unterbrochen wird sobald der Wert erreicht wird und dann nach kurzer Zeitwieder eingeschaltet wird. usw.

Damit der Strom möglichst wenig von der Wicklungsinduktivität begrenzt wird wird der Treiber mit einer viel höheren Spannung versorgt. 24V bei einem 4,1V Motor ist eine mögliche Wahl.

Das Netzteil hat auch genügend Leistung für diesen Motor.

Ich nehme mal an der Motor läuft im Leerlauf.

AccelStepper Stepper1(1,7,6);

Halte Pin 1 für die serielle Schnittstelle frei.

Also weiß ich nicht wo die Schritte verloren gehen.

Was ist der "external driver" mode? An welches Pin des A4988 hast Du das angeschlossen?

Grüße Uwe

Ja, die 1 ist da unglücklich aufgehoben.
Besser/klarer wäre:

 AccelStepper Stepper1(AccelStepper::DRIVER,7,6);

Der AccelStepper bietet da halt verschiedene Treibermodelle an.
Und die 1 ist eigentlich an der Stelle goldrichtig.
Nur ebend etwas verwirrend wenn man die Methodensignatur nicht vor sich hat.

Hallo und danke nochmal für deinen Code.

Ich habe den Code heute ausprobiert - dazu habe ich auch gleich eine Frage.

Es ist so, dass die Pausen zwischen den Umdrehungen immer kürzer und die Anzahl der Umdrehungen immer höher wird, bis er letztlich bei diesem Code einfach permanent dreht.

Wie habe ich deinen Code anzupassen, damit er immer nur eine Umdrehung macht und der zeitliche Abstand (ca. 1 Sek.) gleich bleibt?

Danke