Gesture-Controlled 3D Robotic Hand

Mimic is a 3D printed hand which mimics the finger movement of the user using flex sensors & servos

Engineer

Sharad P.

Area of Interest

Electrical Engineering/Computer Science

School

Gunn High School

Grade

Rising Freshman

Third Milestone + Modifications

The majority of the time alocated for my Third Milestone was spent in finetuning my project since the code was already completed in the First Milestone and the hardware in the Second Milestone. I did, however attach my flex sensors to my glove using electrical tape. Not only did the tape secure the flex sensors onto my fingers, but also secured the connections from my arduino to my flex sensor. Previously, many of the connections fell out and failed to supply the power to the flex sensors. The one change I made to my code was that I calibrated the new flex sensor resistance values, since they had changed from the First Milestone( In the beginning, the flex sensors were perpendicularly attached to the breadboard, for my third milestone however, it was comnnected to my fingers which had a slight natural bend) To get the right flex sensor values I used the serial plotter which plotted out the points fed to it from ‘Serial.println()’ on a graph

Flex sensors attached with e-tape

img_0432

Decrease in voltage, sensed by the analog pins on the arduino

jeee

After completing my project, I did re-visit some of the earlier concepts to grasp a more thorough understanding of my circuit. When looking at my circuit, I had to resistors- the flex sensor(variable resistor) and a normal 22k Ω. I had initially took this as a given and simply went with it. However, after some indepedent research, I figured that if I had the flex sensor as the only resistor, my arduino would always read the voltage to be 0, since the flex sensor which essentially eat up all the voltage. However, if I introduced a second resistor in series the input voltage would be divided across the two resistors and the voltage read by the arduino would be a  fraction of the original input voltage based on the bend of the flex sensor. This phenomenon is called a voltage divide. To derive the voltage divide you have to use Ohms Law; Volgtage = Current x Resistance. Since the resistance increases by adding another resistor, and the voltage is the same, the overall current decreases. That’s why the voltage across the first resistor(the flex sensor) is less than the original input voltage, and thus the voltage is divided

Even though, I didn’t achieve my modification to make the connection between my glove and the robotic hand wireless, I understood how to do it. For arduino uno control both the flex sensors and the robotic hand would have to require a wire. That’s why I’m going to use an arduino nano(wiring is much simpler than an uno) to recieve inputs from the flex sensors and the arduino uno to move the robotic fingers. However, I need a way to get both the microcontrollers to start communicating with each other. I will use NRF radios to solve this issue. NRF’s use SPI communication to send infomation to each other ina cheap low powered way. MISO stands for Master-In  Slave-Out, while MOSI stands for Master-Out  Slave-In and the SCK is a clock that synchronizes the rate at which data is sent and recieved.

Diagram of Wireless Modification

lousdjpg
screen-shot-2019-07-18-at-11.23.39-pm

Arduino Code

#include <Servo.h>

Servo myservo_1; //pinki
Servo myservo_2; //middle
Servo myservo_3; //index
Servo myservo_4; //ring

const int flexPin_1 = A1; //pinki
const int flexPin_2 = A2; //ring
const int flexPin_3 = A3; //middle
const int flexPin_4 = A4; //index

void setup() 
{

     Serial.begin(9600);

     pinMode(flexPin_1, INPUT);
     pinMode(flexPin_2, INPUT);
     pinMode(flexPin_3, INPUT);
     pinMode(flexPin_4, INPUT);


     myservo_1.attach(10);
     myservo_2.attach(6);
     myservo_3.attach(5);
     myservo_4.attach(9);

}

