Arduino Mikrocontroller Tutorials - Module

Schrittmotoren (Bsp. 28BYJ-48)

Magnetfeld ind Schrittmotor Spulen Magnetfeld ind Schrittmotor Spulen

Der verwendete Motor 28BYJ-48 beruht auf dem Can-Stack Prinzip. Der Rotor besteht aus 16 Dauermagnete (8x Nord- und 8x Südpol) die sich zu zwei hintereinanderliegenden Statorwicklungen, die zueinander einen halben Pol versetzt sind, ausrichten. Auf jeder Statorwicklung sind 2 Spulen mit einer gemeinsamen Mitte (+5V). Durch das abwechselnde anlegen von GND an den beiden Spulenenden lässt sich die Polung jedes Stators ändern. Jeder Stator hat ebenfalls 16 Pole.

Da die beiden Statorwicklungen einen halben Pol zueinander versetzt sind und abwechselnd angesteuert werden sind in Summe 2x16=32 Schritte für eine volle Umdrehung des Rotors notwendig. Die Bewegung von einem Schritt zum nächsten wird erst durchgeführt, wenn sich die Ansteuerung der Statorwicklungen ändert. Bei konstanter Ansteuerung bleibt der Motor positionsgenau stehen.

Der Schrittmotor kann in drei Modi betrieben werden:

Die einzelnen Spulen benötigen zu viel Strom als dass sie an den Arduino Ausgängen direkt angeschlossen werden können. Zur Lastschaltung der 4 Spulen werden deshalb Transistoren verwendet. Beim verwendeten Baustein ULN2003A handelt es sich um ein Transistor-Array-Chip mit 7 eingebauten Darlington- Transistoren. Wir verwenden 4 davon.

Jede Spule einzeln und abwechseln ansteuern

Magnetfeld ind Schrittmotor Spulen

Hier wird jede Spule einzeln geschaltet. Zuerst blau, dann vom zweiten Stator die pinke Spule. Dann wieder vom ersten Stator die gelbe un dann vom zweiten Stator die orangene Spule. Nach vier Schritten mit jeweils einem halben Polabstand wurde in Summe eine 2/16 Drehung durchgeführt. Wenn man diese 4 Schritte 8x wiederholt, hat man eine volle Drehung des Rotors vollendet (32 Steps).

Beim 28BYJ-48 Schrittmotor ist zwischen Rotor und Motorausgang noch ein Getriebe mit einer Übersetzung von 1:64 geschaltet. in Summe sind also 32x64=2048 Steps für eine volle Motorumdrehung notwendig.

Phasen I II III IV
blau x - - -
pink - x - -
gelb - - x -
orange - - - x
Programmcode: Spulen einzeln ansteuern const int pause = 10; // in ms (>2ms) #define A 8 #define B 9 #define C 10 #define D 11 void setup() { pinMode(A, OUTPUT); // blau pinMode(B, OUTPUT); // pink pinMode(C, OUTPUT); // gelb pinMode(D, OUTPUT); // orange } void loop() { digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); delay(pause); digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); delay(pause); digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); delay(pause); digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); delay(pause); }

Vollschritt-Ansteuerung mit jeweils 2 Spulen (Full-Step)

Magnetfeld ind Schrittmotor Spulen

Bei dieser Ansteuerung werden beiden Statorwicklungen jeweils zusammen bestromt. Das hat den Vorteil, dass der Motor durch 2 Spulen gleichzeitig, also mit der doppelten Kraft (aber auch doppeltem Stromverbrauch), bewegt wird.

Beide Statorwicklungen zusammen bilden bei dieser Ansteuerung einen 1,5 mal so breiten Pol. Der entsprechende Rotorpol bewegt sich davon in die Mitte.

Phasen I II III IV
blau x - - x
pink x x - -
gelb - x x -
orange - - x x
Programmcode: Zwei Spulen gleichzeitig ansteuern (Vollschritt-Betrieb) const int pause = 100; // in ms (>2ms) #define A 8 #define B 9 #define C 10 #define D 11 void setup() { pinMode(A, OUTPUT); // blau pinMode(B, OUTPUT); // pink pinMode(C, OUTPUT); // gelb pinMode(D, OUTPUT); // orange } void loop() { digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); delay(pause); digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); delay(pause); digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); delay(pause); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); delay(pause); }

Halbschritt-Ansteuerung als Kombination der oberen beiden Varianten (Half-Step)

Wenn man die oberen beiden Verfahren zusammenführt, lässt sich die Schrittweite nochmal verkleiner. Also halbe Schritte. Für eine Vollständige Motorumdrehung sind so 2x2048=4096 Steps notwendig. Mit dieser Ansteuerung lässt sich der Motor also nochmal deutlich präziser positionieren.

Phasen I II III IV V VI VII IIIV
blau x x - - - - - x
pink - x x x - - - -
gelb - - - x x x - -
orange - - - - - x x x
Programmcode: Ansteuerung in halben Schritten

Im Sketch ist eine Funktion enthalten, in die man die Richtung, den Drehwinkel und die Geschwindigkeit vorgeben kann.

int pause = 100; // in ms (>1 und <100) int phase = 0; // 0-7 beim Halbschrittmotor um ein Polpaar weiterzudrehen #define A 8 #define B 9 #define C 10 #define D 11 void setup() { pinMode(A, OUTPUT); // blau pinMode(B, OUTPUT); // pink pinMode(C, OUTPUT); // gelb pinMode(D, OUTPUT); // orange Serial.begin(115200); } void loop() { go(-360, 2); // Winkel mit Richtung, Schrittpause in ms (1-100) delay (1000); go(360, 5); delay(1000); } //FUNKTION um die Bewegung auszuführen void go (int winkel, int stepPause) { // in °, in ° pro sec) bool drehRichtung; // Uhrzeigersinn = true // nur Werte zw. 1 und 100ms zulassen u. Übertragen in globale Variable pause = constrain(stepPause, 1, 100); // Ermitteln der Schrittanzahl (360° entsprechen 4078 steps des Motors int goSteps = map(winkel, 0, 360, 0, 4078); // wenn der Winkel negativ ist, wird gegen den Uhrzeigersinn gedreht if (goSteps < 0) { drehRichtung = false; goSteps = abs(goSteps); } else drehRichtung = true; // Bewegung ausführen for (int i = 0; i < goSteps; i++) { oneStep(drehRichtung); } } //FUNKTION zum Ansteuern der 4 Spulen in 8 Schritten void oneStep(bool clockwise) { int p; if (clockwise == true) p = 1; else p = -1; switch (phase) { case 0: digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); phase += p; if (phase == -1) phase = 7; break; case 1: digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); phase += p;; break; case 2: digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); phase += p; break; case 3: digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); phase += p; break; case 4: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); phase += p; break; case 5: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); phase += p; break; case 6: digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); phase += p;; break; case 7: digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); phase += p; if (phase == 8) phase = 0; break; } delay(pause); }