Introduction: 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!

Step 1: Materials

Equipment:
  • 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.

Step 2: 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).

Step 3: 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();

}

}

Step 4: 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.

Step 5: 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!