In diesem Artikel erfährst du, wie man einen automatischen Arduino Aufzug für ein Hausmodell baut und programmiert. Mich hat die folgende Frage erreicht:
Hallo, ich würde gern ein Modellhochhaus mit einem selbstständig fahrenden Aufzug ausstatten. Das Hochhaus hat 12 Stockwerke.
Das klingt doch spannend. Glücklicherweise müssen wir dafür keinen kompletten Aufzug mit Ruftasten, Etagenauswahl und schließenden Türen bauen. Konzentrieren wir uns also nur um automatisches Hoch- und runterfahren. Herzstück dieses Projektes ist ein Schrittmotor (auch Stepper-Motor). Man nutzt sie unteranderem in 3D-Druckern und CNC-Fräsen. Sie lassen sich schrittweise (um z. B. 1,5 Grad) drehen. Wir statten die Achse so eines Schrittmotors mit einer Trommel aus, auf der das Tragseil des Aufzugs auf- und abgewickelt werden kann. Nun müssen wir uns nur noch überlegen, wie viele Schritte der Motor ausführen soll, um ein Stockwerk anzufahren. Da Stockwerke unterschiedlich hoch sein können (oft ist das Erdgeschoss höher), speichern wir die Schritte vom einen zum anderen Stockwerk einfach in einem Array. Die nötigen Schritte kann man dann einfach ausprobieren. Sie sind vom Motor, dem Durchmesser der Trommel und der Höhe der Stockwerke abhängig.
Das unterste Geschoss (z. B. Erdgeschoss, Keller, Tiefgarage) dient uns als Referenzwert. Ab hier geht es nur nach oben. Legen wir noch für uns fest, das im Uhrzeigersinn auf, gegen den Uhrzeigersinn abgewickelt wird.
int stockwerkSchritte[] = {150,100,100,100,100,100,100,100 };
Um also vom Erdgeschoss in den ersten Stock zu gelangen, muss der Motor 150 Schritte im Uhrzeigersinn ausführen.
Achtung: Schrittmotoren sind sehr kraftvoll. Wenn der Motor weiterdreht, als der Aufzug fahren kann, kann das Seil reißen oder das ganze Modell Schaden nehmen. Auch kann auch Verletzungsgefahr bestehen. Ich schlage vor, sich vorsichtig an die oberste Etage heranzutasten. Im Notfall schnell die Stromversorgung trennen.
Bauteile
- L293D (falls nicht im Starterkit enthalten)
- Nema 17 Schrittmotor
- Externes Netzteil
- Kühlkörper
Schaltung
Die Schaltung besteht aus einem Arduino, das über ein L293D-Motortreiber einen Schrittmotor (Nema17) steuert. Versorgt wird das Arduino per USB-Strom, der Stepper über ein externes Netzteil. Den L293D sollte man auf jeden Fall mit einem Kühlkörper ausstatten.
Programm: Arduino Aufzug
Nun ist es Zeit, das Programm zu planen. Der Aufzug soll also im untersten Stockwerk starten, sich per Zufall ein Zielstockwerk suchen und dorthin fahren. Da soll er warten, sich wiederum ein Stockwerk suchen und dorthin fahren.
Der Einfachheit halber nehmen wir zwei Variablen, die wir später nur noch vergleichen müssen. Dabei handelt es sich um die aktuelle Position des Aufzugs (positionAktuell) und die Zielposition (positionZiel). Beide Variablen speichern die Schritte, des Schrittmotors. Wenn beide gleich sind, ist der Aufzug an der Zielposition, also in der Zieletage. Dann ist es Zeit für eine Pause und daran, ein neues Zielstockwerk auszuwählen. Mithilfe des Zielstockwerks lässt sich die neue Zielposition errechnen.
Nun benötigen wir nur noch zwei if-Abfragen zum Vergleich der beiden Variablen. Entweder ist die Zielposition größer als die aktuelle Position, dann soll der Aufzug nach oben fahren, oder sie ist kleiner, dann soll der Aufzug nach unten fahren.
Wenn du das folgende Programm auf das Arduino Board lädst, kannst du im seriellen Monitor (Arduino Menü>Werkzeuge>Serieller Monitor) sehen, was das Programm gerade tut. Wichtig ist, dass du die Baud-Rate (unten rechts im seriellen Monitor) auf 115200 setzt. Der Motor sollte sich ebenfalls schon drehen. Nun kannst du die Schritte pro Stockwerk kalibrieren.
#include <Stepper.h> // Einbinden der Stepper-Programmbibliothek #define STEPS 200 // Schritte pro Umdrehung - ist für dieses Projekt nicht wichtig Stepper stepper(STEPS, 8, 9, 10, 11); // erzeugt ein stepper-Objekt int motorSpeed = 1; // je größer, desto langsamer bewegt sich der Aufzug int stockwerkSchritte[] = {150, 100, 100, 100, 100, 100, 100, 100, 100}; // speichert die Steps von Etage zu Etage int anzahlStockwerke = 10; // Anzahl der Stockwerke int aktuellesStockwerk = 0; // 0 = unterstes Geschoss int zielStockwerk = 0; // speichert das Zielstockwerk int positionAktuell = 0; // Position in Schritten, an denen sich der Aufzug befindet int positionZiel = 0; // Zielposition in Schritten int wartezeitMin = 1000; // kürzeste Wartezeit im Stockwerk int wartezeitMax = 5000; // längste Wartezeit im Stockwerk void setup() { Serial.begin(115200); // Serielle Ausgabe stepper.setSpeed(30); // hier kann man die Drehgeschwindigkeit festlegen randomSeed(analogRead(5)); // startet den Zufalls-Nummerngenerator } void loop() { Serial.print("positionZiel= "); Serial.print(positionZiel); // Serielle Ausgabe Serial.print(" positionAktuell= "); Serial.print(positionAktuell); // Serielle Ausgabe if (positionAktuell == positionZiel) { // Aufzug ist am Ziel angekommen Serial.println(" Angekommen"); delay(wartezeitMin + random(wartezeitMax - wartezeitMin));// Warte eine zufällige Zeit zwischen wartezeitMin und Max zielStockwerk = random(anzahlStockwerke); // ermittelt ein neues Stockwerk while (zielStockwerk == aktuellesStockwerk) { // solange das neue Stockwerk aber das aktuelle Stockwerk ist zielStockwerk = random(anzahlStockwerke); // wird noch einmal ermittelt } positionZiel=0; // Zielposition zurücksetzen for (int i = 0; i < zielStockwerk; i++) { // Schritte bis zur Zielposition vom Nullpunkt berechnen positionZiel += stockwerkSchritte[i]; } } else if (positionAktuell < positionZiel) { // nach oben fahren Serial.println(" Nach oben fahren"); // Serielle Ausgabe stepper.step(1); // erhöhe um einen Step positionAktuell++; // erhöhe die Positionsvariable delay(motorSpeed); // Wartezeit nimmt Einfluss auf Aufzugsgeschwindigkeit } else if (positionAktuell > positionZiel) { // nach unten fahren Serial.println(" Nach unten fahren"); // Serielle Ausgabe stepper.step(-1); // erhöhe um einen Step positionAktuell--; // erhöhe die Positionsvariable delay(motorSpeed); // Wartezeit nimmt Einfluss auf Aufzugsgeschwindigkeit } }
Variante mit Stepper-Treiber DRV8825
Nun bleibt noch zu erwähnen, dass der L293D eine günstige Einsteiger-Variante ist, jedoch wäre die Verwendung eines Stepper-Treibers wie dem DRV8825* besser. Wie das geht, sehen wir uns hier an:
Die Schaltung besteht aus dem Arduino, dessen Pins 2 und 3 mit dem Dir- und Step-Pin des DRV8825 verbunden sind. Dessen Reset- und Sleep-Pin sind mit 5V+ verbunden. Das gilt auch für den M0-Pin, was ein 1/2 Microstepping ermöglicht. Der Motor dreht dadurch ruhiger.
Versorgt wird der Stepper durch eine externe Stromversorgung (12V), die hier am DRV8825 an den Pins VMOT und GND verbunden sind. Diese wird noch durch einen 100uF-Elektrolytkondensator (>12V) unterstützt.
Beim Stepper handelt es sich um einen NEMA17 (42BYGHW811).
Achtung! Es ist sehr wichtig, dass der maximale Strom des Stepper-Drivers eingestellt wird. Das kann man mit dem kleinen Potentiometer auf dem DRV8825 erledigen. Wie das genau geht, ist in diesem fantastischen Tutorial erklärt. (Leider nur auf Englisch, aber das lässt sich ja übersetzen. Ich nutze dafür gerne deepl.com.)
Code
Der neue Code verwendet die BasicStepperDriver-Bibliothek, die sich über Bibliotheken verwalten, im Arduino Sketch Menü einbinden lässt.
#include "BasicStepperDriver.h" // Einbinden der Stepper-Programmbibliothek #define MOTOR_STEPS 200 // Schritte pro Umdrehung - ist für dieses Projekt nicht wichtig #define RPM 60 // Stepper Geschwindigkeit #define MICROSTEPS 2 // Microsteps des Stepper-Motors #define DIR 2 // DIR-Pin des Stepper-Motors #define STEP 3 // STEP-Pin des Stepper-Motors #define SLEEP 13 // sleep Funktion des Stepper-Treibers #define MOTOR_ACCEL 2000 #define MOTOR_DECEL 1000 #include "DRV8825.h" #define MODE0 10 #define MODE1 11 #define MODE2 12 DRV8825 stepper(MOTOR_STEPS, DIR, STEP, SLEEP, MODE0, MODE1, MODE2); // erzeugt ein stepper-Objekt //BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP, SLEEP); // erzeugt ein stepper-Objekt int motorSpeed = 1; // je größer, desto langsamer bewegt sich der Aufzug int stockwerkSchritte[] = {150, 100, 100, 100, 100, 100, 100, 100, 100}; // speichert die Steps von Etage zu Etage int anzahlStockwerke = 10; // Anzahl der Stockwerke int aktuellesStockwerk = 0; // 0 = unterstes Geschoss int zielStockwerk = 0; // speichert das Zielstockwerk int positionAktuell = 0; // Position in Schritten, an denen sich der Aufzug befindet int positionZiel = 0; // Zielposition in Schritten int wartezeitMin = 1000; // kürzeste Wartezeit im Stockwerk int wartezeitMax = 5000; // längste Wartezeit im Stockwerk void setup() { stepper.begin(RPM, MICROSTEPS); Serial.begin(115200); // Serielle Ausgabe //stepper.setSpeed(30); // hier kann man die Drehgeschwindigkeit festlegen randomSeed(analogRead(5)); // startet den Zufalls-Nummerngenerator } void loop() { Serial.print("positionZiel= "); Serial.print(positionZiel); // Serielle Ausgabe Serial.print(" positionAktuell= "); Serial.print(positionAktuell); // Serielle Ausgabe if (positionAktuell == positionZiel) { // Aufzug ist am Ziel angekommen Serial.println(" Angekommen"); delay(wartezeitMin + random(wartezeitMax - wartezeitMin));// Warte eine zufällige Zeit zwischen wartezeitMin und Max zielStockwerk = random(anzahlStockwerke); // ermittelt ein neues Stockwerk while (zielStockwerk == aktuellesStockwerk) { // solange das neue Stockwerk aber das aktuelle Stockwerk ist zielStockwerk = random(anzahlStockwerke); // wird noch einmal ermittelt } positionZiel=0; // Zielposition zurücksetzen for (int i = 0; i < zielStockwerk; i++) { // Schritte bis zur Zielposition vom Nullpunkt berechnen positionZiel += stockwerkSchritte[i]; } } else if (positionAktuell < positionZiel) { // nach oben fahren Serial.println(" Nach oben fahren"); // Serielle Ausgabe stepper.rotate(2); //stepper.step(1); // erhöhe um einen Step positionAktuell++; // erhöhe die Positionsvariable delay(motorSpeed); // Wartezeit nimmt Einfluss auf Aufzugsgeschwindigkeit } else if (positionAktuell > positionZiel) { // nach unten fahren Serial.println(" Nach unten fahren"); // Serielle Ausgabe stepper.rotate(-2); //stepper.step(-1); // erhöhe um einen Step positionAktuell--; // erhöhe die Positionsvariable delay(motorSpeed); // Wartezeit nimmt Einfluss auf Aufzugsgeschwindigkeit } }
Wenn dir das Projekt gefallen hat und du von weiteren interessanten Projekten inspiriert werden willst, sieh dir doch mal mein neues E-Book »Arduino Projekte Volume 1« an!
- Die beliebtesten Arduino-Projekte von StartHardware
- Inklusive Schaltplan, Beschreibung und Code
- Arduino-Schnellstart-Kapitel
- Kompakter Programmierkurs
Pingback: Stepper-Motor mit dem DRV8825 steuern – Ein Arduino Tutorial