Iron Man Arm (w/ LED & Boomco Dart Blaster)
by DavidC1125 in Craft > Costumes & Cosplay
5710 Views, 30 Favorites, 0 Comments
Iron Man Arm (w/ LED & Boomco Dart Blaster)
This instructable was created in fulfillment of the project requirement of the Makecourse at the University of South Florida (www.makecourse.com).
This is an Iron Man glove and forearm that shoots Boomco darts and has an LED palm repulsor light. The "firing" is completely hands-off, triggered by hand position using flex sensors. This is the basic functionality: close your fist, and it shoots the pre-loaded dart; bend your hand back, and the palm lights up. The blaster embedded in the forearm is the guts of a Boomco Halo UNSC H-295. The device is completely self-contained, running off a small power bank for smartphones and controlled by an Arduino Nano. The forearm body is 3D printed PLA plastic, and the glove is just a cheap work glove with recycled PLA 3D printing scraps. Interested? Read on!
Materials
- 3D printing capabilities
- Soldering equipment
- Hot glue gun
- Scissors
- Sandpaper
- A hand drill
- Wire cutters/strippers
- Needlenose pliers
- Screwdrivers
- Laptop with Arduino IDE
- USB mini-B cable such as this one (for connecting Arduino Nano to laptop. I had one from a digital camera)
- Much much easier with some sort of Arduino starter kit with breadboard/jumper wires/electrical components. This is the one I have.
Materials:
- Arduino Nano
- Boomco Halo UNSC H-295 blaster
- Bestoss 2000mAh phone power bank (Very compact battery for Arduino projects in general)
- USB micro cable such as this one (Will be destroyed. If you don't have a spare, try a dollar store.)
- 2 2.2" flex sensors
- 2 SG90 9G servos
- 1 small white LED bulb (try dissecting a keychain light)
- 1 2N2222 transistor
- 2 220Ω resistors
- 2 10kΩ resistors
- Electrical wire
- Electrical tape
- Loctite marine epoxy
- Super glue
- A glove of choice. I used a nitrile-coated glove, but found that hot glue did not stick to the nitrile very well.
- Around 1' of 1/4" delrin rod
- Plenty of flat pieces of PLA plastic, such as discarded 3D printing rafts and failed prints. This is for making the hand armor. For this I got permission to use the scraps from my University's student design lab. PLA was good for this because I could easily cut it with scissors, and mold it to the desired shape using heat from my desk lamp. Alternative: craft foam.
- 8 small nails for drywall
- 4 3M x 8mm machine screws, with corresponding nuts and small nylon washers
- 1 white translucent milk jug, or similar flat translucent plastic
- A little bit of shiny aluminum foil
- Cardboard
- Rubber bands
- Mod Podge
- Red spray paint of choice (preferably compatible with plastic)
Note: Don't be too intimidated by this list! Take a look at the project, and see what you could do differently. These are simply the things I used.
The Electronics
The Fritzing diagram shown should help a lot for understanding the control circuit. Basically, the Arduino Nano, the two servos, and the two flex sensors run directly off the power bank (so as not to draw too much current from the Arduino). Note that this circuit powers the Arduino directly through the 5v pin, which will definitely fry it if you supply too much voltage (this power supply is safe). The LED runs off the Arduino. There is one other rather important little item. The 2N2222 transistor may seem to be there simply to trigger a waste of power through a resistor -- that is indeed why it is there. It turns out that most phone-charging power banks will automatically shut off after a short time if a minimum current is not drawn. So, by periodically using the transistor to switch current through the resistor, the power bank is kept awake.
The flex sensors change resistance based on how they are bent. One is mounted to the back of the wearer's middle finger, and one is mounted to the back of the wearer's wrist. Through a voltage divider, this allows the Arduino to know when the user's fist is closed and wrist is bent back, respectively. The closing of the fist is used to trigger the dart firing, and the bending-back of the wrist is used to trigger the palm LED.
Both servos and the LED are all controlled by the Arduino through pulse-width-modulated signals (so that the servo positions can be set and the LED can be dimmed).
The Programming
I have attached a zipped folder of the Arduino sketch used for this project. I have tried to keep all variables that could be used to adjust the program functionality at the beginning of the sketch as global variables. The exception is the sheer mass of values controlling the exact timing of the LED dimming. Those are left in the main loop.
The general approach is to repeatedly read values from the flex sensors and trigger the servos or the LED if target flex sensor readings are obtained. For convenience, I have copied the sketch below, though the formatting is much better in the zipped file:
Main sketch:
/************************************************************************************************************************
TITLE: The Iron Man Arm DESCRIPTION: This program uses flex sensor data to determine when to fire a BOOMco blaster using servos or light an LED
AUTHOR: David Cox
MODIFIED: 5/4/2017 ***********************************************************************************************************************/
#include //Includes the servo library
#define flexFist 1 //Analog pin for the flex sensor signal from the back of the knuckle
#define flexWrist 2 //Analog pin for the flex sensor signal from the back of the wrist
#define servoL 9 //PWM pin for the left servo
#define servoR 10 //PWM pin for the right servo
#define ledPin 6 //Digital pin to the LEDs
#define resistorPin 12 //Digital pin for switching current through a resistor, to keep the battery from turning off
Servo myservoL; //Calls the servo library for the left and right servos, respectively Servo myservoR;
int resistorOff = 10000; //These are the lengths of time in ms that the resistor at pin 12 will alternate off and on
int resistorOn = 500;
int resistorState = 0; //The resistor is initially off
int currentTime; //These variables are used to store the time values
int previousTime;
int flexDuration = 500; //Time range in ms over which flex sensor data is averaged for each reading
int fistTarget = 850; //Experimentally determined flex sensor signal at the desired knuckle bend to move the servos
int wristTarget = 835; //Experimentally determined flex sensor signal at the desired wrist bend to light the LEDs
int flagFist = 0; //These two variables indicate if the servos or the LEDs should be activated, respectively
int flagWrist = 0;
int downL = 178; //These four values are found by experiment
int upL = 112; //They are the servo positions in the open and closed states
int downR = 108;
int upR = 175;
int up = 1;
int down = 0;
int servoDelay = 10; //ms delay called after each 1 degree increment of servo motion
//higher value makes the servos move slower
void setup() {
myservoL.attach(servoL); //The left and right servos are initialized and moved to the closed position
myservoL.write(downL);
myservoR.attach(servoR);
myservoR.write(downR);
pinMode(ledPin, OUTPUT); //The LED power pin is initialized and kept off
analogWrite(ledPin, 0);
pinMode(resistorPin, OUTPUT);
digitalWrite(resistorPin, LOW);
currentTime = millis();
previousTime = currentTime;
}
void loop() {
currentTime = millis(); //Stores the current program time value
if (resistorState == 0 && ((currentTime - previousTime) > resistorOff)) { //Runs only if the resistor has been off long enough
digitalWrite(resistorPin, HIGH); //Sends power to the resistor, to draw sufficient current from the power bank
resistorState = 1;
previousTime = currentTime;
}
if (resistorState == 1 && ((currentTime - previousTime) > resistorOn)) { //Runs only if the resistor has been on long enough
digitalWrite(resistorPin, LOW); //Turns off the resistor, to conserve power
resistorState = 0;
}
readFlex(flexFist, fistTarget); //Reading taken of flex sensor at knuckle; outputs whether reading is above target value
readFlex(flexWrist, wristTarget); //Reading taken of flex sensor at wrist; outputs whether reading is above target value
if (flagFist) { //Runs only if knuckle joint is sufficiently bent
moveServos(up); //Servos are moved to the up position to fire the blaster
delay(3000); //Wait time after firing
moveServos(down); //Servos are returned to the down position
}
if (flagWrist) { //Runs only if the wrist is bent sufficiently backward
for (int u = 0; u < 100; u++){ //Loop for gradually increasing LED brightness using pulse-width modulation
analogWrite(ledPin, u);
delay(7);
}
digitalWrite(ledPin, HIGH); //Sets the LED to full brightness
delay(250);
for (int v = 200; v >0; v=v-5){ //Loop for gradually decreasing the LED brightness using pulse-width modulation
analogWrite(ledPin, v);
delay(5);
}
delay(10);
digitalWrite(ledPin, LOW); //The LED is turned completely off
delay(1000); //Delay to prevent the LED from coming back on too soon
}
}
Functions:
void readFlex (int pinnumber, int flagvalue) //This function collects an averaged reading from the specified flex sensor and outputs whether the value
//is lower or higher than the critical "flag" value
{
int flexValue1 = 0; //These six values will be six flex sensor readings
int flexValue2 = 0;
int flexValue3 = 0;
int flexValue4 = 0;
nt flexValue5 = 0;
int flexValue6 = 0;
int flexAvg = 0; //The average of the six readings
for (int i = 0; i < 6; i++) { //The six flex sensor readings are collected
flexValue6 = flexValue5;
flexValue5 = flexValue4;
flexValue4 = flexValue3;
flexValue3 = flexValue2;
flexValue2 = flexValue1;
flexValue1 = analogRead(pinnumber);
delay(flexDuration / 6); //A time delay is set between each reading so that the total reading time is equal to the duration set
}
flexAvg = (flexValue1 + flexValue2 + flexValue3 + flexValue4 + flexValue5 + flexValue6) / 6; //The readings are averaged
if (pinnumber == flexFist) { //Conditions for knuckle flex sensor readings
if (flexAvg > flagvalue) { //Sets the fist status to 1 if the flex sensor is sufficiently bent
flagFist = 1;
}
else {
flagFist = 0;
}
}
if (pinnumber == flexWrist) { //Conditions for wrist flex sensor readings
if (flexAvg > flagvalue) { //Sets the wrist status to 1 if the flex sensor is sufficiently bent
flagWrist = 1;
}
else {
flagWrist = 0;
}
}
}
void moveServos (int target) //This function moves both servos together to the specified "target" (the open or closed position)
{
int Ltarget; //Local variables for the desired left and right servo positions
int Rtarget;
int Lstate; //Local variables for the measured left and right servo positions
int Rstate;
if (target == up) { //Calls the global variables for servos' up positions
Ltarget = upL;
Rtarget = upR;
}
if (target == down) { //Calls the global variables for the servos' down positions
Ltarget = downL;
Rtarget = downR;
}
Lstate = myservoL.read(); //Initially reads the servo positions
Rstate = myservoR.read();
while (Lstate != Ltarget || Rstate != Rtarget) { //This runs until both servos reach the desired position
if (Lstate < Ltarget) { //Increments the left servo angle if it needs to be higher
myservoL.write(Lstate+1);
}
if (Lstate > Ltarget) { //Decrements the left servo angle if it needs to be lower
myservoL.write(Lstate-1);
}
if (Rstate < Rtarget) { //Increments the right servo angle if it needs to be higher
myservoR.write(Rstate+1);
}
if (Rstate > Rtarget) { //Decrements the right servo angle if it needs to be lower
myservoR.write(Rstate-1);
}
delay(servoDelay); //To slow the servo motion, waits a specified time after each degree of rotation
Lstate = myservoL.read(); //Re-reads the servo positions for the next iteration
Rstate = myservoR.read();
}
}
Downloads
Preparing to Build
The Glove:
The first step for the glove is to get a template that works for the decorative armor pieces. In this I was heavily inspired by this excellent tutorial. That tutorial contains hand template files for the free program Pepakura Viewer, which I would recommend for your project (see the pictures for what the templates look like within the program). Using that program and the template files, I was able to print paper templates. I found them to be a bit big, so I scaled them down to 93%. I have attached zipped pdfs of both the full-scale and scaled-down templates. I recommend printing these on standard paper, cutting them out, and then taping them together to try on a paper version of the glove for size. Make adjustments as needed, and then you have templates for whatever material you choose to make the hand armor out of. I used PLA plastic, but the tutorial before mentioned has good information for using craft foam, if that is more easily available.
The Forearm:
The first step is to buy the Boomco dart blaster and disassemble it. You will salvage the grey internal blaster part with the plunger, the darts, and the tiny springs.
The next step is to get everything else 3D printed. I have attached all of the STL files I created for this project using Autodesk Inventor.
Assembling
I apologize for the major picture dump at this step, but I feel that is the best way to explain the many things that went into assembling this project. Please follow along with the comments on the pictures for understanding each component.
One thing that I could not get good pictures of is the LED inside the glove. The bulb is sandwiched between two small pieces of cardboard, with the bulb sticking through a hole in the middle of one of the pieces of cardboard, and also through a hole in the glove. The cardboard is super glued to the inside of the glove, with the LED's wires coming out. To give credit where credit is due, the LED palm light design is inspired by this tutorial.
Thank you for reading my first Instructable!