Tuesday, August 30, 2011

Gloves and Code Update

So, I've made a bit of progress the past few days/weeks but I'll update it in stages.

Ive put together the gloves and general circuit that controls the servos that will be attached to the wings. The gloves took me several hours to do just because the buttons I am using are so small (not to mention have tiny tiny metal contacts that are made for surface mount PCBs) that it took me a while to solder them, wire them, sew them into the gloves and then reinforce them so they stand up to repeated bending and pushing while I am wearing them. I think the result is fairly robust. Of course, if I get my hand caught in a car door it doesnt matter how much hot glue I use, the push-button is gonna be totaled.

Here are some pictures of the gloves solo and attached to the circuit board.


So, each finger has its own push-button responsible for a different behavior in the wings. Also, I built the gloves so that they could be detached from the leads that connect them to the microcontroller.




Messy, I know. You can see the servos in the back with little metal bobbins attached to the servo horns. I used epoxy rated for 3200 PSI to glue the bobbins. Im sure I couldve gotten away with krazy glue, but the epoxy was the same price at home depot so I figured I'd over engineer it so I wouldnt have to worry about it later on.

I've spent the past few days working on changing the code to give me better functionality out of the wings. The way I originally had it setup, holding a button on a finger would cause the servo to wind up the line that would pull or release the wing, so if you let go the button it would stop. This is easy to use, but because the Arduino is so focused on the button thats being pressed, it isnt able to do anything else in the meantime. That means I was restricted to moving only one segment at a time which is kinda boring and awkward to look at.

To solve this, I designed the code so that pushing (and releasing a button) would start the servo and pushing it again would stop it. This means that once a servo is activated, the arduino is free to do whatever else it pleases, i.e. activate other servos. This means that now, all the servos are free to be operated simultaneously, so I can move the wings any way I see fit, when I see fit.

But, that was a pain in the ass to do. I am the first one to admit, I am not a very strong programmer. I've only really been at it for a few months and its still a little new. With this new method of using the buttons, I had to combat this weird property of electric circuits called "bouncing". Basically, when you try to push a button down, the electricity tends to bounce back and forth in the button, so much so that the microcontroller thinks its switching back and forth a dozen times. So now I have to make it smart enough to recognize this noisey button for what it is and really identify whether or not Im pressing the button. Also, it has to remember what the button was the last time it was pressed.

I was able to get it done, but not without a lot of frustration. But, I think Im a more experienced programmer for it, so all's well that ends well. I could post a video of the gloves turning on the servos, but all you would see are the little silver spools spinning. Once I get the servos mounted to the wings I'll take a video and post it.

Below is the code. If you dont speak code, then feel free to take this as the end of the blog post, theres nothing really interesting down there :)


#include //call up library


#define RI_Pin 2 //Define pins
#define RM_Pin 3
#define RR_Pin 4
#define RP_Pin 5
#define LI_Pin 6
#define LM_Pin 7
#define LR_Pin 8
#define LP_Pin 9
#define rightOuterServoPin 10
#define rightInnerServoPin 11
#define leftInnerServoPin 12
#define leftOuterServoPin 13

int RI_State = LOW; //Current switch states
int RM_State = LOW;
int RR_State = LOW;
int RP_State = LOW;
int LI_State = LOW;
int LM_State = LOW;
int LR_State = LOW;
int LP_State = LOW;

int RI_Old_State = LOW; //Old switch states
int RM_Old_State = LOW;
int RR_Old_State = LOW;
int RP_Old_State = LOW;
int LI_Old_State = LOW;
int LM_Old_State = LOW;
int LR_Old_State = LOW;
int LP_Old_State = LOW;

int RI_Servo_State = LOW; //Switch state stored to send to servo
int RM_Servo_State = LOW;
int RR_Servo_State = LOW;
int RP_Servo_State = LOW;
int LI_Servo_State = LOW;
int LM_Servo_State = LOW;
int LR_Servo_State = LOW;
int LP_Servo_State = LOW;

const int EXPAND = 0; //expand = servo value 0 = CCW motion
const int STOP = 90;
const int CONTRACT = 180; //contract = servo value 180 = CW motion

