Arduino Uno & Nema 23 Schrittmitor mit Arduino Motor Shield - Drehzahl-Problem

Hallo liebes Arduino-Forum,

meine Hardware besteht aus folgenden Komponenten:

Das unten aufgeführte Script ermöglicht einen Betrieb des Schrittmotors mit 250 U/min. Sowohl über Taster (händisch) als auch über Serielle Schnittstelle aus einem anderen Programm heraus (hier nur für den Handbetrieb eingekürzt).

Um den kleinsten möglichen Schritt (1,8°) des Motors in einen präziseren Weg an der Linearachse umzusetzen, soll demnächst ein passendes zweistufiges Planetengetriebe mit 1:50 vorgeschaltet werden.

Damit die Anwendung dann nicht extrem langsam wird, möchte ich den Schrittmotor schneller laufen lassen (laut Datenblatt max. 3000 U/min möglich bei geringem Abtriebsmoment).

Das unten aufgeführte Script nutze ich um die 250 U/min zu erreichen. Die Drehzahl wird "sanft" über eine Rampe angefahren.

Mein Problem:
Ausgebauter Motor - Leerlauf:

  • Erreicht der Motor die 250 U/min vibriert er teils spürbar aber er läuft und funktiniert auch an der Spindel
  • Bei Zieldrehzahl über 300 U/min läuft der Motor zwar an, bleibt ab ca. 300 U/min stehen und vibriert nur noch
  • Bei Zieldrehzahl 2000 U/min läuft der Motor an und bleibt bei ca. 300 U/min stehen und vibriert nur noch - man kann ihn durch schütteln dann jedoch in Gang bringen (mit 2000 U/min)

Frage:

  • Auf dem Motor sind aufgedruckt 2.0 A und 3.4 V - Der Blick ins Datenblatt verrät, dass scheinbar 48 V und 2,8 A notwendig sind. Habe ich das korrekt verstanden ?
    Ist es somit nur Glück, dass der Motor in dem aktuellen Anwendungsfall mit 250 U/min funktioniert?
  • Wäre der TB6600 Stepper Motor Driver (max. 42 V - aber keine 48V ) statt dem Motor Schield Rev3 mit 12 V geeignet das Problem zu lösen, oder muss der Treiber noch "größer" sein? Ich brauche kaum Drehmoment, sondern nur Präzisison
  • Oder liegt die Ursache der geringen erreichbaren Drehzahl in meinem Script?

Script:

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
Stepper myStepper(stepsPerRevolution, 12,13);     

// give the motor control pins names:
const int pwmA = 3;
const int pwmB = 11;
const int brakeA = 9;
const int brakeB = 8;
const int dirA = 12;
const int dirB = 13;
const int betriebsart = 2;
const int stepvor = 4;
const int steprueck = 5;
const int vor = 6;
const int rueck = 7;
String serialInput = "";
long x = 0;
//int speed = 2200;  //upm - geht im Leerlauf unb wenn detr Motor zum Anlaufen leicht um die Hochachse geschüttelt wird
int speed = 250;  //upm
int rampSpeed = 60;
long letzterDurchlauf = 0;
long letzteFahrt = 0;
int strom;
int stepsToDo = 0;
int drehrichtung;

