sitemap link mailform link home

Schrittmotoren ansteuern

Beitrag vom 26.05.2016

Links:
Externer Link http://www.arduino-tutorial.de/2010/06/motorsteuerung-eines-schrittmotors-stepper-motor/

Externer Link http://www.arduino-tutorial.de/2010/06/motorsteuerung-mit-einer-mos-fet-brucke/

 


 

Bei www.pollin.de gibt es das Schrittmotor-Set DAYPOWER S-SPSM-5V für 5,45 € (Bestellnummer 310543):

Schrittmotor-Set

Daten des Schrittmotors:

Betriebsspannung: 5 V-
Phasen: 4
Übersetzung: 1/64 (mit eingebautem Getriebe)
Schrittwinkel: 5.625° (64 Schritte/Umdrehung)
Frequenz: 100 Hz
Gleichstromwiderstand : 50 Ohm ± 7% (25 °C)
Drehmoment: > 34.3 mN*m (120 Hz)
Geräuschpegel: < 35dB (120 Hz)

Treiberschaltung

Schaltplan des ULN2003-Treiber-Boards

Ein Treiber-Board ist auch mit dabei. Dieses kann man direkt an den Arduino anschließen (Steueranschlüsse IN1 bis IN4 auf der linken Seite).

Wir verwenden folgende Zuordnung:

Arduino Port 8 -> IN1 / P1-1
Arduino Port 9 -> IN2 / P1-2
Arduino Port 10 -> IN3 / P1-3
Arduino Port 11 -> IN4 / P1-4


Ergänzung vom 27.05.2016

ACHTUNG FEHLER: Die richtige Zuordnung muss so aussehen:

Arduino Port 8 -> IN1 / P1-1
Arduino Port 9 -> IN2 / P1-3
Arduino Port 10 -> IN3 / P1-2

Arduino Port 11 -> IN4 / P1-4


Das Treiber-Board (also auch den Schrittmotor) sollte man aber separat mit 5 Volt versorgen (Batteriefach mit 3 x 1,5 Volt oder Steckernetzteil) an die Anschlüsse GND (1 ,+) und VCC (2, -).

ULN2003

Eigentlich könnte ich mir die folgende Grafik sparen - aber sicher ist sicher:

Fritzing-Grafik

Verbindung von Arduino und Treiber-Board

Ergänzung vom 27.05.2016

ACHTUNG FEHLER: Die gelbe und die grüne Steckbrücke müssen am Treiber-Board vertauscht werden! Das heißt, dass die gelbe Steckbrücke an IN3 und die grüne Steckbrücke auf IN2 gesteckt werden müssen!

Anm.: Das Treiber-Board mit Schrittmotor sieht im Original etwas anders aus - aber extra ein neues fritzing-Bauteil zu zeichnen, das erschien mir etwas zu aufwändig...

So, nachdem alles korrekt verbunden wurde... kommen wir nun zum Programmierteil...


Der verwendete unipolare Schrittmotor hat vier elektrische Wicklungen / Spulen bzw. 4 Phasen. Dabei wird jede Wicklung einzeln jeweils über IN1 bis IN 4 angesteuert. Der Chip ULN2003 verstärkt die Ausgangssignale des Arduino. Es handelt sich also um eine reine Treiber-Schaltung. Die Signale werden im ULN2003-Chip nicht weiter verarbeitet - sondern nur verstärkt.
Der Schrittmotor braucht in Bewegung schon ca. 200 mA und wenn er stillsteht noch erheblich mehr. Das wäre für den Arduino zu viel!

Wir müssen nun also das Pulsmuster für die Eingänge IN1 / P1-1, IN2 / P1-2, IN3 / P1-3 und IN4 / P1-4 des Treiber-Boards mit Hilfe eines Arduino-Programms erzeugen.

 


 

Interner Link Siehe "Theorie der Schrittmotor-Ansteuerung"

Ansteuerungstabelle:

Eingeschaltete Wicklung = 1       Ausgeschaltete Wicklung = 0