void loop() {             

     // Defines analog input variables
     int flex_1 = analogRead(flexPin_1);
     int flex_1 = analogRead(flexPin_2);
     int flex_3 = analogRead(flexPin_3);
     int flex_4 = analogRead(flexPin_4);
     

     Serial.println(flex_1);


     int pos_1;
     int pos_2;
     int pos_3;
     int pos_4;

     // mapping servo position
     pos_1 = map(flex_1, 613, 510, 180, 0);
     pos_1 = constrain(pos_1, 0, 180);

     pos_2 = map(flex_2, 640, 500, 180, 0);
     pos_2 = constrain(pos_2, 0, 180);

     pos_3 = map(pos_3, 580, 390, 180, 0);
     pos_3 = constrain(pos_3, 0, 180);

     pos_4 = map(flex_4, 650, 550, 180, 0);
     pos_4 = constrain(pos_4, 0, 180);

    
     myservo_1.write(pos_1);
     myservo_2.write(pos_3);
     myservo_3.write(pos_4);
     myservo_4.write(pos_2);

     delay(50); 
}

Second Milestone

For my second milestone I decided to showcase  a fully assembled 3D printed hand and base.

This one week build incorporated many skills other than using mechanical tools. My first step, however, was to use an impact driver(electric screwdriver) to screw in the screws into the nuts, that hold the finger in place. They were Philips-head screws that had unique threading and didn’t have any screwdriver that could match it. That is why I used an impact driver to push it with so much force that it had to fit into the nut. However, that method shreds the thread inside the screw and makes it almost impossible to unscrew. I eventually resorted to using pliers to manually rotate the screws without destroying the screw thread. My next step was to attach two string to a motor each controlling a finger. I designed it so that at any given time one of the strings is taut, while the other loose. When the finger is at its rest position, the string pulling the finger down is taut, while the string pulling the finger up is loose and vice-versa. This pulley-like system allows the finger to have a whole range of motion from its rest position to fully erect. The most tedious part of this process was definitely putting crimps through the strings to hold them in place. After a short period of use, the crimp would slip and let the strings run loose. I  solved this by tying tight knots around the crimps holding it in place. Furthermore, each time I tightened a crimp, it couldn’t be undone and I had to use a new crimp each time.

Simultaneous to the build, I  transferred all the wiring for my flex sensors to a blank PCB.  I had various challenges while trying to solder my electrical components. To create a connection between my ground wire, resistor, and analog wire, I had to solder across 3 joints. I struggled with bridging these joints together in an efficient and clean way. During the first few tries, my PCB would look terribly messy, since I would solder in a clumpy mountain-like fashion. At first, I tried de-soldering the clumpy connections, but I realized that I was burning my PCB since I was overusing my soldering iron.  I eventually resorted to using a fresh set PCBs, wires, and resistors. After soldering my flex sensor connections, I began testing the connections of my servos. After a while of testing, my servos stopped rotating. At first, I thought it was a faulty connection, but then I realized my battery wasn’t charged. I then used a multimeter to measure the voltage passed through the servos. I  found out that there was no power being passed through the servos and realized that the battery was dead

Arduino Code

#include <Servo.h>

Servo myservo_1, myservo_2, myservo_3, myservo_4;

const int flexPin_1 = A1;
const int flexPin_2 = A2;
const int flexPin_3 = A3;
const int flexPin_4 = A4;

void setup() {
// put your setup code here, to run once:

     Serial.begin(9600);

     pinMode(flexPin_1, INPUT);
     pinMode(flexPin_2, INPUT);
     pinMode(flexPin_3, INPUT);
     pinMode(flexPin_4, INPUT);


     myservo_1.attach(11);
     myservo_2.attach(10);
     myservo_3.attach(6);
     myservo_4.attach(3);

}

void loop() {             

     // Defines analog input variables
     flexPosition_1 = analogRead(flexPin_1);
     flexPosition_2 = analogRead(flexPin_2);
     flexPosition_3 = analogRead(flexPin_3);
     flexPosition_4 = analogRead(flexPin_4);


     int pos_1;
     int pos_2;
     int pos_3;
     int pos_4;

     // mapping servo position
     pos_1 = map(flexPosition, 400, 700, 0, 180);
     pos_1 = constrain(servoPosition, 0, 180);

     pos_2 = map(flexPosition2, 200, 500, 0, 180);
     pos_2 = constrain(servoPosition2, 0, 180);

     pos_3 = map(flexPosition3, 400, 700, 0, 180);
     pos_3 = constrain(servoPosition3, 0, 180);

     pos_4 = map(flexPosition4, 200, 500, 0, 180);
     pos_4 = constrain(servoPosition4, 0, 180);

     // changing servo to reach position
     myservo_1.write(servoPosition);
     myservo_2.write(servoPosition2);
     myservo_3.write(servoPosition3);
     myservo_4.write(servoPosition4);

     delay(50); 
}

