Robot Arm

Dit is een tutorial hoe je een robotarm kan maken die wordt bestuurd door draden. Het voordeel van het gebruik van draden is dat jouw arm lichter is en dat je al jouw motoren onder in je arm kan hebben, waardoor bouwen en onderhoud eenvoudiger wordt. Hier is een video van de arm in actie. Ik ben van plan om in de toekomst een klauw toe te voegen, zodat ik dingen kan oppikken en niet alleen maar duwen.

Components:

  • 6 Servo Motors (MG995)
  • Arduino Uno
  • 6 meter staaldraad (0.5mm)
  • Box 23x33x10 (mag smaller zijn, zeker niet korter)
  • Plank van hout 33×10
  • Bouten en moeren
  • Buis 14 cm (dit is nodig om de draden te geleiden)
  • 4 L-Beugel
  • 5-volt adapter
  • 2 7-way aansluitklemmen
  • Breadboard-draden

3D gedrukt components:

  • Deze zijn niet door mij gemaakt, vind ze hier
  • 3 “Bolts”
  • 2 “Element 1”
  • 1 “Element 2”
  • 2 “Element 3”
  • 1 Modified Element

Stappen:

  • Druk alle 3D-componenten af. Mogelijk heb je ondersteuning (printsupport) nodig voor de bolt gaten en bogen, maar zorg ervoor dat jij geen ondersteuning toevoegt aan de body van jouw component; dit zal de kleine draadgaten dichten en je zult nieuwe gaten moeten maken.
  • (Optioneel) Bevestig een houten plank aan de onderkant van jouw doos om deze te versterken.
  • Meet en snijd een plank van hout om in de doos te passen.
  • Markeer de posities van de motoren, zorg ervoor dat geen van de armpjes elkaar raken. 
  • Markeer de posities van de beugels en de pijp. De buis moet ongeveer een centimeter voor het gat worden geplaatst.
  • Boor een gat voor de kabels die uit jouw doos komen (USB en voeding)
  • Boor en zag alle gemarkeerde gaten 
  • Bevestig de motoren en de buis aan de plank
  • Bevestig de plank aan de doos met de L-beugels
  • Soldeer de draden van de aansluitklemmen zo dat alle positieve draden met elkaar zijn verbonden en alle negatieve draden met elkaar zijn verbonden
  • Knip het uiteinde van het netsnoer van de adapter en strip de draden
  • Identificeer en markeer de plus- en min-draden
  • Bevestig de draden aan de aansluitblokken zodat alle + servodraden en de + draad van het netsnoer zijn aangesloten, hetzelfde geldt voor de – draden.
  • Snijd de kop van een breadboard-draad af
  • Bevestig het gestripte uiteinde van de breadboard-draad aan het negatieve aansluitblok en het peneinde aan de grondpin in jouw arduino. Als jij dit niet doet, zullen de motoren onregelmatig en zonder invoer bewegen.
  • Boor drie gaten in de bodem van de doos voor de draden die uit je arm komen. De gaten moeten overeenkomen met de gaten in het modified element.
  • Bevestig de modified element aan de doos
  • De draadgroeven voor elementen 2 en 3 zijn te ondiep. Gebruik een mes of nagelvijl om ze dieper te maken.
  • Construeer de arm volgens de instructies hier, het kan zijn dat je de onderdelen moet afvijlen zodat ze passen
  • Installeer Processing en Arduino
  • Plak de code vanaf onderkant van dit post in de programma’s. Jij zou een GUI zoals deze moeten krijgen:
  • Verbind de servo controlepennen met de Arduino, ik verbond de eerste motor met de derde digitale pin, de tweede motor met de vierde digitale pin enzovoort. Zorg ervoor dat de aardingspen nog steeds is aangesloten op het – aansluitklem.
  • Druk in Processing op de reset knop. Hierdoor worden alle motoren op 90 graden gezet
  • Bevestig de servo-armpjes horizontaal aan de motor [Picture of arms] 
  • Leid de draden door de armen zodat er geen speling is. Zorg ervoor dat je de draad zo veel gaten doorspeelt als je kunt, deze houdt hem tijdelijk vast en is gemakkelijk te verwijderen.
  • Test de arm 
  • Heet lijm de draden aan de servo-armen.

Tips:

Ik gebruikte sieradendraden van 0,5 mm, maar 0,4 mm zou ook goed moeten zijn. Het originele ontwerp gebruikte PVC-draad, maar dat brak te gemakkelijk en was moeilijk om mee te werken.

Als je de arm in een auto of fiets gaat bewegen, wikkel je de armverbindingen in plakband om er zeker van te zijn dat ze niet naar buiten komen. Dit is vooral belangrijk voor het eerste verbinding.

Probleemoplossen:

De draadgaten worden gesloten in de 3D-geprinte elementen:

Jij hebt ondersteuning voor het hele element toegevoegd in plaats van alleen de boutgaten. Druk het element opnieuw af of open de gaten met een zeer hete naald.

