projects‎ > ‎

Robotic Hand

I had some servos in the parts bin so I decided to make a robot hand.  Got some plastic tubing from the local hardware store and used some pipe cleaners that I had from another project. Wooden skewers served at the backbone for connecting the servos together.

I had found medium torque servos for $7 a piece online, but since this project that item has been deactivated :(  The tubing was about $0.60 per foot from a local hardware store.  The skewers I can't recall the price, but they're super cheap for an entire bag of them.  I used 20lb SpiderWire fishing line, entire spool was about $10.  My Arduino setup is always an ATmega328, 16Mhz resonator, resistor and cap for reset pin so the entire thing comes to about $8-$10.  One entire hand can be assembled for around $50 which is much less than any retail 5 fingered robotic hand I've seen online.  It can hold more than 1 pound of weight - much more than I expected.  Holding a large, heavy object takes about 2.5 amps so keep that in mind if you're looking to make this battery powered.


Pipe Cleaners:
A simple start right after the brainstorming...


I taped the fingers because they weren't straight - didn't help.



Fishing Line:
SpiderWire is strong stuff!


This is with the fishing line instead of the pipe cleaners.  Glued to a wooden board for stability.


Holding up a full sunblock container.





Fingers closed almost to perfection.  Took lots of modification of the cuts in each finger tube and fishing line adjustments to the servos.


Looking down the fingers while closed.






Remote Control and Video Streaming:

So I wanted to let other people control the hand and see it working.  This Ustream channel has the live video.  Head to the website http://navic.godsofsand.com to view the embedded live stream (same as below) as well as links to open and close the hand yourself.  The hand was invited to become a part of the livebots.cc group of internet controlled robots so head over there and check out this hand and control it yourself.



















Arduino Sketches:

Hand.pde is the stand alone arduino sketch.  It's the 5 servos and a button.  When you press the button the hand either opens or closes, depending on what state it is in when the button is pressed.

Hand_Network.pde is for use with the Arduino Ethernet Shield (now available at RadioShack, but more expensive)  This code sets up a telnet server on the default port 23.  When a client connects they can enter two commands:  0 = Close hand and 1 = Open hand.  To prevent large power usage, the hand will remain closed for 20 seconds only then automatically open up.  Serial 'debug' commands are in there so if you want to run this sketch via a PC you can see what's going on in the Serial terminal.  Also an LED lights up when someone is connected.  Don't forget to change the MAC and IP/Subnet/Gateway addresses for your device/network.

Hand_Web.ino is the HTTP version of the network code.  Links that open and close the hand as well as the live stream embedded are included in this code.

Most likely there have been modifications to this code so email me if you'd like the most recent version.


Hand.pde:

#include <Servo.h>

Servo one;
Servo two;
Servo three;
Servo four;
Servo five;
int button = 0;

void setup()
{
  Serial.begin(9600);
  // Button
  pinMode(3, INPUT);
  one.attach(4);
  two.attach(5);
  three.attach(6);
  four.attach(7);
  five.attach(8);
  delay(100);
  // Open All
  for (int i = 110; i < 175; i++)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
}

void loop()
{
  if (digitalRead(3) == 0)
  {
    Serial.println(button);
    Serial.println("Pushed");
    if (button == 0)
    {
      Serial.println("Closing");
      CloseAll();
      button = 1;
    }
    else if (button == 1)
    {
      Serial.println("Opening");
      OpenAll();
      button = 0;
    }
  }
  delay(100);
}

//#################  Hand Functions  #####################
void OpenAll()
{
  for (int i = 110; i < 175; i++)
  {
    one.write(i);
    two.write(i-5);
    three.write(i-5);
    four.write(i-5);
    five.write(i);
    delay(20);
  }
  return;
}

void CloseAll()
{
  for (int i = 175; i > 109; i--)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
  return;
}




Hand_Network.pde:
/*
  Thanks to David A. Mellis and Tom Igoe from the ChatServer sketch
  January 26, 2012
 */

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xC2, 0x10 };
byte ip[] = { 192,168,1,121 };
byte gateway[] = { 192,168,1,97 };
byte subnet[] = { 255, 255, 255, 224 };
Server server(23);
boolean gotAMessage = false, handclosed = false;
char inp;
Servo one;
Servo two;
Servo three;
Servo four;
Servo five;
int button = 0, total_time = 0;
unsigned long cur_time;
float past_time, diff_time;

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.begin(9600);
  // LED on pin 9:
  pinMode(9, OUTPUT);
  // Servo pins:
  one.attach(4);
  two.attach(5);
  three.attach(6);
  four.attach(7);
  five.attach(8);
  delay(100);
  // Open the hand to start off:
  OpenAll();
}

void loop()
{
  // Take time measurements
  cur_time = millis();
  past_time = cur_time / 1000;
  // Telnet serving activate
  Client client = server.available();
  if (client)
  {
    // Turn on LED showing a connection
    digitalWrite(9, HIGH);
    if (!gotAMessage)
    {
      Serial.println("We have a new client");
      client.println("Welcome to Remote Robotic Hand!");
      client.println("0 = Close Hand, 1 = Open Hand"); 
      gotAMessage = true;
    }
    // Get client input
    char thisChar = client.read();
    // Print client input to Serial terminal
    Serial.println(thisChar);
    if (thisChar == '1')
    {
      Serial.println("Open Hand");
      client.println("Hand Open");
      OpenAll();
      handclosed = false;
    }
    if (thisChar == '0')
    {
      Serial.println("Close Hand");
      client.println("Hand Closed");
      CloseAll();
      handclosed = true;
    }
  }
  // Every 1 second lets check hand status
  if (past_time != diff_time)
  {
    if (handclosed)
    {
      // Hand is closed, lets count the seconds
      total_time++;
      // When it's closed for 20 seconds:
      if (total_time >= 20)
      {
        // Open the hand automatically
        OpenAll();
        // Show info in serial terminal
        Serial.println("Timeout, Hand Opened");
        // Reset the hand status counters
        handclosed = false;
        total_time = 0;
      }
    }
  }
  // Turn LED off showing no connection
  digitalWrite(9, LOW);
  diff_time = past_time;
}