Servo rightOuterServo; //Create instances of Servos
Servo rightInnerServo;
Servo leftInnerServo;
Servo leftOuterServo;


void setup() {
rightOuterServo.attach(rightOuterServoPin); //attach servos to proper pins
rightInnerServo.attach(rightInnerServoPin);
leftInnerServo.attach(leftInnerServoPin);
leftOuterServo.attach(leftOuterServoPin);


pinMode(RI_Pin,INPUT); //set finger buttons as inputs
pinMode(RM_Pin,INPUT);
pinMode(RR_Pin,INPUT);
pinMode(RP_Pin,INPUT);
pinMode(LI_Pin,INPUT);
pinMode(LM_Pin,INPUT);
pinMode(LR_Pin,INPUT);
pinMode(LP_Pin,INPUT);

rightOuterServo.write(STOP); //make sure servos begin sketch as stopped
rightInnerServo.write(STOP);
leftInnerServo.write(STOP);
leftOuterServo.write(STOP);
}


void loop() {

//Read Switch States
RI_Old_State = digitalRead(RI_Pin);
RM_Old_State = digitalRead(RM_Pin);
RR_Old_State = digitalRead(RR_Pin);
RP_Old_State = digitalRead(RP_Pin);
LI_Old_State = digitalRead(LI_Pin);
LM_Old_State = digitalRead(LM_Pin);
LR_Old_State = digitalRead(LR_Pin);
LP_Old_State = digitalRead(LP_Pin);
delay(10);
RI_State = digitalRead(RI_Pin);
RM_State = digitalRead(RM_Pin);
RR_State = digitalRead(RR_Pin);
RP_State = digitalRead(RP_Pin);
LI_State = digitalRead(LI_Pin);
LM_State = digitalRead(LM_Pin);
LR_State = digitalRead(LR_Pin);
LP_State = digitalRead(LP_Pin);

//Right Index
if (RI_State != RI_Old_State) {
if(RI_State == 1) {
RI_Servo_State = !RI_Servo_State;
}
if (RI_Servo_State == 1) {
rightOuterServo.write(EXPAND);
} else {
rightOuterServo.write(STOP);
}
}

//Right Middle
if (RM_State != RM_Old_State) {
if(RM_State == 1) {
RM_Servo_State = !RM_Servo_State;
}
if (RM_Servo_State == 1) {
rightInnerServo.write(EXPAND);
} else {
rightInnerServo.write(STOP);
}
}

//Right Ring
if (RR_State != RR_Old_State) {
if(RR_State == 1) {
RR_Servo_State = !RR_Servo_State;
}
if (RR_Servo_State == 1) {
rightOuterServo.write(CONTRACT);
} else {
rightOuterServo.write(STOP);
}
}

//Right Pinky
if (RP_State != RP_Old_State) {
if(RP_State == 1) {
RP_Servo_State = !RP_Servo_State;
}
if (RP_Servo_State == 1) {
rightInnerServo.write(CONTRACT);
} else {
rightInnerServo.write(STOP);
}
}

//Left Index
if (LI_State != LI_Old_State) {
if(LI_State == 1) {
LI_Servo_State = !LI_Servo_State;
}
if (LI_Servo_State == 1) {
leftOuterServo.write(EXPAND);
} else {
leftOuterServo.write(STOP);
}
}

//Left Middle
if (LM_State != LM_Old_State) {
if(LM_State == 1) {
LM_Servo_State = !LM_Servo_State;
}
if (LM_Servo_State == 1) {
leftInnerServo.write(EXPAND);
} else {
leftInnerServo.write(STOP);
}
}

//Left Ring
if (LR_State != LR_Old_State) {
if(LR_State == 1) {
LR_Servo_State = !LR_Servo_State;
}
if (LR_Servo_State == 1) {
leftOuterServo.write(CONTRACT);
} else {
leftOuterServo.write(STOP);
}
}

//Left Pinky
if (LP_State != LP_Old_State) {
if(LP_State == 1) {
LP_Servo_State = !LP_Servo_State;
}
if (LP_Servo_State == 1) {
leftInnerServo.write(CONTRACT);
} else {
leftInnerServo.write(STOP);
}
}

}













No comments:

Post a Comment