DIY Arduino Roboterarm: Kabellos per Smartphone steuern & programmieren
Einführung
In diesem Tutorial bauen Sie einen Arduino Roboterarm mit 5 Freiheitsgraden, der kabellos per selbstentwickelter Android-App gesteuert und programmiert wird. Prozess: 3D-Druck, Elektronik, Arduino-Code, App-Entwicklung (MIT App Inventor).
Funktionsumfang der App
- 6 Slider für manuelle Steuerung jedes Servos/Achse
- Geschwindigkeits-Slider
- SAVE: Aktuelle Position als Schritt speichern
- RUN: Gespeicherte Schritte automatisch abspielen (Loop)
- PAUSE (während RUN): Anhalten, erneutes RUN → fortsetzen
- RESET: Alle Schritte löschen, neu aufnehmen
- Schrittzähler-Anzeige
3D-Modell & Druck
Design in SolidWorks. 5 Achsen: Basis (Drehung), Schulter, Ellbogen, Handgelenk-Roll, Handgelenk-Pitch, Greifer.
Servos:
- Achse 1–3 (Basis, Schulter, Ellbogen): MG996R (hohes Drehmoment)
- Achse 4–5 (Handgelenk) & Greifer: SG90 Micro
3D-Modell (STL/Assembly) auf Thangs zum Download & Browser-Exploration.
3D-Druck (Creality CR-10)
Alle Teile in wenigen Stunden gedruckt. CR-10: 90% vormontiert, top Druckqualität.
Tipp: Exzentermuttern an Rollen justieren für sauberen Lauf. Bett leveln → drucken.
Roboterarm montieren
- Basis: Servo 1 anschrauben, Rundhorn auf Welle, Bolzen sichern.
- Oberteil aufsetzen, 2 Schrauben.
- Schulter: Servo 2 → Horn → nächstes Teil → Bolzen.
- Wichtig: Feder/Gummiband an Schulterachse zur Gewichtsentlastung (trägt ganzen Arm + Last).
- Ellbogen, Handgelenke, Greifer analog (4 mm Schrauben/Muttern für Greifer).
- Greifer auf letztes Servo → Fertig.
Elektronik & Schaltplan
Einfach: Arduino + HC-05 Bluetooth-Modul. 6 Servo-Signalpins an Digitalpins 5–10.
Stromversorgung: Servos brauchen 5 V, aber externes Netzteil (≥ 2 A) – Arduino kann Summenstrom nicht liefern. Gemeinsame Masse (Arduino GND = Netzteil GND = Servo GND).
Benötigte Bauteile
- 3× MG996R Servo
- 3× SG90 Micro Servo
- HC-05 Bluetooth Modul
- Arduino Board (Uno/Nano/Mega)
- 5 V 2 A DC-Netzteil
Arduino Code (strukturiert)
Code in Abschnitten erklärt, am Ende vollständiger Sketch.
1. Bibliotheken & Variablen
#include <SoftwareSerial.h>
#include <Servo.h>
Servo servo01, servo02, servo03, servo04, servo05, servo06;
SoftwareSerial Bluetooth(3, 4); // Arduino RX=3, TX=4 → HC-05 TX, RX
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // aktuell
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // vorher
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // Schritte
int speedDelay = 20;
int index = 0;
String dataIn = "";
2. Setup: Initialposition & Bluetooth
void setup() {
servo01.attach(5); servo02.attach(6); servo03.attach(7);
servo04.attach(8); servo05.attach(9); servo06.attach(10);
Bluetooth.begin(38400); // HC-05 Default Baud
Bluetooth.setTimeout(1);
delay(20);
// Initialposition
servo1PPos = 90; servo01.write(servo1PPos);
servo2PPos = 150; servo02.write(servo2PPos);
servo3PPos = 35; servo03.write(servo3PPos);
servo4PPos = 140; servo04.write(servo4PPos);
servo5PPos = 85; servo05.write(servo5PPos);
servo6PPos = 80; servo06.write(servo6PPos);
}
3. Loop: Bluetooth-Daten verarbeiten
void loop() {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString(); // String empfangen
// Servo 1 (Basis) - Präfix "s1"
if (dataIn.startsWith("s1")) {
String val = dataIn.substring(2); // ab Index 2
servo1Pos = val.toInt();
moveServoSlow(servo01, servo1PPos, servo1Pos, 20);
servo1PPos = servo1Pos;
}
// Servo 2 (Schulter) - "s2", Delay 50
if (dataIn.startsWith("s2")) {
String val = dataIn.substring(2);
servo2Pos = val.toInt();
moveServoSlow(servo02, servo2PPos, servo2Pos, 50);
servo2PPos = servo2Pos;
}
// Servo 3 (Ellbogen) - "s3", Delay 30
if (dataIn.startsWith("s3")) { /* analog, delay 30 */ }
// Servo 4 (Handgelenk Roll) - "s4", Delay 30
if (dataIn.startsWith("s4")) { /* analog, delay 30 */ }
// Servo 5 (Handgelenk Pitch) - "s5", Delay 30
if (dataIn.startsWith("s5")) { /* analog, delay 30 */ }
// Servo 6 (Greifer) - "s6", Delay 30
if (dataIn.startsWith("s6")) { /* analog, delay 30 */ }
// SAVE gedrückt
if (dataIn.startsWith("SAVE")) {
servo01SP[index] = servo1PPos;
servo02SP[index] = servo2PPos;
servo03SP[index] = servo3PPos;
servo04SP[index] = servo4PPos;
servo05SP[index] = servo5PPos;
servo06SP[index] = servo6PPos;
index++;
}
// RUN gedrückt
if (dataIn.startsWith("RUN")) {
runservo();
}
// RESET gedrückt
if (dataIn == "RESET") {
memset(servo01SP, 0, sizeof(servo01SP));
memset(servo02SP, 0, sizeof(servo02SP));
memset(servo03SP, 0, sizeof(servo03SP));
memset(servo04SP, 0, sizeof(servo04SP));
memset(servo05SP, 0, sizeof(servo05SP));
memset(servo06SP, 0, sizeof(servo06SP));
index = 0;
}
}
}
4. Hilfsfunktion: Langsame Servobewegung
void moveServoSlow(Servo &servo, int fromPos, int toPos, int dly) {
if (fromPos > toPos) {
for (int j = fromPos; j >= toPos; j--) {
servo.write(j);
delay(dly);
}
} else if (fromPos < toPos) {
for (int j = fromPos; j <= toPos; j++) {
servo.write(j);
delay(dly);
}
}
}
5. Automatik-Modus: Gespeicherte Schritte abfahren
void runservo() {
while (dataIn != "RESET") {
for (int i = 0; i <= index - 2; i++) {
// Bluetooth während Bewegung prüfen (PAUSE, SPEED, RESET)
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if (dataIn == "PAUSE") {
while (dataIn != "RUN") {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if (dataIn == "RESET") break;
}
}
}
if (dataIn.startsWith("ss")) { // Speed Slider
String val = dataIn.substring(2);
speedDelay = val.toInt();
}
}
// Alle 6 Servos zum nächsten Schritt bewegen
moveServoArray(servo01, servo01SP, i, speedDelay);
moveServoArray(servo02, servo02SP, i, speedDelay);
moveServoArray(servo03, servo03SP, i, speedDelay);
moveServoArray(servo04, servo04SP, i, speedDelay);
moveServoArray(servo05, servo05SP, i, speedDelay);
moveServoArray(servo06, servo06SP, i, speedDelay);
}
}
}
void moveServoArray(Servo &servo, int arr[], int i, int dly) {
if (arr[i] == arr[i+1]) return;
if (arr[i] > arr[i+1]) {
for (int j = arr[i]; j >= arr[i+1]; j--) { servo.write(j); delay(dly); }
} else {
for (int j = arr[i]; j <= arr[i+1]; j++) { servo.write(j); delay(dly); }
}
}
Android App (MIT App Inventor)
App-Struktur:
- Oben: Bluetooth Connect/Disconnect Buttons
- Links: Roboterarm-Bild, Rechts: 6 Servo-Slider + Speed-Slider
- Unten: SAVE, RUN, RESET Buttons + Schrittzähler
Jeder Slider sendet bei Änderung: "s" + ServoNummer + Wert (z. B. "s1120"). Speed-Slider: "ss" + Wert. Buttons senden "SAVE", "RUN", "RESET".
Downloads
- MIT App Inventor Projektdatei (.aia) – 24,85 KB
- Android App (APK) – 2,57 MB, direkt installierbar
Kompletter Arduino Sketch
/* DIY Arduino Robot Arm Smartphone Control
* by Dejan, www.HowToMechatronics.com
*/
#include <SoftwareSerial.h>
#include <Servo.h>
Servo servo01, servo02, servo03, servo04, servo05, servo06;
SoftwareSerial Bluetooth(3, 4);
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos;
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos;
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50];
int speedDelay = 20;
int index = 0;
String dataIn = "";
void setup() {
servo01.attach(5); servo02.attach(6); servo03.attach(7);
servo04.attach(8); servo05.attach(9); servo06.attach(10);
Bluetooth.begin(38400); Bluetooth.setTimeout(1); delay(20);
servo1PPos = 90; servo01.write(servo1PPos);
servo2PPos = 150; servo02.write(servo2PPos);
servo3PPos = 35; servo03.write(servo3PPos);
servo4PPos = 140; servo04.write(servo4PPos);
servo5PPos = 85; servo05.write(servo5PPos);
servo6PPos = 80; servo06.write(servo6PPos);
}
void loop() {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if (dataIn.startsWith("s1")) { servo1Pos = dataIn.substring(2).toInt(); moveServoSlow(servo01, servo1PPos, servo1Pos, 20); servo1PPos = servo1Pos; }
if (dataIn.startsWith("s2")) { servo2Pos = dataIn.substring(2).toInt(); moveServoSlow(servo02, servo2PPos, servo2Pos, 50); servo2PPos = servo2Pos; }
if (dataIn.startsWith("s3")) { servo3Pos = dataIn.substring(2).toInt(); moveServoSlow(servo03, servo3PPos, servo3Pos, 30); servo3PPos = servo3Pos; }
if (dataIn.startsWith("s4")) { servo4Pos = dataIn.substring(2).toInt(); moveServoSlow(servo04, servo4PPos, servo4Pos, 30); servo4PPos = servo4Pos; }
if (dataIn.startsWith("s5")) { servo5Pos = dataIn.substring(2).toInt(); moveServoSlow(servo05, servo5PPos, servo5Pos, 30); servo5PPos = servo5Pos; }
if (dataIn.startsWith("s6")) { servo6Pos = dataIn.substring(2).toInt(); moveServoSlow(servo06, servo6PPos, servo6Pos, 30); servo6PPos = servo6Pos; }
if (dataIn.startsWith("SAVE")) {
servo01SP[index] = servo1PPos; servo02SP[index] = servo2PPos;
servo03SP[index] = servo3PPos; servo04SP[index] = servo4PPos;
servo05SP[index] = servo5PPos; servo06SP[index] = servo6PPos;
index++;
}
if (dataIn.startsWith("RUN")) { runservo(); }
if (dataIn == "RESET") {
memset(servo01SP, 0, sizeof(servo01SP)); memset(servo02SP, 0, sizeof(servo02SP));
memset(servo03SP, 0, sizeof(servo03SP)); memset(servo04SP, 0, sizeof(servo04SP));
memset(servo05SP, 0, sizeof(servo05SP)); memset(servo06SP, 0, sizeof(servo06SP));
index = 0;
}
}
}
void moveServoSlow(Servo &servo, int from, int to, int dly) {
if (from > to) for (int j = from; j >= to; j--) { servo.write(j); delay(dly); }
else if (from < to) for (int j = from; j <= to; j++) { servo.write(j); delay(dly); }
}
void runservo() {
while (dataIn != "RESET") {
for (int i = 0; i <= index - 2; i++) {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if (dataIn == "PAUSE") {
while (dataIn != "RUN") {
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.readString();
if (dataIn == "RESET") break;
}
}
}
if (dataIn.startsWith("ss")) { speedDelay = dataIn.substring(2).toInt(); }
}
moveServoArray(servo01, servo01SP, i, speedDelay);
moveServoArray(servo02, servo02SP, i, speedDelay);
moveServoArray(servo03, servo03SP, i, speedDelay);
moveServoArray(servo04, servo04SP, i, speedDelay);
moveServoArray(servo05, servo05SP, i, speedDelay);
moveServoArray(servo06, servo06SP, i, speedDelay);
}
}
}
void moveServoArray(Servo &servo, int arr[], int i, int dly) {
if (arr[i] == arr[i+1]) return;
if (arr[i] > arr[i+1]) for (int j = arr[i]; j >= arr[i+1]; j--) { servo.write(j); delay(dly); }
else for (int j = arr[i]; j <= arr[i+1]; j++) { servo.write(j); delay(dly); }
}
Viel Spaß beim Bauen & Programmieren! Fragen in den Kommentaren. Meine Arduino-Projektsammlung.
Herstellungsprozess
- Smartes Sparschwein: Münzprüfer mit Arduino Nano steuern
- Intelligentes Voltmeter mit Arduino & Smartphone bauen – Einfaches DIY-Projekt
- Fernsteuerung eines Roboterarms per IoT: Eigenbau mit Arduino MKR1000
- Servogesteuerter Hindernisvermeidungs-Roboter: Bauen mit Arduino & HC-SR04
- LED per Bluetooth mit Arduino steuern – Einfache DIY-Anleitung
- Arduino-basierter 6-DoF Roboterarm mit Nunchuk-Steuerung
- Zwei Schrittmotoren mit Arduino Nano & Joystick steuern – Einfaches Tutorial
- MobBob: Eigenen Arduino-Roboter bauen, per Android-Smartphone steuern
- LittleArm 2C: Robuster 3D-gedruckter Arduino-Roboterarm für STEM-Bildung
- Yama Seiki GA-2000CR: Kompaktes Drehzentrum mit Roboterarm & Palettensystem