IMPORTANT LINKS:

sharad-bill-of-materials-bom-1

Step 1: Screwing in the nuts and bolts to secure fingers in place

step_1

Step 2: Attach strings to each finger in order to pull the finger up and down

step_2

Step 3: Screw in servos in place and attach strings to servos. Make sure that at any given time one string is always tighter than the other

step_3

Step 4: Now that the hand is fully assembled test that when servo rotates, strings move and bend the finger

step_4

First Milestone

blurr

Correct Way Of Reading Voltage(Arduino Wire In Between Resistors

real

Wrong way of reading voltage(Arduino wire after both resistors. Voltage will always be 0)

mistake

Arduino Code

#include <Servo.h>

Servo myservo_1, myservo_2, myservo_3, myservo_4;

const int flexPin_1 = A1;
const int flexPin_2 = A2;
const int flexPin_3 = A3;
const int flexPin_4 = A4;

void setup() {
// put your setup code here, to run once:

     Serial.begin(9600);

     pinMode(flexPin_1, INPUT);
     pinMode(flexPin_2, INPUT);
     pinMode(flexPin_3, INPUT);
     pinMode(flexPin_4, INPUT);


     myservo_1.attach(11);
     myservo_2.attach(10);
     myservo_3.attach(6);
     myservo_4.attach(3);

}

void loop() {             

     // Defines analog input variables
     flexPosition_1 = analogRead(flexPin_1);
     flexPosition_2 = analogRead(flexPin_2);
     flexPosition_3 = analogRead(flexPin_3);
     flexPosition_4 = analogRead(flexPin_4);


     int pos_1;
     int pos_2;
     int pos_3;
     int pos_4;

     // mapping servo position
     pos_1 = map(flexPosition, 400, 700, 0, 180);
     pos_1 = constrain(servoPosition, 0, 180);

     pos_2 = map(flexPosition2, 200, 500, 0, 180);
     pos_2 = constrain(servoPosition2, 0, 180);

     pos_3 = map(flexPosition3, 400, 700, 0, 180);
     pos_3 = constrain(servoPosition3, 0, 180);

     pos_4 = map(flexPosition4, 200, 500, 0, 180);
     pos_4 = constrain(servoPosition4, 0, 180);

     // changing servo to reach position
     myservo_1.write(servoPosition);
     myservo_2.write(servoPosition2);
     myservo_3.write(servoPosition3);
     myservo_4.write(servoPosition4);

     delay(50); 
}

My first milestone was getting four pairs of flex sensors and servos to work together. As the user bends the flex sensor, the servo starts to rotate.

 The circuit contains four resistors, each that are connected to the flex sensors. The flex sensors act as variable resistors, and as I bend them, the voltage across it increases and the voltage across the second resistor decreases, The analog pins on the Arduino will read this voltage passed across the second resistor. Using the map(), the Arduino will map the voltage to a servo’s position. At the end of my code, the Arduino would write the servo to spin to the desired position.

As of now, I have been using an Arduino, breadboard, wires, flex sensors, resistors, and servos. For the first few weeks, I decided to focus on the electrical components and conduct tests with my code. All my Arduino code has been uploaded to this website. To test out my code, I used a breadboard to prototype my circuit before making any permanent connections on a PCB. 

There were several challenges that I encountered during the completion of my first milestone. My breadboard had a lot of wiring and due to unfortunate circumstances, the supply of jumper wires ran out.  I had to strip solid wire and use that to make my connections. Even though solder wire serves well as a temporary replacement, they don’t tend to last long and often slip out of the breadboard holes. During many occasions, my servos would not rotate, because one of the power wires had popped out of the socket. Moreover, whenever I had to debug, I ended up rewiring my whole circuit since it was very hard to see which wire was malfunctioning among the jungles of wires present. 

Picture of Serial monitor getting inputs from the flex sensor. As seen in the image below, as I bend the flex sensor, the voltage accross it increases.

screen-shot-2019-06-27-at-9.06.33-am

Starter Project – Motion Activated Alarm

For my starter project, I decided to build a motion activated alarm using an ultrasonic distance sensor. When a person moves in front of the alarm, the Arduino will beep a buzzer, flash lights on an RGB LED, and rotate a servo.

Outputs

A piezo-electric buzzer functions by containing piezo crystals in between two conductors. When voltage is applied across these crystals, they push one conductor and pull the other conductor. The continuous pull and push action generate a sharp sound wave.

An RGB LED produces a whole variety of colors by combining the three colors(red, green, and blue) in different brightnesses. To adjust the brightness of each color, the Arduino uses PWM signals that assign each pin a certain value.

Sensing

The distance sensor has 4 pins, – VCC, GND, trig, echo. The first two pins manage power. The Vcc manages incoming power, while GND simply serves as a return path for all the current. The trig pin(output) sends a signal, which eventually reaches an object and reflects off it. The echo pin(input) then receives the signal and measures the time taken for the signal to reach the object. The code then multiplies that time by the speed of sound in air, to calculate the distance.

screen-shot-2019-06-21-at-9.49.59-am

Schematics

screen-shot-2019-06-21-at-9.44.38-am
Schematics

Arduino Code

70% Complete
#include <Servo.h> //include the servo library

const int trigPin = 11; //connects to the trigger pin on the distance sensor 
const int echoPin = 12; //connects to the echo pin on the distance sensor

const int redPin = 3; 
const int greenPin = 5; 
const int bluePin = 6;

const int buzzerPin = 10;

float distance = 0;

Servo myservo; 
void setup()
{
Serial.begin (9600);

pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT);


pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

pinMode(buzzerPin, OUTPUT); //set the buzzer pin to output

myservo.attach(9); //use pin 9 to control the servo

}