Eingang

Schritt-Nr.

IN1 P1-1

IN2 P1-2

IN3 P1-3

IN4 P1-4
11001
21010
30110
40101
11001

Wir verwenden die Arduino-Ports 8, 9, 10 und 11.

Hier nun das erste, einfache Programm zum Ansteuern unseres Schrittmotors.
Sobald das Programm gestartet wird beginnt sich der Schrittmotor einfach nur zu drehen:

 

// Ansteuerung eines Schrittmotors

// P1x sind die Eingänge des Controllers
// P11 = Port 8, P12 = Port 9, P13 = Port 10, P14 = Port 11:
#define P11 8
#define P12 9
#define P13 10
#define P14 11

// Länge der  Stepper-Phase
// Der Stepper kann mit minimal 4 ms angesteuert werden

#define STEPLENGTH 5 // Minimaler Wert = 4!

int arrayStepsP11[] = {1, 1, 0, 0};
int arrayStepsP12[] = {0, 0, 1, 1};
int arrayStepsP13[] = {0, 1, 1, 0};
int arrayStepsP14[] = {1, 0, 0, 1};

void setup() {

  // Pins auf Ausgang setzen:
  pinMode(P11, OUTPUT);
  pinMode(P12, OUTPUT);
  pinMode(P13, OUTPUT);
  pinMode(P14, OUTPUT);
}

void loop() {

  // Fortlaufende Ausgabe des Pulsmusters - 4-Phasen Vollschritt
  for (int i = 0; i < 4; i++)
  {
    if (arrayStepsP11[i] == 1)
    {
      digitalWrite(P11, HIGH);
    }
    else
    {
      digitalWrite(P11, LOW);
    }
    if (arrayStepsP12[i] == 1)
    {
      digitalWrite(P12, HIGH);
    }
    else
    {
      digitalWrite(P12, LOW);
    }
    if (arrayStepsP13[i] == 1)
    {
      digitalWrite(P13, HIGH);
    }
    else
    {
      digitalWrite(P13, LOW);
    }
    if (arrayStepsP14[i] == 1)
    {
      digitalWrite(P14, HIGH);
    }
    else
    {
      digitalWrite(P14, LOW);
    }
   delay(STEPLENGTH);
  }
}

Bei einer STEPLENGTH unterhalb von 4 (ms) gerät dieser einfache Stepper aus dem Tritt und bleibt stehen.

 


Schrittmotor starten und stoppen

 

Als nächstes wollen wir nun ein Programm schreiben, mit dem der Stepper auch ein- und ausgeschaltet werden kann.

Dazu benötigen wir einen Tastenschalter. Dieser wird wie fogt an den Port 2 (im Bild als gelbe Steckbrücke) angeschlossen:

fritzing-Bild

ACHTUNG FEHLER: Die gelbe und die grüne Steckbrücke müssen am Treiber-Board vertauscht werden! Das heißt, dass die gelbe Steckbrücke an IN3 und die grüne Steckbrücke auf IN2 gesteckt werden müssen!

Da wir auch noch einen Taster für die Drehrichtung benötigen, fügen wir diesen rechts daneben ein und verbinden ihn mit Port 3 (grüne Steckbrücke).

Die Schaltung - bestehend aus Taster und Widerstand - hat folgende Funktion:

  • Taster nicht gedrückt - über den Widerstand 10 kΩ liegt am Port exakt eine Spannung von 0 Volt an
  • Taster gedrückt - am Port liegt exakt eine Spannung von 5 Volt an

Ohne den Widerstand 10 kΩ wäre das Spannungspotential am Port nicht definiert, da der Port dann sozusagen "in der Luft hängen würde". Das kann zur Einstreuung von Störspannungen aus der Umwelt führen und Fehlfunktionen auslösen.

 


So - aber nun wieder zur Programmierung...

Wir benötigen nun eine Variable varEinschalter vom Typ boolean, um den Taster namens EINSCHALTER abfragen zu können.
Der Stepper soll damit gestartet werden.

