Arduino Mecanum-Räder Roboter bauen: 360° Mobilität DIY Anleitung
In diesem Tutorial lernen wir, wie man einen Arduino Mecanum-Räder-Roboter baut, der sich in jede Richtung bewegen kann. Diese einzigartige Mobilität wird durch spezielle Räder erreicht – sogenannte Mecanum-Räder. Sie können das folgende Video ansehen oder die schriftliche Anleitung unten lesen. Ich habe diese Räder selbst entworfen und 3D-gedruckt, da sie gekauft recht teuer sind. Sie funktionieren sehr gut und ich muss sagen: Das Fahren dieser Roboterplattform macht riesigen Spaß. Wir können den Roboter drahtlos per NRF24L01-Funkmodul steuern – in meinem Fall mit meinem DIY-RC-Sender aus einem früheren Video. Zusätzlich ist eine Steuerung per Smartphone via Bluetooth möglich. Ich schrieb eine eigene Android-App, mit der wir den Roboter in jede Richtung bewegen und per Schieberegler die Geschwindigkeit regeln können. Das Gehirn der Plattform ist ein Arduino Mega, der jedes Rad einzeln ansteuert. Jedes Rad sitzt auf einem NEMA 17 Schrittmotor. Da Schrittmotoren präzise steuerbar sind, fügte ich in der App eine weitere coole Funktion hinzu: automatische Programmierung. Per „Speichern“-Button speichern wir jede Position/Schritt, und der Roboter kann diese Schritte automatisch abfahren und wiederholen. Mit demselben Button kann man pausieren, zurücksetzen oder neue Schritte speichern. Zunächst entwarf ich den Roboter in einer 3D-Modellierungssoftware. Die Basisplattform ist ein einfacher Kasten aus 8mm starken MDF-Platten. Die vier Schrittmotoren werden auf dieser Plattform montiert, die Mecanum-Räder auf den Motorwellen. Das 3D-Modell finden Sie auf Thangs zum Download und zur Browser-Ansicht. Assembly 3D-Modell von Thangs herunterladen. STL-Dateien für 3D-Druck: Ein Mecanum-Rad hat Rollen am Umfang, die diagonal – im 45°-Winkel zur Drehachse – angebracht sind. Dadurch übt das Rad bei Vorwärts- oder Rückwärtsdrehung eine diagonale Kraft aus. Indem wir die Räder in bestimmten Mustern drehen, nutzen wir diese Diagonalkräfte und der Roboter kann sich in jede Richtung bewegen. Wichtig: Es gibt zwei Arten von Mecanum-Rädern – links- und rechtsgängig. Der Unterschied liegt in der Rollenorientierung, und sie müssen an spezifischen Positionen am Roboter montiert werden. Die Drehachse des oberen Rollers jedes Rads muss zum Roboterzentrum zeigen. Kurze Demonstration der Bewegungen je nach Raddrehrichtung: Nun zeige ich den Bau der Roboterplattform. Für die Basis verwende ich 8mm MDF-Platten. Per Tischkreissäge säge ich alle Teile nach den 3D-Modell-Maßen zu. Mit 3mm Bohrer und 25mm Forstnerbohrer die Öffnungen für die Schrittmotoren in die Seitenwände bohren. Teile bereit, Zusammenbau mit Holzleim und Schrauben. Wichtig: Motoröffnungen präzise fertigen, damit alle Räder später gleichmäßig aufliegen. Man könnte die Basis auch 3D-drucken – die 3D-Datei dazu stelle ich im Webartikel bereit. Zum Schluss Grundplatte und Deckel weiß lackieren. Nun die Mecanum-Räder. Wie gesagt: Selbst entworfen und 3D-gedruckt, da gekaufte teuer sind. Die Räder bestehen aus zwei Hälften (außen/innen), verschraubt mit M4-Schrauben/Muttern. Je 10 Rollen pro Rad, Wellenkupplung passend für NEMA 17. Alle Teile auf meinem Creality CR-10 gedruckt. Link zu diesem 3D-Drucker falls Interesse besteht. Für die Rollenwellen nutze ich 3mm Stahlseil. Länge ca. 40mm, per Dremel zurechtgeschnitten. Radmontage: Zwei Hälften und Wellenkupplung mit vier M4-Schrauben/Muttern (45mm lang) verbinden. Rollen einbauen: Welle leicht in die Löcher des Innenrings stecken, M3-Unterlegscheibe, Rolle, Welle ganz in den Schlitz der Außenhälfte schieben. Nur eine Unterlegscheibe, da Platz für zweite fehlte. Diesen Vorgang für alle 10 Rollen wiederholen. Einfach und fast meditativ. Wichtig: Rollen müssen sich frei drehen können. Zum Schluss paar Tropfen Sekundenkleber in die Innenlöcher, damit die Wellen nicht lockern. Räder fertig – jetzt den ganzen Roboter zusammenbauen. Schrittmotoren an Basisplattform schrauben (M3x12mm). Räder auf Motorwellen: Meine Wellenkupplung hat Schlitz für M3-Mutter, durch die M3-Schraube das Rad an der Welle fixiert. Deckelbefestigung: Gewindestangen in zwei Ecken der Basis, passende Löcher im Deckel – so lässt sich der Deckel leicht aufsetzen und befestigen. Rückseitig 20mm Loch für Netzschalter, 5mm Loch für LED. Jetzt die Elektronik. Hier der komplette Schaltplan: Vier NEMA 17 Schrittmotoren werden über vier DRV8825 Treiber (alternativ A4988) angesteuert. Stromversorgung: 12V, in meinem Fall 3S Li-Po (ca. 11,1V). Funk: NRF24L01, Bluetooth: HC-05. Zusätzlich ein Spannungsteiler zur Batterieüberwachung und LED für Unterspannungsanzeige (<11V). Einen dedizierten 5V-Regler (ca. 3A) habe ich auch integriert – optional, aber für ein zukünftiges Video geplant, in dem ich dieses Projekt mit meinem Arduino Roboterarm kombiniere (der 5V für seine Servos braucht). Benötigte Komponenten: Um die Elektronik übersichtlich zu halten und Kabelsalat zu vermeiden, entwarf ich ein eigenes PCB mit EasyEDA. Dieses PCB fungiert als Arduino MEGA Shield – wird direkt auf den Arduino Mega aufgesteckt. Ich nutze beide Leiterseiten. Für ungenutzte Arduino-Pins sind Pin-Header vorhanden für spätere Erweiterungen. Auch 12V, 5V, GND und Jumper für Schrittauflösung sind vorgesehen. Link zu den PCB-Projektdateien. Nach Designfertigstellung Gerber-Dateien generiert. Gerber-Datei: Bestellt bei JLCPCB (Sponsor dieses Videos). Gerber-Datei per Drag & Drop hochladen, im Viewer prüfen, Eigenschaften wählen (ich wählte blaue PCB-Farbe passend zum Arduino), bestellen. Bei Erstbestellung bis zu 10 PCBs für nur 2$. Nach einigen Tagen PCBs erhalten – hervorragende Qualität, exakt wie Design. Zuerst kleine Bauteile: Widerstände, Kondensatoren. Dann male Pin-Header für Arduino-Verbindung einlöten. Dann female Pin-Header einlöten. Für Schrittmotor-Anschlüsse und Schrittauflösungs-Jumper male Header. Klemmblöcke, Trimmer und Spannungsregler einlöten. PCB fertig – nun Treiber einsetzen und Motoren anschließen. Jumper für Schrittauflösung: 1/16-Schritt durch Verbinden der MS3-Pins mit 5V. Darauf die DRV8825 Treiber stecken, NRF24L01 und HC-05 Modul anschließen. PCB auf Arduino Mega aufstecken. Akku an Klemmblock anschließen, in Basisplattform legen. Netzschalter in Rückseite einsetzen, an anderen Klemmblock anschließen. Darüber die Batterie-LED. Motoren an PCB anschließen. Wichtig: Bei gegenüberliegenden Motoren die Stecker ebenfalls gegensätzlich anschließen. Das wird später bei der Programmierung benötigt, damit z.B. „Vorwärts“ beide Motoren in gleiche Richtung dreht, obwohl sie physikalisch gespiegelt montiert sind (einer CW, der andere CCW). Zum Schluss Deckel aufsetzen – der Mecanum-Räder-Roboter ist fertig. Zum Schluss der Arduino-Code. Es gibt zwei separate Codes: einer für NRF24L01-Funksteuerung, einer für Smartphone-Steuerung. Arduino-Code für NRF24L01-Steuerung: Beschreibung: Wir nutzen RF24-Bibliothek für Funk und AccelStepper für Schrittmotoren. Pins definieren, Variablen anlegen, im Arduino-Code für Smartphone-Steuerung via Bluetooth: Beschreibung: Der Bluetooth-Code funktioniert ähnlich. Statt Funkmodul definieren wir das Bluetooth-Modul und initialisieren es im App erstellt mit MIT App Inventor – Details im zugehörigen Tutorial. App und bearbeitbare Projektdatei hier herunterladen: Für die automatische Bewegung: „SAVE“ speichert aktuelle Schrittmotor-Positionen in Arrays. „RUN“ ruft Ich hoffe, Ihnen hat dieses Tutorial gefallen und Sie haben etwas Neues gelernt. Fragen gerne in den Kommentaren und schauen Sie in meine Arduino-Projektsammlung.Überblick