void loop() {
distance = getDistance(); 

if(distance <= 8){

//make the RGB LED red
analogWrite(redPin, 255);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);

//this code wiggles the servo and beeps the buzzer
tone(buzzerPin, 272); 
myservo.write(45); 
delay(100);

noTone(buzzerPin); 
myservo.write(135); 
delay(100);


} else if(9 < distance && distance < 20){ //if the object is a medium distance

//make the RGB LED yellow
analogWrite(redPin,255);
analogWrite(greenPin, 100);
analogWrite(bluePin, 0);

} else{ //if the object is far away

//make the RGB LED green
analogWrite(redPin, 0);
analogWrite(greenPin, 255);
analogWrite(bluePin, 0); 
}

delay(50); //delay 50ms between each reading
}

//------------------FUNCTIONS-------------------------------

float getDistance()
{
float echoTime; //variable to store the time it takes for a ping to bounce off an object
float calculatedDistance; //variable to store the distance calculated from the echo time

//send out an ultrasonic pulse that's 10ms long
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); 
digitalWrite(trigPin, LOW);

echoTime = pulseIn(echoPin, HIGH); 


calculatedDistance = echoTime / 148.0;

return calculatedDistance; 
}

TEM Summer Camps Coding & Robotics Classes For Kids San Francisco Coding & Robotics Classes For Kids New York Coding & Robotics Classes For Kids Denver Coding & Robotics Classes For Kids Palo Alto STEM Summer Camps For Kids in New York STEM Summer Camps For Kids in Palo Alto STEM Summer Camps For Kids San Francisco STEM Classes For Kids in New York STEM Classes For Kids in Palo Alto STEM Classes For Kids in San Francisco Code Classes For Kids Code Classes For Kids in New York Code Classes For Kids in Palo Alto Code Classes For Kids in San Francisco STEM Summer Camps For Kids

Leave a Comment

Start typing and press Enter to search