//#################  Hand Functions  #####################
void OpenAll()
{
  for (int i = 110; i < 170; i++)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
  return;
}

void CloseAll()
{
  for (int i = 170; i > 109; i--)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
  return;
}



Hand_Web.ino:

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xC2, 0x10 };
byte ip[] = { 192, 168, 1, 50 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);

String readString;
Servo one;
Servo two;
Servo three;
Servo four;
Servo five;
boolean handclosed = false;
int button = 0, total_time = 0;
unsigned long cur_time;
float past_time, diff_time;

//////////////////////

void setup()
{
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin(); 
  Serial.begin(9600); 
  Serial.println("servertest1");
  pinMode(9, OUTPUT);
  one.attach(4);
  two.attach(5);
  three.attach(6);
  four.attach(7);
  five.attach(8);
  delay(100);
  OpenAll();
}

void loop()
{
  // Take time measurements
  cur_time = millis();
  past_time = cur_time / 1000;
  // Create a client connection
  EthernetClient client = server.available();
  if (client)
  {
    digitalWrite(9, HIGH);  // LED on showing connection
    while (client.connected())
    {
      if (client.available())
      {
        char c = client.read();
        //read char by char HTTP request
        if (readString.length() < 100)
        {
          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 
        //if HTTP request has ended
        if (c == '\n')
        {
          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
             if(readString.indexOf('?') >=0)
             {
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println();
             }
             else
             {
                client.println("HTTP/1.1 200 OK"); //send new page
                client.println("Content-Type: text/html");
                client.println();
                client.println("<HTML>");
                client.println("<HEAD>");
                client.println("<TITLE>Robot Hand Control</TITLE>");
                client.println("</HEAD>");
                client.println("<BODY>");
                client.println("<H1>Control a Robot Hand</H1>");
                client.println("Hand will be down between 8pm-5am EST");
                client.println("<H2><a href=\"/?open\" target=\"inlineframe\">Open Hand</a><br>"); 
                client.println("<a href=\"/?close\" target=\"inlineframe\">Close Hand</a></H2>"); 
                client.println("<IFRAME name=inlineframe style=\"display:none\" >");          
                client.println("</IFRAME>");
                client.println("<iframe width=\"480\" height=\"384\" src=\"http://www.ustream.tv/embed/10361463\" scrolling=\"no\" frameborder=\"0\" style=\"border: 0px none transparent;\"> </iframe> <br/>");
                client.println("<br>");
                client.println("<a href=\"https://www.youtube.com/playlist?list=PL51106EABB0884128&feature=view_all\">YouTube Playlist of the Robot Hand development and tests</a><br>");
                client.println("<a href=\"https://sites.google.com/site/vectrasoft/projects/robotic-hand\">Webpage with detailed information on how I made this robot hand</a>");
                client.println("</BODY>");
                client.println("</HTML>");
             }
          delay(1);
          //stopping client
          client.stop();
          digitalWrite(9,LOW);
          if(readString.indexOf("open") >0)
          {
            OpenAll();
            handclosed = false;
            Serial.println("Opening Hand");
          }
          if(readString.indexOf("close") >0)
          {
            CloseAll();
            handclosed = true;
            Serial.println("Closing Hand");
          }
          //clearing string for next read
          readString="";
        }
      }
    }
  }
  
/*
  // Every 1 second lets check hand status
  if (past_time != diff_time)
  {
    if (handclosed)
    {
      // Hand is closed, lets count the seconds
      total_time++;
      // When it's closed for 20 seconds:
      if (total_time >= 200)
      {
        // Open the hand automatically
        OpenAll();
        // Show info in serial terminal
        Serial.println("Timeout, Hand Opened");
        // Reset the hand status counters
        handclosed = false;
        total_time = 0;
      }
    }
  }
*/
  
  


/*
          // Every 1 second lets check hand status
          if (past_time != diff_time)
          {
            if (handclosed)
            {
              // Hand is closed, lets count the seconds
              total_time++;
              // When it's closed for 20 seconds:
              if (total_time >= 20)
              {
                // Open the hand automatically
                OpenAll();
                // Show info in serial terminal
                Serial.println("Timeout, Hand Opened");
                // Reset the hand status counters
                handclosed = false;
                total_time = 0;
              }
            }
          }
*/


//#################  Hand Functions  #####################
void OpenAll()
{
  for (int i = 110; i < 170; i++)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
  return;
}

void CloseAll()
{
  for (int i = 170; i > 109; i--)
  {
    one.write(i);
    two.write(i);
    three.write(i);
    four.write(i);
    five.write(i);
    delay(20);
  }
  return;
}

Č
ċ
Hand.pde
(3k)
Robert Svec,
Feb 15, 2012, 5:34 PM
ċ
Hand_Network.pde
(3k)
Robert Svec,
Feb 15, 2012, 5:35 PM
ċ
Hand_Web.ino
(6k)
Robert Svec,
Dec 9, 2012, 7:22 AM
Comments