Robotic Arm

I’ve begun making a robotic arm - in fact, the building was quite easy as I decided in the end to use off the shelf parts for it so that I could retask them when I’ve finished playing with my arm.

The arm doesn’t work yet, it still needs wiring up along it’s length and to the arduino. In fact, I’m not sure the servos will carry the weight of the arm itself, but this is an initial effort so I’m anticipating one step forward for 5 steps back :slight_smile:

I have a small bit of code (just to test out my gripper servo really)

/ Test servo sketch by Andy Crook Feb 2009
// simply cycle a servo gripper open and closed. The values are not 180 and 0 because
// my gripper opens at 30 and closes fully at 170.

#include <Servo.h> 

Servo myservo;  // create servo object to control a servo 

void setup() 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 

void loop() 
    myservo.write(170);              // tell servo to close to setting 170          
    myservo.write(30);              // tell servo to open to setting 30

Hi Andy, looks like a good start. I think you may be correct about needing beefier servos further down the arm ( are those HS322 HD?)

Looking forward to seeing more ;)

Have fun!

Yeah 322s with carbonite gearing. I have 3 422's to swap around with as well, one in the base and two in the gripper at present but I think I may shorten the end of the arm, and put in the 422's at the base angle and first joint where the weight of the arm would produce most problems. I can also simply remove the tubes to shorten the arms drastically if needed, probably on the second tube. Have to play with it all and see I guess.

Real industrial articulated robots use a counter weight or spring on the arm axis to balance the weigh of the arm and end effector, this reduces the load on the motor. Maybe you can try something like that?


That's a possibility if it comes down to it. I don't want to have to buy very expensive servos for it certainly.

Well, after a long time (and a birthday) I’ve got some more powerful servos for my arm, and it’s pretty much done apart from some wiring. I’ve left this till last so I could focus on the software.

So lastly I need to wire up all the servos, and beautify the wiring so that the arm is free to move. I also need to bolt the base down as the arm is quite heavy now and tips over.

I’ve got the arduino sketch taking command over serial, then setting the appropriate servo, and a more complex VB app which will send servo positions to the arduino. In the end, I’m going to be able to record sets of servo positions so I can calibrate the arm for positions in front of it, and switch between them.

Here is the current GUI for the VB app. Simple at the moment but it’s just for moving the servos. It’s a real pleasure to move a slider in a VB app and see the arm move in the real world :slight_smile:

Here’s the sketch on the Arduino as it currently stands. It has been a trial to get VB to output the right kind of serial bytes to the arduino - i thought it would be simpler, but I got it sorted in the end. This code may change a bit still, but most of the coding will be done via VB now.

// This Arduino sketch controls 6 servos on a robotic arm by receiving commands over a serial COM port
// by Andy Crook 2009

#include <ServoTimer2.h>  // the servo library

// define the pins for the servos
#define basePin 2
#define shoulderPin 3
#define elbowPin   4
#define wristPin 5
#define wristrotatePin 6
#define gripPin   7

#define MIN_PULSE  540 // pulse in microseconds for servo's
#define MAX_PULSE  2200

ServoTimer2 servoBase;    // declare variables for the 6 servos
ServoTimer2 servoShoulder;
ServoTimer2 servoElbow;    
ServoTimer2 servoWrist;
ServoTimer2 servoWristrotate;
ServoTimer2 servoGrip;   

int incomingByte = 0;  // for incoming data
int servovalue = 0; // for servo value
int pos = 0;
long val0 = 0;

int base = 0;
int shoulder = 0;
int elbow = 0;
int wrist = 0;
int wristrotate = 0;
int grip = 0;

void setup() {
  servoBase.attach(basePin);           // attach all pins to the servos
  servoBase.write(1000);               // set initial values for all servos
  servoShoulder.write(1000);           // will calibrate these once arm is built 
  servoElbow.write(1000);              // for a good 'initial setting'
  Serial.begin(9600);   // opens serial port and sets data rate to 9600 bps

void loop()

  if (Serial.available() > 1) {      // if there are more than 1 bytes of data in the buffer read them in 2 byte chunks
    // this will cycle round every 2 bytes. As long as you send 2 bytes at a time to the buffer
    // they should all set fine. If one byte is sent it will wait for the next one but
    // if no appropriate header byte is found, it will do nothing but clear the buffer
    // the servovalue byte must be from 0 - 180 for the map function to work right
    // example setting for all 6 servos:
    // As a byte sequence this is: 200 65 201 66 202 67 203 68 204 69 205 70

    // read incoming byte
    incomingByte =;
    servovalue =;
    Serial.print("Servo Command: ");
    Serial.print(incomingByte, DEC);
    //incomingByte = (incomingByte, DEC);
    if (incomingByte == 200){
       Serial.print(" - BASE ");
    if (incomingByte == 201){
       Serial.print(" - SHOULDER ");
    if (incomingByte == 202){
       Serial.print(" - ELBOW ");
    if (incomingByte == 203){
       Serial.print(" - WRIST ");
    if (incomingByte == 204){
       Serial.print(" - WRIST ROTATE ");
    if (incomingByte == 205){
       Serial.print(" - GRIP ");
    if (incomingByte > 199 && incomingByte < 206) // if command is valid, state servo setting
    Serial.print(" - VALUE: ");
    Serial.print(servovalue, DEC);
    Serial.println(" Degrees");
   // Serial.println(" ");
      Serial.println(" Command not recognised "); // if command header byte is not 200-205, signal error
    if (incomingByte == 200) // sets base to value following 200
      pos = servovalue;
      base = pos;  // keep value of base set for future use (not implemented yet)
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoBase.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (incomingByte == 201) // sets shoulder to value following 201
      pos = servovalue;
      shoulder = pos;
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoShoulder.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (incomingByte == 202) // sets elbow to value following 202
      pos = servovalue;
      elbow = pos;
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoElbow.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (incomingByte == 203) // sets wrist to value following 203
      pos = servovalue;
      wrist = pos;
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoWrist.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (incomingByte == 204) // sets wristrotate to value following 204
      pos = servovalue;
      wristrotate = pos;
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoWristrotate.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (incomingByte == 205) // sets grip to value following 205
      pos = servovalue;
      grip = pos;
      val0 = map(pos, 0, 180, MIN_PULSE , MAX_PULSE ); 
      servoGrip.write(val0);              // tell servo to go to position in variable 'pos' from 0 to 180
  if (Serial.available() == 1) // if there is only one byte left after read, then read it to discard it
    Serial.println("Serial Buffer ERROR: One byte left -> Discarded");;



Keep up the good work. I hope to start a project like this in the future.

Looks like you've got the forward kinematics taken care of. Your links do appear rather long, it looks like its asking a lot out of the bottom servo. Note the short links on your computer screen in DSCF1314rs.JPG. I would put a beefier servo for that placement.

Post more of your VB development, I am interested in that. Good job!

Once I get around to the final wiring and the like, I'll get to adding to and tidying up the code, then post some source but it's nothing special, just simple serial commands to the arduino which sets the servo angle. I may try to code an IK solver for the XYZ space the arm can reach, which I imagine would be quite a challenge :)