void setup() {
Serial.begin(9600);
// set the PWM and brake pins so that the direction pins  // can be used to control the motor:
pinMode(pwmA, OUTPUT);
pinMode(pwmB, OUTPUT);
pinMode(brakeA, OUTPUT);
pinMode(brakeB, OUTPUT);
digitalWrite(pwmA, HIGH);
digitalWrite(pwmB, HIGH);
digitalWrite(brakeA, LOW);
digitalWrite(brakeB, LOW);
pinMode(betriebsart, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
digitalWrite(betriebsart, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);

// initialize the serial port:
Serial.begin(9600);
Serial.setTimeout(100);
// set the motor speed (for multiple steps only):
myStepper.setSpeed(speed);

// power 0%
analogWrite(3,0); 
analogWrite(11,0);
Serial.println("setup complete");
} // end setup

void loop() {

  if (digitalRead(betriebsart) == LOW) handbetrieb();

//  wenn fahrt lange her, strom wieder ausstellen

  if ((millis() - letzteFahrt ) > 3000) {
      analogWrite(3,0); 
      analogWrite(11,0);
       // myStepper.setSpeed(speed);
    delay(5); 
    x=millis();
   rampSpeed = 30;
  }
} 

void handbetrieb() {

  // Button on pin 6 = rückwärts drehen
  while(digitalRead(6) == LOW){
    strom = stromAnpassung(rampSpeed);
    analogWrite(3,strom); 
    analogWrite(11,strom);
    myStepper.setSpeed(rampSpeed);
    myStepper.step(-1);
    if (rampSpeed < speed){
    rampSpeed++;
    }
    }// end bu6  

  // Button on pin 7 = rückwärts drehen
  while(digitalRead(7) == LOW){
    strom = stromAnpassung(rampSpeed);
    analogWrite(3,strom); 
    analogWrite(11,strom);
    myStepper.setSpeed(rampSpeed);
    myStepper.step(1);
    if (rampSpeed < speed){
      rampSpeed++;
    }
   
    }// end bu7

  // speed zurück setzen
  myStepper.setSpeed(speed);
}  // end handbetrieb

int stromAnpassung(int upm){
  int strom;
  strom = upm * 0.637 + 160;
  if (strom > 255) strom = 255;
  return strom;
}

Dank im Voraus

Toni

Dieses Motorshield (mit dem uralten L298) ist absolut ungeeignet für deinen Schrittmotor. Der ist für einen Stromtreiber ausgelegt. Der TB6600 wäre da die wesentlich bessere Wahl (Es gibt aber auch noch andere Alternativen - je nach Anforderung ). Grundsätzlich gilt für einen Stromtreiber: je höher die Spannung ( natürlich innerhalb seiner Spezifikation), desto besser das Verhalten bei höheren Drehzahlen. Die Kurven im Datenblatt zeigen das Drehmoment über die Drehzahl für so einen Stromtreiber bei 24V und bei 48V. Die siehst, dass bei 24V das Drehmoment mit der Drehzahl deutlich stärker abfällt als bei 48V. Mit 12V wird der Effekt nochmal wesentlich stärker sein.

Dein Programm sieht auch sehr seltsam aus - da funktioniert einiges nicht mir einem Stepper. Manches sieht eher so aus, als wolltest Du einen DC-Motor ansteuern.
Z.B.:

    strom = stromAnpassung(rampSpeed);
    analogWrite(3,strom); 
    analogWrite(11,strom);

Du kannst bei einem Stepper die Drehzahl nicht mit dem Strom regeln.
Hast Du den Sketch selbst geschrieben oder wo ist der her?

Die Stepper.h ist für deinen Zweck auch eher nicht geeignet. Verwende eine Lib, die das Beschleunigen/Abbremsen selbst verwaltet. Bis 750U/Min ( ohne Microsteps) könntest Du meine MobaTools verwenden ( bei nur 1-2 Steppern evtl auch bis 1500U/Min).

Hallo MicroBahner,

dann würde ich es zunächst mit einem anderen Stromtreiber versuchen.
Frage dazu:
ist der TB6600 ausreichend, da er nur mit max. 42V Betriebsspannung angegeben ist?
Was wären die von angesprochenen Alternativen?

48V sind ja kein 'Muss' für deinen Stepper.

Die 'professionellere' Alternative zum TB6600 wäre z.B. der DM542T von StepperOnline. Den kannst Du auch mit 48V betreiben. (Der Link ist nur ein Beispiel für die HW, als Händler kenn ich den nicht).

Außerdem gäbe es noch kleine Treiber-Boards, z.B. DRV8825 oder die TMC-Treiber. Die sind mit deinem Stepper aber schon ziemlich an der Belastungsgrenze.

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Das Skript stammt nicht von mir. Ich versuche es zu verstehen und anzupassen. Über das Thema mit der drehzahlabhängigen Stromanpassung bin ich auch schon gestolpert. Es funktioniert auch ohne diese.

Dann werde ich mal den DM542T beschaffen und damit mein Glück versuchen. Ich halte euch auf dem Laufenden.

Ganz ohne Stromanpassung würde dein Stepper aber viel zu viel Strom ziehen. Der ist nicht dafür ausgelegt, direkt an 12V betrieben zu werden. Aber man kann nicht einfach die PWM drehzahlabhängig ändern. Es geht darum, den Strom über die Drehzahl konstant zu halten - und das ist dann Aufgabe des Stromtreibers.

2000 U/Min ist schon recht herausfordernd für den UNO R3. Es bedeutet ( Ohne Mikroschritte! ) 6666 Steps/Sek. Das kann weder die AccelStepper noch meine MobaTools. Wenn das dein Ziel ist, solltest Du über einen schnelleren Prozessor nachdenken. Die Werte für die MobaTools sind z.B.:
UNO R4: 12000 Steps/Sek = 3600 U/Min
ESP32: 30000 Steps/Sek = 9000 U/Min
Wobei der Motor das natürlich überhaupt können muss. Stepper sind generell eher keine Motore für hohe Drehzahlen. Wenn Du Mikrosteps einsetzt, reduzieren sich die Werte für U/Min entsprechend.

Ich werden die DM542T beschaffen + geeignetes Netzteil.
Laut Datenblatt vom Motor sollten max. 3000 U/min möglich sein. Ich verwende ein 1:50 untersetztes Planetengetriebe für eine feinfühligere Postionierung - das Antriebsmoment sollte sehr niedrig sein.

Noch eine Frage zur Drehzahl bzw. zum Arduino UNO R3:

Ich habe verstanden, dass der vorhandene UNO R3 die Ansteuerung bei 3000 U/min rechentechnisch nicht schafft und deshalb besser der UNO R4 besorgt werden soll.

Ist das korrekt? Dann würde ich diesen auch gleich beschaffen.

Wenn die hohe Drehzahl mit der Stepper.h - Lib nicht funzt und auch die MobaTools bei 750 U/Min endet, womit wäre es dann erreichbar?

Das gilt zumindest für die MobaTools. Der R4 hat auf jeden Fall den Vorteil, dass er - wie der R3 - ein 5V Prozessor ist. Eigentlich alle anderen schnelleren Prozessoren sind 3,3V Prozessoren. Da muss man dann bei der HW etwas aufpassen...

Es gibt noch die fastAccelStepper. Die kenne ich aber nicht näher. Es kommt halt auch immer darauf an, was die Lib können soll, und wie flexibel sie sein soll. Die MobaTools sind z.B. darauf ausgelegt, dass Du zu jeder Zeit alle Parameter (Zielposition, Geschwindigkeit, Rampenlänge ) ändern kannst, und der Stepper sofort darauf reagiert. Das kostet zusätzliche Rechenzeit, die die maximale Steprate begrenzt.
[Edit] Außerdem sind die MobaTools darauf ausgelegt, dass das alles auch mit 6 Steppern gleichzeitig - aber unabhängig voneinander - funktioniert. Wenn Du weniger hast kann man deshalb beim R3 etwas 'tunen' und kommt dann auf 1500 U/Min (5000 Steps/sec). Aber das reicht für dich ja auch noch nicht.

Mit dem DM542 (V4) Treiber, einem 32 V-Netzteil (1,5A) und dem Arduino UNO R3 läuft der Schrittmotor sicher bis 1890 U/min (6300 Steps/Sek.) auch im eingebauten Zustand am Getriebe mit Last.
Das 48 V-Netzteil mit bis zu 3.7 A und der Arduino UNO R4 sind leider noch nicht da.

Ich werde berichten.

Anbei der aktuelle Code:

#include <AccelStepper.h>

const int buttonPin7 = 7; // Pin, an dem der Taster angeschlossen ist
const int buttonPin6 = 6; // Pin, an dem der Taster angeschlossen ist
const int buttonPin5 = 5; // Pin, an dem der Taster angeschlossen ist
const int buttonPin4 = 4; // Pin, an dem der Taster angeschlossen ist
int rampSpeed = 30;
long x = 0;
int speed = 6300; //3200;  //Steps per Second

AccelStepper stepper(1, 13, 12); // (Step, Dir) - Step-Pin: 13, Dir-Pin: 12

void setup() {
  Serial.begin(9600); // initialize serial communication
  pinMode(buttonPin7, INPUT_PULLUP); // Tasterpin als Input mit Pull-up-Widerstand
  pinMode(buttonPin6, INPUT_PULLUP); // Tasterpin als Input mit Pull-up-Widerstand
  pinMode(buttonPin5, INPUT_PULLUP); // Tasterpin als Input mit Pull-up-Widerstand
  pinMode(buttonPin4, INPUT_PULLUP); // Tasterpin als Input mit Pull-up-Widerstand
  stepper.setMaxSpeed(speed); // Setze die maximale Geschwindigkeit in Schritten pro Minute (500 Umdrehungen pro Sekunde)
  //stepper.setAcceleration(100); // Setze die Beschleunigung in Schritten pro Sekunde pro Sekunde
}

void loop() {
  // Prüfe, ob der Taster gedrückt ist
  if (digitalRead(buttonPin7) == LOW) {
    // Dreh den Motor kontinuierlich mit maximaler Geschwindigkeit
    while (digitalRead(buttonPin7) == LOW) {
      if (rampSpeed < speed) {
        rampSpeed++;
      }
      stepper.setSpeed(rampSpeed);
      stepper.runSpeed(); // Aktualisiere die Geschwindigkeit
    }

    // Sanft anhalten
    while (rampSpeed > 0) {
      rampSpeed--;
      stepper.setSpeed(rampSpeed);
      stepper.runSpeed(); // Aktualisiere die Geschwindigkeit
    }

    stepper.stop(); // Motor anhalten, wenn der Taster losgelassen wird
    delay(300); // Optional: Warte für 1 Sekunde (kann angepasst werden)
    rampSpeed = 30; // Zurücksetzen der Startgeschwindigkeit
  }

 if (digitalRead(buttonPin6) == LOW) {
    // Dreh den Motor kontinuierlich mit maximaler Geschwindigkeit rückwärts
    while (digitalRead(buttonPin6) == LOW) {
      if (rampSpeed < speed) {
        rampSpeed++;
      }
      stepper.setSpeed(-rampSpeed);
      stepper.runSpeed(); // Aktualisiere die Geschwindigkeit
    }

    // Sanft anhalten
    while (rampSpeed > 0) {
      rampSpeed--;
      stepper.setSpeed(-rampSpeed);
      stepper.runSpeed(); // Aktualisiere die Geschwindigkeit
    }

    stepper.stop(); // Motor anhalten, wenn der Taster losgelassen wird
    delay(300); // Optional: Warte für 1 Sekunde (kann angepasst werden)
    rampSpeed = 30; // Zurücksetzen der Startgeschwindigkeit
  }

if (digitalRead(buttonPin5) == LOW) { //Motor macht einen Step rückwärts
      stepper.move(-1);
      stepper.runSpeedToPosition();
      delay(250);  
  }

if (digitalRead(buttonPin4) == LOW) { //Motor macht einen Step vorwärts
      stepper.move(1);
      stepper.runSpeedToPosition();
      delay(250);  
  }
}

Mit dem Arduino UNO R4 und dem passenden 48V - Netzteil mit ausreichender Stromlieferfähigkeit sind problemlos 9500Steps möglich und der Motor dreht damit knapp 3000 U/min.

Danke für den Support!

Werde mich nun weiter mit der accelstepper - Bibliothek bechäftigen und versuchen den Stepper per serieller Schnittstelle zu steurn und zu regeln.

Auf dem R4 schaffen die MobaTools 12000 Steps/sek. Je nachdem was Du sonst noch alles machen willst, könnten die MobaTools Vorteile haben, weil Du die Schrittimpulse nicht direkt im loop() erzeugen musst.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.