Group Members:
Dawn Haken
Quoc Pham
Yuchen Li
Project Description
Initial goal: To create a finger-like robot which can hold objects of different stiffnesses without crushing them.
Final goal: To rotate the entire assembly, and keep the object gripped without squishing it; increase the pressure from the servo motor arm as the object's weight on the sensor decreases.
Design Sketch:
Materials:
RedBoard, breadboard, jumper wires, resistors: from ECE 110 lab kit
Servo motor: https://www.servocity.com/html/hs-311_standard.html#.VhLQxU13F9M, acquired from the electronic services shop
Servo motor arm: Fabricated by the machine shop, 5 inches in length
Pressure sensor: Three small force sensitive resistors: https://www.sparkfun.com/products/9673
Small neoprene pads: Used to simulate the finger pads
Wooden board as a surface on which to attach the motor, force sensors, and RedBoard/breadboard assembly
Mounting bracket from the machine shop to hold the servo motor in place and attach it to the board
Op-amp chip LM358N: https://www.sparkfun.com/products/9456
Red and green LEDs
Assembled project!
Tentative Stages of Development:
1) Research cost effective parts that are appropriate for our design
2) Gathering parts and setting up the mechanism
3) Coding the servo to move and hold the positions we need at the speeds we choose
4) Reading, interpreting, and filtering the values we will receive from the force sensors
5) Re-coding our servo to move based on input from our sensors
6) Adjusting our program to be able to grip objects of various weights and "squishiness"
7) Re-coding our program to account for the change in sensor values when moving from a horizontal grip to a vertical grip
8) Adding features that will make the finger more autonomous (will begin gripping when an object is placed on the sensors)
9) Attempt more sophisticated movement (catching something)
How it will work:
The force sensors under the object will trigger values that the Arduino will read. These values will be set as the base value of the object, and the Arduino will begin moving the servo arm until the force exceeds a determined amount greater than the base value. The arm, once it is pressing on the object, will cause this change in the force that it will read. Once it reaches that determined value, it will stop moving and hold the servo arm there.
Circuit Diagram for Force Sensors & Op-amps, Servo Motor, and LEDs:
Current and Expected Problems (any suggestion is welcomed!):
1. The pressure sensor may not be very sensitive to light weights (i.e. below 100g).
Our current solution is to use 3 small pressure sensitive resistors, and arrange them below where the object will sit. These sensors are very small in sensing area but can sense changes of as low as 2g.
2. The maximum torque and friction exerted by the finger may not be large enough.
We decided to use a different, stronger servo. It appears powerful enough.
3. Need to find reliable ways to fix parts into their position, especially to prevent them from moving unexpectedly while being rotated.
Our current plan is to screw/tape/pin everything to a small wooden board. This may be modified in the future to accommodate rotation.
4. Need to collect some data on the weight and pressure resistance of objects that we want the finger to hold.
5. There will be a signal coming from the weight of the object that the program needs to "know" is not coming from the motor arm. The program would have to recognize when an object has been placed on the pressure sensor.
One way to solve this problem would be to have a loop running which could check the resistance of the pressure sensors, and if the resistance were to increase above the usual noise levels (a value we would need to find through experimentation) and stay at that new level, the loop would end and set that new resistance level as a base level. Then it would "know" there was an object on the force sensor. The program could then continue to the next loop which could move the servo arm incrementally and watch for another change in pressure. This would occur as the arm reaches the object and just beings to press down on it.
The robotic finger needs to be able to exert pressure on a variety of objects with a significant weight difference
6. We might need to filter out the noise that will adversely affect how our servo motor "grips".
If the servo cannot hold steady, it will likely drop the object. More research needs to be done on filters.
7. The neoprene pads may not give us the right amount of elasticity or friction for the range of items we want to hold.
We will need to discover this when we have built the majority of the setup. It shouldn't be difficult to attach a different material at that stage
8. Program for the robotic finger will have to be altered or modified once we move to the vertical grip from the horizontal grip.
Daily Summaries
September 21
We discussed two different methods of gripping the object, one with a servo motor and one with a standard motor. We decided on the servo motor because the other option presented more mechanical issues which would take too much time and effort to solve. We examined the neoprene and decided it would provide enough friction and give to hold objects without crushing them. We created a wiki page for our project.
September 28
We drew a high level block diagram of our system. We discussed the sensitivity of the pressure sensors, and decided that the best setup for our needs would be to use 3 of the very small, sensitive sensors and combine the resistance values they output. We talked about different ways to attach an arm to the servo: this is one of our big, ongoing issues. We looked at different options online and decided to choose one before the next meeting.
October 5
We looked for proper servos and arms online. Our best choices online were HS-311 standard servo and 56361 standard spline. But we later decided to use the servo supplied at the ECE shop, and we requested the ECE Machine Shop staff to build a 5-inch arm for our servo (thanks!). We think that coding will be a big part of our project, and we found some information in Circuit #9 of Sparkfun Inventor Guide.pdf. We plan to research on noise-filtering this week. One commonly used but difficult noise-filtering method is called "Kalman filter". But we would like to seek a more practical way that can still satisfy our needs.
October 12
We tested out the servo motor by building a circuit from the Sparkfun Inventor's Kit Guide that allowed us to control the angle of the servo using flex sensors. The program worked perfectly and we were able to fine tune it so that the servo could move in its full range (0 to 180). However, our force sensors had not arrived so we were not able to start programming using the three force sensors. Today's example allowed us to get a good sense of how the servo twitches due to the noise coming through the sensor. Since we're looking to grab and pin down objects, we'll have to filter this noise out in our program. Finally, we began looking for servo motor brackets in order to fix the servo in place to begin testing once the sensors arrive. Fortunately, the machine shop people were kind enough to help us, once again, realize our project. We owe them a big thank you.
October 19
Our three force sensor arrives. Each group did a brief Halfway Progress Report.
October 26
We put the three force sensors in series into the circuit. The resistance of each force sensor reduces rapidly as force increases within the range of (converted to mass) 0-10g. When force>10g, the resistance reduces at a lower speed. The force is represented with voltage across the force sensor. So we have to find a proper "set resistor" that allows the voltage across the sensors to change detectably when the force changes. Today we assumed that the set resistance should be made similar to the half way of the force sensor's desired resistance range (this assumption needs to be considered again). Physically, we arranged the sensing spots of the three force sensors in a "v" shape and set them a little bit higher than the supporting pad so that the force could be distributed to the sensor (instead of the pad). And we used tape to keep the position of the sensors and wires. We succeeded in gaining desirable change of data as force changes. And we will make the motor move according to the data in the following sessions.
November 2
Although we got our prototype code working to move the arm, it wasn't working exactly like we wanted. The arm for some reason was not staying at zero degrees when no object was placed on the sensors. In other words, the robotic finger grabbed every time we turned it on, and it grabbed with the same force every time. We suspect there is something wrong with our loop in the code and perhaps where we have placed that loop. The code was being tweaked and debugged, however, we were unable to successfully solve the problem in the allotted time. The next two weeks will likely be full of debugging and modifying our code.
November 8
First we debugged the code. We realized that the forceReading variable should be read and overridden in each loop containing the movement of the arm. This time we successfully made the arm keep at its original position when no object was put on the sensors, start when something was put on the sensors, and stop when the force on the sensors increased. But then we found another problem: if we push only one of the sensors, the force reading signal does not change, whereas it does change if we push both of the two sensors connected to the circuit (note that there were only two connected to the circuit, which caused a minor bug later because we forgot that). This is because the resistance of each flex sensor is very large (about 10M ohms) when the force is 0, which means the flex sensor(s) will carry almost all the voltage across power and ground, no matter whether one or two sensors are left with no force. To solve this, and also to make it more flexible to use the input(s), we decided to build three identical circuits, each connecting the power and ground, and each containing a flex sensor and a set resistance (22 kilo ohms). We read the voltage at the connecting point of the flex sensor and the set resistance in each circuit. In this way we successfully gained three inputs simultaneously, instead of only one (as we did when connecting all three flex sensors in series).
November 9
We tested the circuit and found that it cannot detect light weight object. We proved mathematically that to make the sensor input more sensitive, we should make the set resistance equal the working resistance of the flex sensor in series to it. When force is small, the flex sensor has a very large resistance (several hundred kilo ohms or even several million ohms). So we let set resistance = 330 kilo ohms in order to detect light objects. Currently, we expect our robot finger will deal with only light objects. But we find another problem: because the circuit makes sensors too sensitive, when we press only one of them, somehow another sensor will be affected. For example, if we press only sensor 1, then sensor 1 will read (in Arduino) around 900, while sensor 2 will read around 100 (0 means no force, and the the representation of max force is 1023). We do not know the reason of it yet. But we may be able to deal with it by setting threshold values, though.
November 16
After debugging the sensors and endless experimenting with them, we fear that these sensors will not have the sensitivity their Sparkfun description led us to believe they had. This may require us to alter or change the original goal of this robotic finger because the sensors won't register objects that are too light. Without demonstrating with light objects such as grapes, it is difficult to recreate a human finger. The current robotic finger will grab the object indifferent to the fragility of the object. Our only possible solution left is to use an op amp so we will putting all eggs in that basket, so to speak.
November 30
First when we ran the program, the arm was trying to push all the way down. The variable "servoPosition" continues to increase even after the arm hits the object and was blocked. To solve this, Prof. Schmitz and Dawn came up with an idea combining spring, potentiometer, and servo motor (better to include a photo here). We haven't implement the idea yet today. We also debugged a problem about sensor reading, which read a few large numbers at the beginning of each run of program, while it should have read zeros constantly. It was because when the servo started to draw a current, which was pretty large, it affected other parts in the circuit that shared the same voltage source (because the source is not "ideal" defined by electric terms). After we made them use separate sources, the bug was fixed.
MISC.
The flex sensor's range goes from Overload to 2.6k Ohm
The Working Program Code:
#include <Servo.h>
Servo servo1;
const int forcePin0 = 0, forcePin1 = 2, forcePin2= 5;
const int servoPin=9, ledPinW = 7, ledPinS= 4;
int delta = 50, baseValue = 0;
int initialForce, initialWeight = 0;
int forceReading0, forceReading1, forceReading2;
int totalReading, servoPosition = 0;
int timeAveragedReading;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
servo1.attach(servoPin);
servo1.write(0);
pinMode(ledPinW, OUTPUT);
pinMode(ledPinS, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
forceReading0 = analogRead(forcePin0);
forceReading1 = analogRead(forcePin1);
forceReading2 = analogRead(forcePin2);
totalReading = forceReading0 + forceReading1 + forceReading2;
Serial.print("Force sensor reading: ");
Serial.print(totalReading);
Serial.print(" Servo position reading: ");
Serial.println(servoPosition);
digitalWrite(ledPinW, LOW);
digitalWrite(ledPinS, LOW);
if (initialWeight == 0) {
if (totalReading > 200) {
digitalWrite(ledPinW, HIGH);
Serial.print("I am in the loop");
delay(10000);
smoothing (30);
initialWeight = timeAveragedReading;
Serial.println(initialWeight);
stepperMove();
}
}
delay(250);
}
void stepperMove () {
smoothing(15);
while (timeAveragedReading <= initialWeight + delta) {
digitalWrite(ledPinS, HIGH);
servoPosition += 1;
servo1.write(servoPosition);
delay (10);
smoothing(15);
/*forceReading0 = analogRead(forcePin0);
forceReading1 = analogRead(forcePin1);
forceReading2 = analogRead(forcePin2);
totalReading = forceReading0 + forceReading1 + forceReading2;*/
Serial.print("Force sensor reading: ");
Serial.println(timeAveragedReading);
Serial.print("Servo position reading: ");
Serial.println(servoPosition);
}
}
void smoothing (int x) {
for (int i=0; i<x; i++) {
forceReading0 = analogRead(forcePin0);
forceReading1 = analogRead(forcePin1);
forceReading2 = analogRead(forcePin2);
totalReading = forceReading0 + forceReading1 + forceReading2;
if (i==0) {
timeAveragedReading = totalReading;
}
if (i>=1) {
timeAveragedReading = (totalReading + timeAveragedReading) / 2;
}
}
Serial.println("Smoothed");
}
Attachments:
rotated v1.PNG (image/png)
IMG_3335.JPG (image/jpeg)
IMG_3335.JPG (image/jpeg)
IMG_3390.JPG (image/jpeg)
sensor reading.PNG (image/png)
Circuit diagram.png (image/png)
110honors diagram.png (image/png)
IMG_3543.JPG (image/jpeg)
IMG_3543.JPG (image/jpeg)
Haken-Li-Pham-Robotic-Finger.pdf (application/pdf)