De COM-poort is gesloten, je kunt niet communiceren met de arduino:

Jouw arduino accepteert mogelijk geen USB 3 poorten, jij kan een USB 2 verlengkabel kopen of een computer gebruiken met USB 2 poorten

De code werkt niet:

Volg deze tutorial

Een deel van de arm beweegt niet:

De draden zijn mogelijk in de war geraakt, om dit te controleren neem jij de servo-armpje van de servo af en probeert de draden met de hand te trekken. Haal de draden uit de servo-armpje, maak de draden los en als het nog steeds lastig is om aan de draden te trekken, probeer dan een WD-40 of een smeermiddel te gebruiken om beweging te vergemakkelijken

Links:

Arduino Code:

#include <Servo.h>
//Declare the motors
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;
//All the motors are set at 90 degrees by default
int current1 = 90;
int current2 = 90;
int current3 = 90;
int current4 = 90;
int current5 = 90;
int current6 = 90;
//Minimum and Maximum Degrees the motors can reach
int mini1 = 0;
int maxi1 = 180;
int mini2 = 0;
int maxi2 = 180;
int mini3 = 0;
int maxi3 = 180;
int mini4 = 0;
int maxi4 = 180;
int mini5 = 0;
int maxi5 = 180;
int mini6 = 0;
int maxi6 = 180;
//Degrees to be added or subtracted from current position
int degreesFoward = 5;
//Delay so two functions don't happen in the wrong order
int delayBetweenSteps = 100;
void setup() {
  //Set control pins for each motor
  myservo1.attach(3);
  myservo2.attach(4);
  myservo3.attach(5);
  myservo4.attach(6);
  myservo5.attach(7);
  myservo6.attach(8);
 
  //Set all motors to the default setting
  myservo1.write(current1);
  myservo2.write(current2);
  myservo3.write(current3);
  myservo4.write(current4);
  myservo5.write(current5);
  myservo6.write(current6);
 
  //start serial communication @9600 bps
  Serial.begin(9600);	
  }