3D-Modell des Mecanum-Räder-Roboters


Wie Mecanum-Räder funktionieren


Mecanum-Räder-Roboter bauen














Schaltplan

PCB-Design




PCB bestücken








Arduino-Code für Mecanum-Räder-Roboter
/* === Arduino Mecanum Wheels Robot === Radio control with NRF24L01 by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: https://www.airspayce.com/mikem/arduino/AccelStepper/index.html */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
RF24 radio(48, 49); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2
AccelStepper RightBackWheel(1, 44, 45); // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4
int wheelSpeed = 1500;
struct Data_Package {
byte j1PotX; byte j1PotY; byte j1Button;
byte j2PotX; byte j2PotY; byte j2Button;
byte pot1; byte pot2;
byte tSwitch1; byte tSwitch2;
byte button1; byte button2; byte button3; byte button4;
};
Data_Package data;
void setup() {
LeftFrontWheel.setMaxSpeed(3000);
LeftBackWheel.setMaxSpeed(3000);
RightFrontWheel.setMaxSpeed(3000);
RightBackWheel.setMaxSpeed(3000);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening();
Serial.begin(115200);
}
void loop() {
currentTime = millis();
if (currentTime - lastReceiveTime > 1000) {
resetData();
}
if (radio.available()) {
radio.read(&data, sizeof(Data_Package));
lastReceiveTime = millis();
}
// Geschwindigkeit - linkes Potentiometer
wheelSpeed = map(data.pot1, 0, 255, 100, 3000);
if (data.j1PotX > 150) { moveSidewaysLeft(); }
else if (data.j1PotX < 100) { moveSidewaysRight(); }
else if (data.j1PotY > 160) { moveForward(); }
else if (data.j1PotY < 100) { moveBackward(); }
else if (data.j2PotX < 100 && data.j2PotY > 160) { moveRightForward(); }
else if (data.j2PotX > 160 && data.j2PotY > 160) { moveLeftForward(); }
else if (data.j2PotX < 100 && data.j2PotY < 100) { moveRightBackward(); }
else if (data.j2PotX > 160 && data.j2PotY < 100) { moveLeftBackward(); }
else if (data.j2PotX < 100) { rotateRight(); }
else if (data.j2PotX > 150) { rotateLeft(); }
else { stopMoving(); }
LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
// Batterie überwachen
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.00) * 3;
if (voltage < 11) { digitalWrite(led, HIGH); }
else { digitalWrite(led, LOW); }
}
void moveForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(0);
}
void resetData() {
data.j1PotX = 127; data.j1PotY = 127;
data.j2PotX = 127; data.j2PotY = 127;
data.j1Button = 1; data.j2Button = 1;
data.pot1 = 1; data.pot2 = 1;
data.tSwitch1 = 1; data.tSwitch2 = 1;
data.button1 = 1; data.button2 = 1;
data.button3 = 1; data.button4 = 1;
}Code language: Arduino (arduino)setup() Maximalgeschwindigkeit setzen, Funk starten. Im loop() Daten vom RC-Sender lesen (Details in dessen Tutorial). Je nach Joystick-Position entsprechende Bewegungsfunktion aufrufen. moveForward() setzt alle Motoren auf positive Geschwindigkeit, moveBackward() auf negative. Andere Richtungen durch passende Radkombinationen. runSpeed() für alle Schrittmotoren im Loop ausführen. Batteriespannung per Spannungsteiler am Analogeingang lesen, LED bei <11V einschalten./* === Arduino Mecanum Wheels Robot === Smartphone control via Bluetooth by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: https://www.airspayce.com/mikem/arduino/AccelStepper/index.html */
#include <SoftwareSerial.h>
#include <AccelStepper.h>
SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)
AccelStepper LeftBackWheel(1, 42, 43);
AccelStepper LeftFrontWheel(1, 40, 41);
AccelStepper RightBackWheel(1, 44, 45);
AccelStepper RightFrontWheel(1, 46, 47);
#define led 14
int wheelSpeed = 1500;
int dataIn, m;
int lbw[50], lfw[50], rbw[50], rfw[50]; // für Positionen/Schritte speichern
int index = 0;
void setup() {
LeftFrontWheel.setMaxSpeed(3000);
LeftBackWheel.setMaxSpeed(3000);
RightFrontWheel.setMaxSpeed(3000);
RightBackWheel.setMaxSpeed(3000);
Serial.begin(38400);
Bluetooth.begin(38400);
Bluetooth.setTimeout(1);
delay(20);
pinMode(led, OUTPUT);
}
void loop() {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if (dataIn == 0) { m = 0; }
if (dataIn == 1) { m = 1; }
if (dataIn == 2) { m = 2; }
if (dataIn == 3) { m = 3; }
if (dataIn == 4) { m = 4; }
if (dataIn == 5) { m = 5; }
if (dataIn == 6) { m = 6; }
if (dataIn == 7) { m = 7; }
if (dataIn == 8) { m = 8; }
if (dataIn == 9) { m = 9; }
if (dataIn == 10) { m = 10; }
if (dataIn == 11) { m = 11; }
if (dataIn == 12) { m = 12; }
if (dataIn == 14) { m = 14; }
// Geschwindigkeit einstellen
if (dataIn >= 16) { wheelSpeed = dataIn * 10; Serial.println(wheelSpeed); }
}
if (m == 4) { moveSidewaysLeft(); }
if (m == 5) { moveSidewaysRight(); }
if (m == 2) { moveForward(); }
if (m == 7) { moveBackward(); }
if (m == 3) { moveRightForward(); }
if (m == 1) { moveLeftForward(); }
if (m == 8) { moveRightBackward(); }
if (m == 6) { moveLeftBackward(); }
if (m == 9) { rotateLeft(); }
if (m == 10) { rotateRight(); }
if (m == 0) { stopMoving(); }
// Button "SAVE"
if (m == 12) {
if (index == 0) {
LeftBackWheel.setCurrentPosition(0);
LeftFrontWheel.setCurrentPosition(0);
RightBackWheel.setCurrentPosition(0);
RightFrontWheel.setCurrentPosition(0);
}
lbw[index] = LeftBackWheel.currentPosition();
lfw[index] = LeftFrontWheel.currentPosition();
rbw[index] = RightBackWheel.currentPosition();
rfw[index] = RightFrontWheel.currentPosition();
index++;
m = 0;
}
if (m == 14) {
runSteps();
if (dataIn != 14) {
stopMoving();
memset(lbw, 0, sizeof(lbw));
memset(lfw, 0, sizeof(lfw));
memset(rbw, 0, sizeof(rbw));
memset(rfw, 0, sizeof(rfw));
index = 0;
}
}
LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.00) * 3;
if (voltage < 11) { digitalWrite(led, HIGH); }
else { digitalWrite(led, LOW); }
}
void runSteps() {
for (int i = index - 1; i >= 0; i--) {
LeftFrontWheel.moveTo(lfw[i]); LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.moveTo(lbw[i]); LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.moveTo(rfw[i]); RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.moveTo(rbw[i]); RightBackWheel.setSpeed(wheelSpeed);
while (LeftBackWheel.currentPosition() != lbw[i] &&
LeftFrontWheel.currentPosition() != lfw[i] &&
RightFrontWheel.currentPosition() != rfw[i] &&
RightBackWheel.currentPosition() != rbw[i]) {
LeftFrontWheel.runSpeedToPosition();
LeftBackWheel.runSpeedToPosition();
RightFrontWheel.runSpeedToPosition();
RightBackWheel.runSpeedToPosition();
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if (dataIn == 15) { // PAUSE
while (dataIn != 14) { // Warten auf RUN
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if (dataIn == 13) { stopMoving(); break; }
}
}
}
if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; }
if (dataIn == 13) { break; }
}
}
}
// Rückwärts durch Schritte
for (int i = 1; i <= index - 1; i++) {
LeftFrontWheel.moveTo(lfw[i]); LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.moveTo(lbw[i]); LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.moveTo(rfw[i]); RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.moveTo(rbw[i]); RightBackWheel.setSpeed(wheelSpeed);
while (LeftBackWheel.currentPosition() != lbw[i] &&
LeftFrontWheel.currentPosition() != lfw[i] &&
RightFrontWheel.currentPosition() != rfw[i] &&
RightBackWheel.currentPosition() != rbw[i]) {
LeftFrontWheel.runSpeedToPosition();
LeftBackWheel.runSpeedToPosition();
RightFrontWheel.runSpeedToPosition();
RightBackWheel.runSpeedToPosition();
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if (dataIn == 15) {
while (dataIn != 14) {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if (dataIn == 13) { stopMoving(); break; }
}
}
}
if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; }
if (dataIn == 13) { break; }
}
}
}
}
// Bewegungsfunktionen (identisch zum NRF24L01-Code)
void moveForward() { ... }
void moveBackward() { ... }
void moveSidewaysRight() { ... }
void moveSidewaysLeft() { ... }
void rotateLeft() { ... }
void rotateRight() { ... }
void moveRightForward() { ... }
void moveRightBackward() { ... }
void moveLeftForward() { ... }
void moveLeftBackward() { ... }
void stopMoving() { ... }Code language: Arduino (arduino)setup(). Wieder lesen wir eingehende Daten vom Smartphone/App und steuern den Roboter entsprechend. Die Android-App sendet Zahlen 0-15 per Bluetooth bei Button-Druck.

runSteps() auf, das per for/while-Schleifen alle Schritte abfährt.
Herstellungsprozess
- Bluetooth-gesteuerter Raspberry Pi Roboter mit Audio-Feedback bauen
- Servogesteuerter Hindernisvermeidungs-Roboter: Bauen mit Arduino & HC-SR04
- Autonomer Linienfolger-Roboter mit Arduino UNO
- Sprachgesteuerter Roboter mit Arduino Nano bauen
- PiBot: Arduino-gesteuerter Klavierroboter für präzise Musikwiedergabe
- LittleArm 2C: Robuster 3D-gedruckter Arduino-Roboterarm für STEM-Bildung
- Autonomer Hausassistent-Roboter bauen: Komplette Teileliste & Setup-Anleitung
- Arduino Roboterarm per Android-App & Bluetooth steuern
- Smartes Indoor-Navigations-Roboter-Kit für Arduino-Projekte
- WiDC: Wi‑Fi FPV Roboter – Fernsteuerung mit Live-Video