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);
}
}

}













Saturday, August 27, 2011

Archangel Wings: Full Disclosure

So, I've told most people about my Maker Faire project, but I havent mentioned it on here very often because this site was restricted mostly to ITP class assignments. But, class is over and all of you loyal fans (all 3 of you, you are too kind) are here waiting for more, so here goes a full description of the project.

The details:
Life size metal wings inspired by the superhero Archangel
They are going to be made from 7075 alloy, air-craft grade aluminum with a final wingspan of close to 12 feet wide, not exactly to scale from the photo, but those would be impossible to wear. The wing will be be articulated at two joints per wing, one on the aluminum backplate I'll be wearing, and another joint half-way down the wing. At the joints will be spring hinges that spring the wings outwards when contracted. Here is a picture of all the panels laid out on the floor with me in the middle for scale:
The wings were originally supposed to be actuated by shape memory alloy ("muscle wire"), but due to limitations of the high maintenance material I had to abandon it in favor of using servos. All's well that ends well, because they will now be completely under my control with full range of motion as opposed to the 20-30 degrees of motion that the muscle wire was capable of producing. The servos will be attached to the wing panels and backplate and will wind up a low-profile, high-strength fishing line, pulling the wings towards them. Wind it one direction and the wings contract, spin the servo in the other direction and the spring hinges take over and open the wings. Heres a video I made while testing the servo control on small sample pieces of aluminum:



I am working on two different methods of control. Manual control of the wings will definitely be ready by Maker Faire (if not sooner), but I am having a really hard time procuring the right components to make the other work. The other method is to have a heart rate monitor I am wearing send signals to the arduino microcontroller which will then flap the wings at a rate proportional to beating of my heart. A simple toggle switch will alternate between one mode and the other (if I can just get that damn heart rate receiver!)

Manual control of the wings will be wired into two gloves I'll be wearing. Each glove will have small push-button switches hidden in the tips of each of the fingers, each responsible for an individual wing panel. Pressing one finger tip will move a certain panel outwards, pressing another finger will bring it back. This will allow me to control each of the wing panels individually and position them any way I want (even fold them up behind me) just by moving certain fingers. I'm hoping it will give the illusion that they are moving on their own since most people dont often notice what you're doing with your finger tips.

So, thats the full description. I hope you got as excited and curious to see it as I am to build it, because I am pretty F**king stoked.

More updates to come, but on that note, Peace!

Wednesday, August 17, 2011

Final Project - Interactive Table Top Slide Museum Installation

Hey Everyone, I know its really late, but heres a video of my final project for physical computing.

Most of the description is in the video, but the basic idea is that a museum visitor can walk up to the slide, drop a random object at the top and depending on how fast the object slides down and how much it weighs, an animation is displayed that shows how the energy is transfered from potential energy to kinetic energy and how much is lost to friction. Once its running better, students could use the slide as a way to perform their own investigations of friction and energy by sliding objects of different shape, size, weight and texture, or even putting different surfaces on the slide itself like sand paper, wax paper, grease (probably not), etc.

It still needs to be painted, polished and finished, but I think it's looking pretty sleek and minimalist which is what I was going for. Enjoy!

Sunday, August 7, 2011

Final Project Progress Slow Going

Im not going to lie. Im a little bit frustrated. I thought the hardware part of this project (arduino and code) was going to be easy compared to the software part (Max/MSP), but the code Im running into speed bumps everywhere. I wrote what I assumed was working code on the train the other day, but when I put all the components on the breadboard it failed miserably. Things were going wrong everywhere in the code. I basically had to scrap the whole sketch and start over.

Progress is ok so far, but once I started getting anywhere my lasers started dying out. I knew they were rated for 3.0 volts, but I hoped that I could get away with the 3.3 volt source on the arduino without decreasing their lifespan too much. Turns out even the extra 0.3 volts was enough to damage them after a 15-20 (cumulative, not consecutive) minutes of testing.

I snagged a 10 mega-ohm resistor from the ITP shelves that Im thinking I can wire in series with the laser to pull down the voltage, but Im a little hazy on the specifics. I got my bachelors degree in physics, but it was so theoretical I dont feel nearly as comfortable with all the circuitry as I do with the theory (I hope my old professors dont read this, its seriously embarrassing). I can recite ohms law and its applications with the best of them, but when it comes to actually selecting the right resistor to get the proper voltage Im really hesitant. The digital multimeter says that the laser has an internal resistance of just under 20 mega-ohms, so Im thinking if I add in 20 mega-ohms in series it should halve the 5v from the arduino and deliver a much safer 2.5 volts to the laser. Lets see how it goes.

Also, Max is being a real pain in the ass. I've got most of it working, but Im having a hard time making some floating point boxes respond automatically to values that are being fed to them. The thing is I need to have those number boxes update automatically if the values from the arduino are going to be interpreted and fed into the animation by Max. Going to ask Luke before class tomorrow.

Here's a pic of what IM working with, hardware-wise:

I taped the components to a plank of wood to make it easy to tweak the code without having to fiddle with the sensors and getting the alignment right. The force sensing resistor is on the left and the two lasers and light sensing resistors are next to it. There are a few status LEDs n the breadboard, but nothing really noteworthy.

This code doesnt seem like it should be so difficult. One problem I spotted so far is that I was using an if function where I should have been using a do (or a while) function. I want the program to be continually listening to the light sensors to tell when an object has passed by, I was using an IF command to listen and act accordingly, but I think it was moving on to the next part of the program before it actually was triggered. If I use a DO/WHILE command then Im can tell it to listen to the light sensor and do nothing else until it is triggered. Only then should it move to the next task in the code.

Im hoping I can get this running fairly satisfactory before going to sleep. Wish me luck.