void loop(){
  if(Serial.available()){  //if data is available to read
	char val = Serial.read(); //put it into this char
	//Motor Controls
	if(val == 'a' && current1 + degreesFoward < maxi1){   	//if the servo 1 foward button is pressed and current degree is less than maximum degree
  	myservo1.write(current1 + degreesFoward); //move the motor by degreesFoward
  	current1 = current1 + degreesFoward; //remember where the motor is now
  	delay(delayBetweenSteps); //wait a bit
  	}
	if(val == 'b' && current1 + degreesFoward  > mini1){	
  	myservo1.write(current1 - degreesFoward);
  	current1 = current1 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'c' && current2 < maxi2){ 	
  	myservo2.write(current2 + degreesFoward);
  	current2 = current2 + degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'd' && current2 > mini2){  
  	myservo2.write(current2 - degreesFoward);
  	current2 = current2 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'e' && current3 < maxi3){ 
  	myservo3.write(current3 + degreesFoward);
  	current3 = current3 + degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'f' && current3 > mini3){ 
  	myservo3.write(current3 - degreesFoward);
  	current3 = current3 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
  	if(val == 'g' && current4 < maxi4){
  	myservo4.write(current4 + degreesFoward);
  	current4 = current4 + degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'h' && current4 > mini4){ 
  	myservo4.write(current4 - degreesFoward);
  	current4 = current4 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
  	if(val == 'i' && current5 < maxi5){  
  	myservo5.write(current5 + degreesFoward);
  	current5 = current5 + degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'j' && current5 > mini5){ 
  	myservo5.write(current5 - degreesFoward);
  	current5 = current5 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
  	if(val == 'k' && current6 < maxi6){ 
  	myservo6.write(current6 + degreesFoward);
  	current6 = current6 + degreesFoward;
  	delay(delayBetweenSteps);
  	}
	if(val == 'l' && current6 > mini6){
  	myservo6.write(current6 - degreesFoward);
  	current6 = current6 - degreesFoward;
  	delay(delayBetweenSteps);
  	}
  	
	//Speed Controls
	if(val == 'w'){ //If speed 1 button pressed
  	degreesFoward = 1;
  	delay(delayBetweenSteps);
  	}
	if(val == 'x'){ //If speed 5 button pressed
  	degreesFoward = 5;
  	delay(delayBetweenSteps);
  	}
  	
	if(val == 'y'){ //If speed 10 button pressed
  	degreesFoward = 10;
  	delay(delayBetweenSteps);
  	}
	if(val == 'z'){ //If speed 20 button pressed
  	degreesFoward = 20;
  	delay(delayBetweenSteps);
  	}
  	
	if(val == 'r'){ //If speed 20 button pressed
  	myservo1.write(90);
  	current1 = 90;
  	myservo2.write(90);
  	current2 = 90;
  	myservo3.write(90);
  	current3 = 90;
  	myservo4.write(90);
  	current4 = 90;
  	myservo5.write(90);
  	current5 = 90;
  	myservo6.write(90);
  	current6 = 90;
  	delay(delayBetweenSteps);
  	}
	}
  }







Processing Code:

import processing.serial.*;
import controlP5.*; //import ControlP5 library
Serial port;
ControlP5 cp5; //create ControlP5 object
PFont font;
void setup(){ //same as arduino program
  size(300, 700);	//window size, (width, height)
 
  printArray(Serial.list());   //prints all available serial ports
  //If you are having a problem it probably comes from here
  String portName = Serial.list()[0];
  port = new Serial(this, portName, 9600);  //i have connected arduino to com3, it would be different in linux and mac os
  //lets add buton to empty window
 
  cp5 = new ControlP5(this);
  font = createFont("Arial", 13);	// custom fonts for buttons and title
// Speed Control Buttons
  cp5.addButton("One") 	//"One" is the name of button
	.setPosition(50, 50)  //x and y coordinates of upper left corner of button
	.setSize(55, 25)  	//(width, height)
	.setFont(font)
  ; 
  cp5.addButton("Five") 	
	.setPosition(110, 50)
	.setSize(55, 25)
	.setFont(font)
  ;
 
  cp5.addButton("Ten") 
	.setPosition(170, 50)
	.setSize(55, 25)
	.setFont(font)
  ;
 
  cp5.addButton("Twenty")
	.setPosition(230, 50)
	.setSize(55, 25) 
	.setFont(font)
  ;
  
	cp5.addButton("Reset") 	
	.setPosition(110, 2)
	.setSize(55, 25)
	.setFont(font)
  ;
 
  cp5.addButton("Servo_1_Foward")  
	.setPosition(50, 90)
	.setSize(190, 40) 	
	.setFont(font)
  ;  
// Motor Control Buttons
  cp5.addButton("Servo_1_Back")	
	.setPosition(50, 140)
	.setSize(190, 40) 
	.setFont(font)
  ;
 
	cp5.addButton("Servo_2_Foward")
	.setPosition(50, 190)
	.setSize(190, 40)  
	.setFont(font)
  ;  
  cp5.addButton("Servo_2_Back")  
	.setPosition(50, 240)
	.setSize(190, 40)  
	.setFont(font)
  ;
 
	cp5.addButton("Servo_3_Foward") 
	.setPosition(50, 290)
	.setSize(190, 40) 	
	.setFont(font)
  ;  
  cp5.addButton("Servo_3_Back")  
	.setPosition(50, 340)
	.setSize(190, 40)  	//(width, height)
	.setFont(font)
  ;
 
	cp5.addButton("Servo_4_Foward")	
	.setPosition(50, 390)
	.setSize(190, 40)  
	.setFont(font)
  ;  
  cp5.addButton("Servo_4_Back")  
	.setPosition(50, 440)
	.setSize(190, 40)  	//(width, height)
	.setFont(font)
  ;
 
	cp5.addButton("Servo_5_Foward") 
	.setPosition(50, 490)
	.setSize(190, 40)	
	.setFont(font)
  ;  
  cp5.addButton("Servo_5_Back")  
	.setPosition(50, 540)
	.setSize(190, 40)  
	.setFont(font)
  ;
 
	cp5.addButton("Servo_6_Foward")  
	.setPosition(50, 590)
	.setSize(190, 40)  
	.setFont(font)
  ;  
  cp5.addButton("Servo_6_Back") 
	.setPosition(50, 640)
	.setSize(190, 40)	
	.setFont(font)
  ;
 
}
void draw(){  //same as loop in arduino
  background(192, 215, 249); // background color of window (r, g, b) or (0 to 255)
 
  //Add text saying speed control is speed control
  fill(0, 10, 25);           	//text color (r, g, b)
  textFont(font);
  text("Speed Control", 50, 40);  // ("text", x coordinate, y coordinat)
}
//lets add some functions to our buttons
//so when you press any button, it sends particular char over serial port
//I am sure it is possible to send strings instead of chars, and it would make more sense but I don’t know how to do it
//Speed Control Commands
void One(){
  port.write('w');
}
void Five(){
  port.write('x');
}
void Ten(){
  port.write('y');
}
void Twenty(){
  port.write('z');
}
//Motor Control Commands
void Servo_1_Foward(){
  port.write('a');
}
void Servo_1_Back(){
  port.write('b');
}
void Servo_2_Foward(){
  port.write('c');
}
void Servo_2_Back(){
  port.write('d');
}
void Servo_3_Foward(){
  port.write('e');
}
void Servo_3_Back(){
  port.write('f');
}
void Servo_4_Foward(){
  port.write('g');
}
void Servo_4_Back(){
  port.write('h');
}
void Servo_5_Foward(){
  port.write('i');
}
void Servo_5_Back(){
  port.write('j');
}
void Servo_6_Foward(){
  port.write('k');
}
void Servo_6_Back(){
  port.write('l');
}
void Reset(){
  port.write('r');
}