Ansteuerung Schrittmotor mit Endstufe

Hallo zusammen,

ich steh gerade ganz am Anfang bei dem Programmieren des Arduino UNO`s und bräuchte etwas Hilfe.

Und zwar würde ich gern ein Schrittmotor NEMA17 über eine Endstufe (Microstep-Driver 4A) antreiben.

Da ich hier neu bin möchte ich mich jetzt schon bei allen bedanken die mir irgendwie weiterhelfen. :slight_smile:

Anforderung:

taster1=7; //Taster1 auf Pin7 Motor dreht “Hoch”
taster2=8; //Taster2 auf Pin8 Motor dreht “Runter”
taster3=9; //Taster3 auf Pin9 Motor dreht kurz “0,5mm Hoch”
taster4=10; //Taster4 auf Pin9 Motor dreht kurz “0,5mm Runter”
poti = A0; //Poti fuer Geschwindigkeit bei Taster 1 oder 2

Endstufe:
aktuell ist diese auf Pulse/Rev = “200” und MicroStep “1” eingestellt.

Problem:
Der Schrittmotor läuft viel zu schnell bzw. dreht überhaupt nicht.
Kann mir hier vll. jemand helfen um eine Basis-Programmierung zu erstellen die ich dann weiter modifizieren kann?

Info:
Über den Schrittmotor soll eine Spindel angetrieben werden, welche dann eine Oberfräse nach oben oder unten bewegt.
Gesteuert werden soll dies über die Taster “rauf” bzw. “runter” bzw. 0,5mm “rauf” bzw. 0,5mm “runter”
Bei “dauer” rauf-runter sollte noch über ein poti die Geschwindigkeit eingestellt werden können.

Vielen Dank

int Index;

int taster1 = 7;                                     //Taster1 auf Pin7  Dauer Hoch
int taster2 = 8;                                     //Taster2 auf Pin8   Dauer Runter
int taster3 = 9;                                     //Taster3 auf Pin9   0,5mm Hoch
int taster4 = 10;                                    //Taster4 auf Pin9   0,5mm Runter
int poti = A0;                                       //Poti fuer Geschwindigkeit
int tasterstatus = 0;                                //Das Wort „tasterstatus“=0
int vspeed = 0;                                      //Pulse Delay period

void setup()
{
  pinMode(6, OUTPUT); //Enable
  pinMode(5, OUTPUT); //Puls
  pinMode(4, OUTPUT); //Direction

  digitalWrite(6, LOW);
}

void loop()

//Dauer Hoch
{
  tasterstatus = digitalRead(taster1);                 //„HIGH“ = 5Volt oder „LOW“ = 0Volt.

  vspeed = map((analogRead(poti)), 0, 1023, 10, 200);  //map digital value from (0, 1023) to (2, 1000)
  //min speed =2 and max speed =500 rpm
  if (tasterstatus == HIGH)                            //Taster1 (auf)
  {
    digitalWrite(4, HIGH);                             //Richtung
    digitalWrite(5, HIGH);
    delayMicroseconds(vspeed);
    digitalWrite(5, LOW);
    delayMicroseconds(vspeed);
  }
  else
  {
  }

  //Dauer Runter
  {
    tasterstatus = digitalRead(taster2);                 //„HIGH“ = 5Volt oder „LOW“ = 0Volt.

    vspeed = map((analogRead(poti)), 0, 1023, 10, 200);  //map digital value from (0, 1023) to (2, 1000)
    //min speed =2 and max speed =500 rpm
    if (tasterstatus == HIGH)                            //Taster1 (auf)
    {
      digitalWrite(4, LOW);                             //Richtung
      digitalWrite(5, HIGH);
      delayMicroseconds(vspeed);
      digitalWrite(5, LOW);
      delayMicroseconds(vspeed);
    }
    else
    {
    }
  }

  //0,5mm Hoch
  {
    tasterstatus = digitalRead(taster3);                  //„HIGH“ = 5Volt oder „LOW“ = 0Volt.
    if (tasterstatus == HIGH)                             //Taster3 (auf)
      for (Index = 0; Index < 400; Index++)                //Anzahl Steps (3200=>1.Umdrehung)
      {
        digitalWrite(4, LOW);                                 //Richtung
        digitalWrite(5, HIGH);
        delayMicroseconds(1000);                       //Geschwindigkeit
        digitalWrite(5, LOW);
        delayMicroseconds(1000);                       //Geschwindigkeit
      }
    else
    {
    }
  }



  //0,5mm Runter
  {
    tasterstatus = digitalRead(taster4);                //„HIGH“ = 5Volt oder „LOW“ = 0Volt.
    if (tasterstatus == HIGH)                           //Taster4 (auf)
      for (Index = 0; Index < 400; Index++)               //Anzahl Steps (3200=>1.Umdrehung)
      {
        digitalWrite(4, HIGH);                          //Richtung
        digitalWrite(5, HIGH);
        delayMicroseconds(1000);                        //Geschwindigkeit
        digitalWrite(5, LOW);
        delayMicroseconds(1000);                      //Geschwindigkeit
      }
    else
    {
    }
  }


}

Schrittmotor_mit_Poti_20200419.ino.ino (2.95 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Außerdem formatiere bitte den Code ordentlich (+T in der IDE hilft Dir dabei).

Gruß Tommy

Damit man dir besser helfen kann, solltes Du Links auf die von dir verwendeten Komponenten ( Netzteil, Treiber und Motor ) posten. Hast Du den Strom am Treiber passend zu deinem Motor eingestellt?

Was die Geschwindigkeit angeht: Wie kommst Du auf diese Berechnungen:

vspeed = map((analogRead(poti)),0,1023,10,200);      //map digital value from (0, 1023) to (2, 1000)
                                                     //min speed =2 and max speed =500 rpm

10 bzw. 200 µsec sind viel zu klein, da bekommst Du niemals die gewünschten rpm raus.

Für die Schrittmotoransteuerung ist es auch einfacher eine entsprechende Lib, die auch Anfahr- und Bremsrampen beherrscht, zu verwenden. Z.B. die AccelStepper oder meine MobaTools.

P.S. Stelle deinen Sketch bitte auch direkt hier im Post in Code-Tags ( Das Symbol </> oben links im Editor ) ein und nicht als Attachment. Dann kann man den direkt sehen.

Die Codetags fehlen noch. Ohne die ist der Sketch schwerer zu lesen, und manchmal werden auch Codeteile von der Forumssoftware als Formatierungszeichen mißinterpretiert. Deshalb sind die Codetags so wichtig. Das geht auch noch nachträglich: Editiere deinen Post ( im Editor ), markiere den gesamten Code und drücke oben links auf den </> Button.

Und dann darfst Du auch die Fragen beantworten :wink:

Sorry, hat etwas länger gedauert.
Der Code sollte jetzt richtig angezeigt sein :slight_smile:

Die Werte habe ich von einem online Skript übernommen.
Leider kenne ich mich in der Materie noch nicht all zu gut aus :frowning:
Wie aufwendig ist es eine "AccelStepper" in dem Skript mit einzubauen?

Könntet ihr mir vll. Werte geben für einen Testlauf?
Ich würde Anfangs eher geringere Umdrehungen bevorzugen (vll. ca. 20U/min)

Endstufe:
TB6600 Einzelachse 4A CNC Schrittmotortreiber Controller 9~40V Für Motor Driver
https://www.ebay.de/itm/333371655819
Aktuell eingestellt auf Micro Step 1 Pulse/rev 200

Schrittmotor:
Stepper Motor Nema 17 Schrittmotor 59Ncm 2A 48mm 4-lead 1m Cable 17HS19-2004S1

Einstein-86:
Wie aufwendig ist es eine “AccelStepper” in dem Skript mit einzubauen?

Ich hab’s mal mit meinen MobaTools gemacht :wink:
Die Taster musst Du aber so anschliessen, dass sie gegen Gnd schalten - also zwischen den Eingangspin und Gnd verdrahten. Widerstände brauchst Du nicht.

#define MAX8BUTTONS // spart Speicher, da nur 4 Taster benötigt werden
#include <MobaTools.h>

//Stepper einrichten
MoToStepper myStepper( 200, STEPDIR );  // 200 Steps/ Umdrehung
const byte dirPin = 4;
const byte stepPin = 5;
const byte enaPin = 6;

// Taster einrichten ( die Taster müssen gegen Gnd schalten, keine Widerstände notwendig )
//Taster1 auf Pin7  Dauer Hoch
//Taster2 auf Pin8   Dauer Runter
//Taster3 auf Pin9   0,5mm Hoch
//Taster4 auf Pin10   0,5mm Runter
enum { Taster1, Taster2, Taster3, Taster4 } ; // Den Tasternamen die Indizes 0...4 zuordnen
const byte tasterPins[] = { 7, 8, 9, 10 };
MoToButtons taster( tasterPins, sizeof(tasterPins), 20, 500 );   // Flankenauswertung und Entprellung

MoToTimer speedIntervall;       // Zeitintervall zum Auslesen des Speedpotentiometers

const byte poti = A0;                                //Poti fuer Geschwindigkeit
int vspeed = 0;                                      //Steppergeschwindigkeit in U/min*10

void setup()
{
  //Serial.begin (115200);
  myStepper.attach( stepPin, dirPin );
  myStepper.attachEnable( enaPin, 10, LOW );        // Enable Pin aktivieren ( LOW=aktiv )
  myStepper.setSpeed( 200 );
  myStepper.setRampLen( 10 );                       // Rampenlänge 10 Steps bei 20U/min
}

void loop()
{
  taster.processButtons();          // Taster einlesen und bearbeiten

  // Speed alle 100ms neu einlesen und setzen
  if ( not speedIntervall.running() )
  { // 100ms sind abgelaufen
    speedIntervall.setTime( 100 );
    vspeed = map((analogRead(poti)), 0, 1023, 20, 5000);  //Poti mappen auf 2 ... 500 Umdr/Min
    //min speed =2 and max speed =500 rpm
    myStepper.setSpeed( vspeed );
  }

  //Dauer Hoch
  if (taster.pressed(Taster1) )
  { //Taster1 gedrückt (auf)
    //Serial.println("Taster1-gedr.");
    myStepper.rotate( 1 );          // Stepper dreht vorwärts
  }
  if ( taster.released(Taster1) )
  { //Taster1 losgelassen (auf)
    //Serial.println("Taster1-losg.");
    myStepper.rotate(0);             // Stepper stoppt
  }

  //Dauer Runter
  if (taster.pressed(Taster2) )
  { //Taster2 (runter)
    //Serial.println("Taster2-gedr.");
    myStepper.rotate( -1 );         // Stepper dreht rückwärts
  }
  if ( taster.released(Taster2) )
  { //Taster2 losgelassen (runter)
    //Serial.println("Taster2-losgel.");
    myStepper.rotate(0);            // Stepper stoppt
  }

  //0,5mm Hoch
  if (taster.pressed(Taster3) )
  { //Taster3 (auf) gedrückt
    //Serial.println("Taster3-gedr.");
    myStepper.doSteps(400);         // 400 Steps = 0,5mm vorwärts
  }

  //0,5mm Runter
  if (taster.pressed(Taster4) )
  { //Taster4 (runter) gedrückt
    //Serial.println("Taster4-gedr.");
    myStepper.doSteps(-400);        // 400 Steps = 0,5mm rückwärts
  }
}

Vielen Dank für das angepasste Skript.
Soweit funktioniert das Ganze auch :slight_smile:

Leider läuft der Schrittmotor immer noch relativ unsauber :frowning:
Also er "Ruckelt" und hat kaum Drehmoment.

Wo sollte ich anfangen zu optimieren?
Bei der Endstufe mit den Schritten?
(Mir wäre ein möglichst hohes Drehmoment wichtiger als eine hohe Geschwindigkeit)
Aktuell sind hier Micro Step 1 & Pulse/rev 200 einstellt.
Würde es was bringen wenn ich diese erhöhe?

Bei minimaler Last auf dem Steppmotor dreht dieser auch relativ schnell in die andere Richtung.
Normal?

Einstein-86:
Leider läuft der Schrittmotor immer noch relativ unsauber :frowning:

Könnte an falscher Stromeinstellung beim Treiber liegen. Wenn ich bei mir z.B. den Strom zu hoch einstelle, ruckelt der Motor auch und läuft unsauber.

Habe gerade noch etwas getestet, da ändert sich nichts, egal wie stark der Strom in der Endstufe eingestellt ist.
=> Netzteil ist mit 36V 2,8A verbaut.

Einstein-86:
egal wie stark der Strom in der Endstufe eingestellt ist.

Ein zu hoher Strom kann das Problem sein

Ich hab alle Stromstärken an der Endstufe ausprobiert (0,5A - 3A)
=> keine Veränderung

Du könntest es natürlich mal mit 1/2 oder 1/4 Step probieren. Dann hast Du aber auch entsprechend mehr Steps/Umdrehung, was Du im Sketch anpassen musst. Und die Maximaldrehzahl wird geringer.

Zeige bitte mal ein Schema, wie Du die Step (PUL) / Dir Leitungen des Motor-Treibers an den Arduino angeschlossen hast. Ich hatte da nämmlich bei meiner Schiebetür anfangs das gleiche Problem. der Stepper kam einfach nicht in die Gänge. Musste dann das PUL Signal Invertiert anschliessen, damit der Motor sauber und kraftvoll gelaufen ist. Allerdings hatte ich damals die Accelstepper Lib verwendet, Mobatools gab es damals noch nicht.

LG Stefan

Anbei die Schema-Skizze

Frästisch.pdf (1.47 MB)

Hallo Einstein, ja genau auf diese Weise hatte ich es damals auch versucht. Wenn ich den Impulsgenerator Mit dem ich den Steper ohne Arduino mit einem Poti mit Impulsen versorgen kann , drann hatte (anstelle des Arduino) ist der Stepper gerannt wie Sau, schnell Kraftvoll, Ab ich den Arduino drangehangen, kam der Stepper kaum anständig zum drehen, keine Kraft , kein Tempo unsauberer lauf. Dann habe ich versuchsweise am Steperdriver PUL + / DIR + / En + Zusammen auf +5V geschalte und die Anschlüsse PUL - / DIR - / ENA - an den Arduino. (bei dir müsstest Du für diesen Versuch die Programmzeile :

 myStepper.attachEnable( enaPin, 10, LOW );        // Enable Pin aktivierü/codeen ( LOW=aktiv )

ändern in

 myStepper.attachEnable( enaPin, 10, HIGH );        // Enable Pin aktivieren ( HIGH=aktiv )

Oder für den Versuch ENA - einfach nicht an den Arduino anschliessen.

so lief bei mir der Stepper dann sauber. Warumm genau das so war kann ich dier auch nicht mit absoluter Sicherheit sagen. evt. war der HIGH PEGEL am Arduino Pin, der das PULSE (Step) Signal raus gibt, etwas zu niedrig. (vlt, der Vorwiderstand für den Optokopler im TB6600 etwas hoch) so dass die Impulse nicht mehr sauber erkannt werden.
Bei diesen versuch musst du auch beachten, dass der Motor auch in entgegengesetzter richtung dreht, gegenüber deiner Jetzigen Beschaltung. Sollte der Motor zwar so sauber laufen, die vertauschte Drehrichtung ein Problem sein, kannst du ja entweder in der Software das Dir-Signal invertieren, oder einfach das Grüne und das Blaue Motorkabel am Treiber tauschen.

Kannst ja mal versuchen, ob es damit sauberer läuft.

LG Stefan

Hi Einstein ,
ich nochmals,
Du hast irgendwo noch gefragt gehabt was in der Zeile:

 myStepper.attachEnable( enaPin, 10, LOW );        // Enable Pin aktivieren ( LOW=aktiv )

die '10' bedeutet.
Ich vermute, das ist eine Verzögerung, um dem Motor-Treiber Zeit einzuräumen, die Endstufen wieder einzuschalten. Die meisten treiber benötigen zum einschalten der Endstufen einen kleinen Moment Zeit, bis die Endstufen wieder ganz hochgefahren sind. Aus diesem Grund kann man einen Stepermotor für den Betrieb auch nicht über den ENA Eingang des Treibers Pulsen, weil der ENA da einfach zu langsam ist.

LG Stefan

Deltaflyer:
Ich vermute, das ist eine Verzögerung, um dem Motor-Treiber Zeit einzuräumen, die Endstufen wieder einzuschalten.

Richtig, die Zeit in ms um die der erste Step nach dem Enable verzögert wird. Ebenso wird das Enable erst um diese Zeit nach dem letzten Step abgeschaltet.

Danke Frnz-Peter
für die Bestätigung. Ich hatte bisher leider noch keine Zeit, mich mit den MoBa-Tools Auseinander zu setzen, da ich seit längerem intensiv in nem andern Projekt stecke, das auch noch laufend erweitert wird. (Ok das ende der Erwiterungen ist glaub ich jetzt erreicht, muss nur noch die neuen Teile dann einbinden (Hard- und Software) -> Aber das nur am Rande , um ne gute Ausrede zu haben :wink:

Aber ich weiss, dass die Treiber für Enable eine gewisse Zeit benötigen, und als ich im Code die form der Initirung für Enable sah, und die Frage dazu las, bin ich einfach auf die Idee gekommen, dass Du da die Möglichkeit eingebunden hast, Die MoBa Tools auf das verhalten des Treibers und also auch ans System , anzupassen..

LG Stefan

I

Leider keine Veränderung :frowning: