Introduction: Build a $30k CyberGlove for $40 - Submitted by BayLab for the Instructables Sponsorship Program

The glove on the right is a CyberGlove, made by a company several years ago who charged $30,000 per glove. I know this because I found a pair in the lab I work in at school...

So I built my own pair with 70% of the functionality for three orders of magnitude cheaper. These gloves will measure the position and movement of your fingers and dump it into a computer so you can teleoperate a robot, control animatronics, manipulate digital content, or whatever you want.

Step 1: The Glove

Finding a good glove is more important than you might think. It turns out I picked probably the worst glove I could have, but I still made it work. Ideally, you want a glove that fits very snugly. I imagine a leather or spandex glove would be great. It must have fingers and it should be smooth without any decorative ridges or patches or anything. I used some $4 gloves from home depot that we had laying around my shop. You can make this project as cheap or expensive as you want in picking your glove. If you're just building one, use the glove for your dominant hand. 

Step 2: Detecting Movement

The way we detect where your fingers are is with resistance. The CyberGlove uses strip flex potentiometers like these. You can certain hack these into your glove, but I didn't have any when I built mine. I did have some spring loaded pots from a game controller through. You can either tear apart anything with a joystick (like a PS2 controller, Xbox controller, etc), or you can buy one from Digikey. These are actually two axis, so you can improve this project to detect lateral finger motion if you want, but I didn't need it for my purposes, so I just used a single axis.

To use these pots, just use an ohmmeter to see which pins change resistance when you wiggle the joystick. Solder some long wires to the pins and put a little heatshrink over it to keep it from accidentally shorting. I used zip ties to keep the wires organized. 

Step 3: Anchor the Pots

Put the glove on and use a Sharpie to mark where you'll want the pots. Make sure you have room so they won't run into each other but are still aligned with the finger. You can see in my glove I had to stagger them to make it fit. I used hot glue to attach them to the glove. If your glove is tight fitting, that might be all you need. If it's loose like mine was, you should put the glove on after gluing down the pots and use your other finger to pull the joystick down and see if it moves the entire pot. If the pot lifts up and stretches the glove material, you can bunch up some glove material behind the pot and glue it down to the back surface of the pot. This is basically removing any slack from the glove so that the glove itself isn't acting as a spring and bending your finger a tiny bit will bend the joystick a tiny bit instead of lifting the pot without bending the joystick. 

Step 4: Wiring the Fingers

To actually move the pots, I used some thin magnet wire I had laying around and wire wrapped it around the joystick. Then I ran it underneath the glove and back to the top again so it would stay straight when I moved my finger. I weaved it several times though the end of the finger to anchor it. This worked fine for the thumb, but not for the other fingers. The spring in the pot wasn't long enough to see my entire finger flex. So I added some small springs that I had laying around  and adjusted the wire length until not bending my finger didn't move the joystick and curling it into a fist made the joystick hit it's forward limit. If you can't find any small springs, try using some out of mechanical pencils or pens. I didn't do any calculations to figure out what spring to use, I just grabbed one and made it work. 

Step 5: Electronics

I used an Arduino to read the variable resistance. I built a resistor divider and treated it like an analog input. You don't have to use a 10k resistor, you can use whatever is laying around. You'll be calibrating it in the next step anyway.

Step 6: Code

The quickest way to get started is using the built in analog pot sketch that comes with Arduino. I'll show you the code I wrote, but you'll need to modify it for your own needs. It does show you how to scale the values and gives you a good template though.

This first sketch uses hardcoded values for the pot. That is, I saw what Arduino output for the max and min positions of the pot and used those to figure out how much the finger has moved:

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

This example code is in the public domain.
*/


float analog0;
float analog1;
float analog2;
float analog3;
float analog0_close;
float analog1_close;
float analog2_close;
float analog3_close;
float analog0_open;
float analog1_open;
float analog2_open;
float analog3_open;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Using hardcoded max and min");
}

// the loop routine runs over and over again forever:
void loop() {
analog0 = analogRead(A0);
   analog1 = analogRead(A1);
   analog2 = analogRead(A2);
   analog3 = analogRead(A3);

  //Scale the values to a range of [0,1]
float scaled_thumb = (analog0 - 854.00)/(920.00 - 854.00);
float scaled_point = (analog1 - 860.00)/(923.00 - 860.00);
float scaled_middle = (analog2 - 862.00)/(913.00 - 862.00);
float scaled_ring = (analog3 - 848.00)/(902.00 - 848.00);
if(scaled_thumb < 0.00){
   scaled_thumb = 0.00;
}
if(scaled_point < 0.00){
   scaled_point = 0.00;
}
if(scaled_middle < 0.00){
   scaled_middle = 0.00;
}
if(scaled_ring < 0.00){
   scaled_ring = 0.00;
}

  Serial.print("Thumb: ");
  Serial.print(scaled_thumb);
  Serial.print(" Point: ");
  Serial.print(scaled_point);
  Serial.print(" Middle: ");
  Serial.print(scaled_middle);
  Serial.print(" Ring: ");
  Serial.println(scaled_ring);
  Serial.print(scaled_point);

 delay(1);        // delay in between reads for stability. Use this for debugging

 }



Here's another version I wrote that tries to calibrate the max and min positions at the beginning. I found this didn't work quite as well because of the pliability of my glove. 

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

This example code is in the public domain.
*/


float analog0;
float analog1;
float analog2;
float analog3;
float analog0_close;
float analog1_close;
float analog2_close;
float analog3_close;
float analog0_open;
float analog1_open;
float analog2_open;
float analog3_open;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial.println("Calibrating...");
  Serial.println("Open hand.");
  delay(2000);
   analog0 = analogRead(A0);
   analog1 = analogRead(A1);
   analog2 = analogRead(A2);
   analog3 = analogRead(A3);

   analog0_open = analog0;
   analog1_open = analog1;
   analog2_open = analog2;
   analog3_open = analog3;
   Serial.print("Acquired: ");
   Serial.print(analog0_open);
   Serial.print(" ");
   Serial.print(analog1_open);
   Serial.print(" ");
   Serial.print(analog2_open);
   Serial.print(" ");
   Serial.println(analog3_open);

  Serial.println("Close hand");
  delay(2000);
  analog0 = analogRead(A0);
   analog1 = analogRead(A1);
   analog2 = analogRead(A2);
   analog3 = analogRead(A3);
   analog0_close = analog0;
   analog1_close = analog1;
   analog2_close = analog2;
   analog3_close = analog3;

  Serial.print("Acquired: ");
   Serial.print(analog0_close);
   Serial.print(" ");
   Serial.print(analog1_close);
   Serial.print(" ");
   Serial.print(analog2_close);
   Serial.print(" ");
   Serial.println(analog3_close);

  Serial.println("Calibration complete.");
  Serial.println("Running...");
  delay(2000);
}

// the loop routine runs over and over again forever:
void loop() {
analog0 = analogRead(A0);
   analog1 = analogRead(A1);
   analog2 = analogRead(A2);
   analog3 = analogRead(A3);
  // print out the value you read:
//  Serial.print("Thumb: ");
//  Serial.print(analog0);
//  Serial.print(" Point: ");
//  Serial.print(analog1);
//  Serial.print(" Middle: ");
//  Serial.print(analog2);
//  Serial.print(" Ring: ");
//  Serial.println(analog3);
  //Scale the values to a range of [0,1]
float scaled_thumb = (analog0 - analog0_open)/(analog0_close - analog0_open);
float scaled_point = (analog1 - analog1_open)/(analog1_close - analog1_open);
float scaled_middle = (analog2 - analog2_open)/(analog2_close - analog2_open);
float scaled_ring = (analog3 - analog3_open)/(analog3_close - analog3_open);

  Serial.print("Thumb: ");
  Serial.print(scaled_thumb);
  Serial.print(" Point: ");
  Serial.print(scaled_point);
  Serial.print(" Middle: ");
  Serial.print(scaled_middle);
  Serial.print(" Ring: ");
  Serial.println(scaled_ring);

  delay(1);        // delay in between reads for stability

}

Step 7: That's It!

Now go make a robot hand so you have something to control.