Introduction: Wire Controlled Robot Arm

This a tutorial on how to make a robot arm controlled by wires. The advantage of using wires is that your arm is lighter and you can have all your motors in the bottom of your arm, making building and maintenance easier. Here is a video of the arm in action. I plan to add a claw in the future so it can pick things up and not just push them around.

3D Printables:

Here and Here


6 Servo Motors (MG995)

Arduino Uno

About 6 meters of plastic coated steel wire (0.5mm)

Box 23x33x10 (may be narrower, definitely should not be shorter)

Plank of wood 33x10

Nuts and Bolts

Pipe 14 cm (this is needed to guide the strings)

4 L-Brackets

5-volt adapter

2 7-way terminal blocks

Breadboard wires

3D Printed Components (Not designed by me, links to elements in the description):

3 “Bolts”

2 “Element 1”

1 “Element 2”

2 “Element 3”

1 Base Connector

Step 1: Print All the 3D Components

You may need support for the bolt holes and arches but make sure not to add support to the body of your components; this will close up the small wire holes and you will need to make new holes

Step 2: ​(Optional) Attach a Plank of Wood to the Bottom of Your Box to Strengthen It

My box was pretty weak, yours may not be

Step 3: Measure and Cut a Plank of Wood to Fit the Box

Step 4: Mark the Positions of the Motors

make sure none of the arms touch each other

Step 5: Mark the Positions of the Brackets and the Pipe.

The pipe should be placed around one centimeter in front of the hole

Step 6: Drill a Hole for the Cables Coming Out of Your Box (USB and Power)

Step 7: Drill and Saw All the Marked Holes

Step 8: Attach the Motors and Pipe to the Plank

Step 9: Attach the Plank to the Box With the L-Brackets

Step 10: Take Your Terminal Blocks and Solder the Wires Together

Step 11: Cut the End of the Adapter Power Cord and Strip the Wires

Step 12: Identify and Mark the Plus and Minus Wires

Step 13: Attach the Wires to the Terminal Blocks So That All the + Servo Wires and the + Wire From the Power Cord Are Connected, Same Goes for the - Wires.

Step 14: Cut the Head Off a Breadboard Wire

Attach the stripped end of the breadboard wire to the minus terminal block and the pin end to the ground pin in your arduino. If you don’t do this the motors will move erratically without any input.

Step 15: Drill Three Holes in the Bottom of the Box for the Wires Coming Out of Your Arm.

The holes should match up to the holes in the base connector.

Step 16: Attach the Base Connector to the Box

Step 17: Use a Knife or Nail File to Make the Wire Grooves Deeper

The wire grooves for elements 2 and 3 are too shallow.

Step 18: Construct the Arm

Construct the arm according to the instructions here you may need to file the parts so they fit

Step 19: Install Processing and Arduino

Step 20: Paste the Code Programs.

The code is at the bottom of this page

Step 21: Connect the Servo Control Pins to the Arduino

I connected the first motor to the third digital pin, the second motor to the fourth digital pin and so on. Make sure the ground pin is still connected to the - terminal block.

Step 22: Press the Reset Button in Processing, This Will Set All Arms to 90 Degrees

Step 23: Fix the Servo Arms to the Motor Horizontally

Step 24: Thread the Wires Through the Arms So That There Is No Slack

Make sure you thread the wire through as many holes as you can, this will hold it temporarily and be easy to remove.

Step 25: Test the Arm and Tighten or Loosen the Wires As Needed

Step 26: Hot Glue the Wires to the Servo Arms to Make It Permanent

Step 27: Notes

I used 0.5mm jewelry wire but 0.4mm should be fine. The original design used PVC wire but that broke too easily and was hard to work with.

If you are going to be moving the arm in a car or bike wrap the arm joints in tape to make sure they don’t pop out. This is especially important for element 1.

When I started this project I was wondering why I could only find one tutorial on how to make an arm controlled by wires. Now I understand why this isn’t the most common way to make a hobby robot arm. The wires sometimes fall out of their grooves and the whole thing is kind of flimsy. I don’t know if the problems are because I don’t have a lot of experience or if the whole idea is problematic although I am sure that it would be more solid if I knew what I was doing.

Step 28: Troubleshooting

The wire holes are closed up in the 3D printed elements:

You added support for the whole element instead of just the bolt holes. Either re-print the element or open up the holes with a really hot needle.

The COM port is closed, you can’t communicate with the arduino:

Your arduino may not accept USB 3 ports (mine didn’t), you can either buy a USB 2 extension cable or use a computer that has USB 2 ports

The code isn’t working:

Follow this tutorial and modify it to make your own code

A part of the arm is not moving:

The wires might have tangled up, to check this take the servo arm off the servo and try pulling the wires by hand. Untangle the wires and if it’s still difficult to pull the wires try using some WD-40 or a lubricant to make movement easier

Step 29: Links

Step 30: Code

Modified from this code

Arduino Code:

#include //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 =; //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'); }

Step 31: More Pictures