Folgende Befehle (hervorgehoben) müssen in das Programm eingefügt werden:

 

// Ansteuerung eines Schrittmotors

// P1x sind die Eingänge des Controllers
// P11 = Port 8, P12 = Port 9, P13 = Port 10, P14 = Port 11:
#define P11 8
#define P12 9
#define P13 10
#define P14 11

#define EINSCHALTER 2

// Länge der  Stepper-Phase
#define STEPLENGTH 5 // Minimaler Wert = 4!

int arrayStepsP11[] = {1, 1, 0, 0};
int arrayStepsP12[] = {0, 0, 1, 1};
int arrayStepsP13[] = {0, 1, 1, 0};
int arrayStepsP14[] = {1, 0, 0, 1};

// Schalter-Variablen definieren
boolean varEinschalter = 0;


void setup() {
  pinMode(P11, OUTPUT);
  pinMode(P12, OUTPUT);
  pinMode(P13, OUTPUT);
  pinMode(P14, OUTPUT);

  // Schalter-Port auf Eingang setzen
  pinMode(EINSCHALTER, INPUT);

}

void loop() {

  // Einschalter abfragen
  varEinschalter = digitalRead(EINSCHALTER);
  if (varEinschalter == 1)
  {

Am Ende des Programms muss noch eine schließende geschweifte Klammer eingefügt werden, da wir ja den "Rest" des Programmcodes in die Schleife   if (varEinschalter == 1) eingefügt haben.

Nun dreht sich der Schrittmotor nur, wenn der Taster an Port 2 gedrückt wurde.

ABER: Gerade wenn der Stepper nicht dreht, verbraucht er am meisten Strom! Also ist es besser, das Batteriefach abzuklemmen, während man den Programmcode schreibt.
Sonst sind die Batterien in einer halben Stunde leer!


Richtungsänderung des Schrittmotors

Es ist ganz einfach, die Drehrichtung mit dem zweiten Taster zu ändern.

Dann müssen die Werte aus den Arrays "rückwärts" abgerufen werden. Das könnte man folgendermaßen machen - auch wenn es nicht sehr elegant ist:

 

// Ansteuerung eines Schrittmotors

// Mit 2 Tastern kann die Drehrichtung gewählt und der Schrittmotor gestartet werden.
// Der Schrittmotor läuft nur so lange, wie der Taster EINSCHALTER am Port 2 gedrückt wird.
// Standardmäßig läuft der Schrittmotor rechts herum - also im Uhrzeigersinn.
// Nur bei gedrücktem Taster DREHRICHTUNG an Port 3 dreht der Schrittmotor links herum.

// P1x sind die Eingänge des Controllers
// P11 = Port 8, P12 = Port 9, P13 = Port 10, P14 = Port 11:
#define P11 8
#define P12 9
#define P13 10
#define P14 11

#define EINSCHALTER 2
#define DREHRICHTUNG 3
#define LINKS 0
#define RECHTS 1

// Länge der  Stepper-Phase
#define STEPLENGTH 5 // Minimaler Wert = 4!

// Rechtslauf
int arrayStepsP11[] = {1, 1, 0, 0};
int arrayStepsP12[] = {0, 0, 1, 1};
int arrayStepsP13[] = {0, 1, 1, 0};
int arrayStepsP14[] = {1, 0, 0, 1};

// Schalter-Variable definieren
boolean varEinschalter = 0;
// Drehrichtungs-Variable definieren
// 1 = RECHTS = Rechtslauf, 0 = LINKS = Linkslauf
boolean varDrehrichtung = LINKS;

void setup() {
  pinMode(P11, OUTPUT);
  pinMode(P12, OUTPUT);
  pinMode(P13, OUTPUT);
  pinMode(P14, OUTPUT);

  // Schalter-Port auf Eingang setzen
  pinMode(EINSCHALTER, INPUT);
  // Drehrichtungs-Port auf Eingang setzen
  pinMode(DREHRICHTUNG, INPUT);  
}

void loop() {

  // Einschalter abfragen
  varEinschalter = digitalRead(EINSCHALTER);
  // Drehrichtungsschalter abfragen
  varDrehrichtung = digitalRead(DREHRICHTUNG);
 
  if (varEinschalter == 1)
  {
    if (varDrehrichtung == RECHTS)
    {
      // Rechtslauf
      // Es sind definitiv 4 Phasen beim Vollschrittbetrieb:
      for (int i = 0; i < 4; i++)
      {
        if (arrayStepsP11[i] == 1)
        {
          digitalWrite(P11, HIGH);
        }
        else
        {
          digitalWrite(P11, LOW);
        }
        if (arrayStepsP12[i] == 1)
        {
          digitalWrite(P12, HIGH);
        }
        else
        {
          digitalWrite(P12, LOW);
        }
        if (arrayStepsP13[i] == 1)
        {
          digitalWrite(P13, HIGH);
        }
        else
        {
          digitalWrite(P13, LOW);
        }
        if (arrayStepsP14[i] == 1)
        {
          digitalWrite(P14, HIGH);
        }
        else
        {
          digitalWrite(P14, LOW);
        }
       delay(STEPLENGTH);
      }
    }
    else
    {
      // Linkslauf
      // Es sind definitiv 4 Phasen beim Vollschrittbetrieb:
      for (int i = 3; i >= 0; i--)
      {
        if (arrayStepsP11[i] == 1)
        {
          digitalWrite(P11, HIGH);
        }
        else
        {
          digitalWrite(P11, LOW);
        }
        if (arrayStepsP12[i] == 1)
        {
          digitalWrite(P12, HIGH);
        }
        else
        {
          digitalWrite(P12, LOW);
        }
        if (arrayStepsP13[i] == 1)
        {
          digitalWrite(P13, HIGH);
        }
        else
        {
          digitalWrite(P13, LOW);
        }
        if (arrayStepsP14[i] == 1)
        {
          digitalWrite(P14, HIGH);
        }
        else
        {
          digitalWrite(P14, LOW);
        }
       delay(STEPLENGTH);
      }
    }
  }
}

So, das funktioniert prima... Für heute reicht es mit Programmieren! Cool


Hier nun eine Variante mit zwei Endlagenschaltern parallel an Pin 3 - zur Richtungsumkehr.
Damit kann man z.B. einen Fahrstuhl bauen, der fortlaufend hoch und runter fährt:

 

// Ansteuerung eines Schrittmotors
// Ganz unten auf der Website
// http://elektronik.nmp24.de/?Mikrocontroller:senseBox%3Aedu:Schrittmotoren_ansteuern

// Mit gedrücktem Taster an Pin 2 kann der Schrittmotor gestartet werden.
// Statt eines Tasters kann Pin 2 auch direkt mit +5 Volt verbunden werden.
// Dann läuft der Schrittmotor ständig.
//
// Zu Beginn läuft der Schrittmotor links herum - also gegen den Uhrzeigersinn.
// Nach dem Drücken eines der beiden Endlagenschalter kehrt sich die Drehrichtung um.
// Danach pausiert der Schrittmotor für eine kurze Zeit:
#define ENDLAGENWARTEZEIT 1000

// INx sind die Eingänge des Schrittmotor-Controllers
// ACHTUNG: In der fritzing-Schaltung auf der Website müssen Pin 9 und Pin 10 vertauscht werden!
// P11 = IN1= Port 8, P12 = IN3 = Port 9, P13 = IN2 = Port 10, P14 = IN4 = Port 11:
#define P11 8 //IN1
#define P12 9 //IN3
#define P13 10 //IN2
#define P14 11 //IN4
// SORRY - die Bezeichner der Pins sind leider etwas verwirrend...

#define EINSCHALTER 2
#define DREHRICHTUNGSTASTER 3
#define LINKS 0
#define RECHTS 1
#define AUS 0
#define AN 1

// Länge der  Stepper-Phase
#define STEPLENGTH 2 // Minimaler Wert ist 2! -> ausprobiert!!!

// Rechtslauf
int arrayStepsP11[] = {1, 1, 0, 0};
int arrayStepsP12[] = {0, 0, 1, 1};
int arrayStepsP13[] = {0, 1, 1, 0};
int arrayStepsP14[] = {1, 0, 0, 1};

// Schalter-Variable definieren
boolean varEinschalter = 0;
// Drehrichtungs-Variable definieren
// 1 = RECHTS = Rechtslauf, 0 = LINKS = Linkslauf
boolean varDrehrichtung = LINKS;
boolean varDrehrichtungstaster = AUS;
boolean varDrehrichtungstasterAlt = AUS;

void setup() {
  pinMode(P11, OUTPUT);
  pinMode(P12, OUTPUT);
  pinMode(P13, OUTPUT);
  pinMode(P14, OUTPUT);

  // Einschalter-Pin auf Eingang setzen
  pinMode(EINSCHALTER, INPUT);
  // Drehrichtungstaster-Pin auf Eingang setzen
  pinMode(DREHRICHTUNGSTASTER, INPUT);
}

void loop() {

  // Einschalter-Pin abfragen
  varEinschalter = digitalRead(EINSCHALTER);
  // Drehrichtungsschalter-Pin abfragen und auswerten
  varDrehrichtungstaster = digitalRead(DREHRICHTUNGSTASTER);
   if ((varDrehrichtungstaster == AN) && (varDrehrichtungstasterAlt == AUS))
   {
    varDrehrichtung = !varDrehrichtung; // Negation
    varDrehrichtungstasterAlt = AN;
    delay(ENDLAGENWARTEZEIT);
   }
   if ((varDrehrichtungstaster == AUS) && (varDrehrichtungstasterAlt == AN))
   {
    varDrehrichtungstasterAlt = AUS;
   }
 
  if (varEinschalter == 1)
  {
   if (varDrehrichtung == RECHTS)
    {
      // Rechtslauf
      // Es sind definitiv 4 Phasen beim Vollschrittbetrieb:
      for (int i = 0; i < 4; i++)
      {
        if (arrayStepsP11[i] == 1)
        {
          digitalWrite(P11, HIGH);
        }
        else
        {
          digitalWrite(P11, LOW);
        }
        if (arrayStepsP12[i] == 1)
        {
          digitalWrite(P12, HIGH);
        }
        else
        {
          digitalWrite(P12, LOW);
        }
        if (arrayStepsP13[i] == 1)
        {
          digitalWrite(P13, HIGH);
        }
        else
        {
          digitalWrite(P13, LOW);
        }
        if (arrayStepsP14[i] == 1)
        {
          digitalWrite(P14, HIGH);
        }
        else
        {
          digitalWrite(P14, LOW);
        }
        delay(STEPLENGTH);
      }
    }
    else
    {
      // Linkslauf
      // Es sind definitiv 4 Phasen beim Vollschrittbetrieb:
      for (int i = 3; i >= 0; i--)
      {
        if (arrayStepsP11[i] == 1)
        {
          digitalWrite(P11, HIGH);
        }
        else
        {
          digitalWrite(P11, LOW);
        }
        if (arrayStepsP12[i] == 1)
        {
          digitalWrite(P12, HIGH);
        }
        else
        {
          digitalWrite(P12, LOW);
        }
        if (arrayStepsP13[i] == 1)
        {
          digitalWrite(P13, HIGH);
        }
        else
        {
          digitalWrite(P13, LOW);
        }
        if (arrayStepsP14[i] == 1)
        {
          digitalWrite(P14, HIGH);
        }
        else
        {
          digitalWrite(P14, LOW);
        }
        delay(STEPLENGTH);
      }
    }
  }
}


So, ich hoffe, dass das auch bei allen so funktioniert...

.

Letzte Änderung:
March 23. 2023 21:04:40
«    top    »