Introduction: Animatronic Iron Man Mk III Suit
Iron Man costumes have been extremely popular lately and the number one question I am most often asked is "How can I add animatronics to my suit?" My friend Greg wanted to add animatronics to his MkIII fiberglass suit so he asked for my help and for this suit we went all out.
We wanted to add as many functions as seen in the movies as possible, which wasn't easy given that most of those sequences were not done using practical effects. The other issue was how should all of the functions be actuated? After considering several options we used RFID tags in the gloves to trigger the shoulder rocket pods, hip pods, forearm missile, back flaps and helmet. The helmet has wireless control via XBee radios. The boots light up and make sound while walking by using an infrared distance sensor in the boot to trigger the effect.
Here's a video that shows all of the suit functions-
This is certainly not an easy project but if you know your way around an Arduino and can wield a soldering iron this instructable will show you how to do it.
Be sure to click on any picture to get a larger version.
Update: I've also created an animatronics forum where people can go to get help with their costume and prop projects. I get so many messages for specific project help from people that I decided to create a dedicated forum where everyone can get help and share ideas!
Let's get started!
Step 1: Build Design/details
The suit is basically broken down into three systems: left side, right side and boots.
The left hand has two RFID tags that trigger programmed sequences for the helmet, hip pods and back flaps. The right hand RFID tags trigger programmed sequences for the forearm missile and shoulder rockets. The boots have an infrared sensor that triggers the boot lights and sound effect as soon as the boot is lifted from the ground.
The single most difficult thing about this build is that the suit fits like a glove- there's no room in it! The helmet has less than 1/2" of space around the head, there's about 1" depth for the shoulder rocket pods and the hip pod area has less than 1" depth available so the packaging of the mechanics and electronics is really tight. Another issue is that there's almost no flat surfaces so mounting servos and hardware gets really interesting.
The system is Arduino based and uses four ProMinis- one for each side, one for the boots and one in the helmet. Since we wanted the helmet to be easy to take on and off we decided to make it wireless using XBee radios to send the control signals. For the point to point wiring running from the electronics mounted in the back to the arms and feet we used Ethernet cables and jacks so they could be easily disconnected. The sound effects for the boots are handled by a WaveShield that sits on a Arduino Pro.
If you are not familiar with Arduino and XBee radios then please read through this instructable. It will explain a lot of the basics and you'll be up and running in no time!
Another issue with systems like this are the different voltage and current requirements so we thought it best to power the servos separately using AA batteries, primarily for ease of availability if the suit is to be worn at conventions.
Step 2: Tools and Materials
As far as tools go, most all of the work was done with basic tools-
I used a scroll saw to cut the plywood, soldering iron/torch, wire cutters, pliers, screwdrivers, glue gun and a Dremel tool. A multimeter will also come in very handy, as will a servo programmer. A servo programmer allows you to adjust several performance parameters of digital servos, such as speed, direction of rotation, etc. They can also be used to test a servo's movement, which is super handy when installing servos.
Soldering iron- I've used a lot of different soldering irons and my favorite (by far!) is made by Pace. The Pace ST50 is the digital version of my iron. A less expensive but also very, very nice iron is the Hakko FX-951.
A bit of fiberglass work was done in the helmet and for this I really like epoxy resin- I use West Systems epoxies. Epoxy resin doesn't smell and it's a lot tougher than polyester resin. The West Systems epoxy resin also has an incredibly long shelf life and it's super easy to mix if you use their metered pumps. ProPoxy 20 (a two part epoxy putty) is something that I use a lot when bonding various materials- it's great for bonding metals to plastic. I also use a lot of super glue for tacking parts in place before securing them with epoxy putty. My favorite is Gorilla glue and I often use an accelerator to speed it's drying time. Apoxie Sculpt is used to fill gaps and add sculpted details. For mounting servos (when you don't want to use screws) I really like high strength Velcro- it allows you to easily remove the servo for repositioning.
West Sytems Epoxy
ProPoxy 20
Gorilla super glue
Apoxie Sculpt
High strength Velcro
Make sure to wear a respirator when cutting and sanding fiberglass! I also always wear disposable gloves when working with epoxies and resins.
Most of the build materials were nothing special. For pivots I used brass tube, rod and music wire. The exact size isn't particularly important- I used whatever I had in my scrap bin. Brass and Aluminum sheet was also used to make parts for servo linkages. As long as it's it's not super thin material the exact size isn't really important. All of the brass sheet used is 1/16" (1.6mm) thick. The Aluminum sheet used for the shoulder rocket servo arms is around 1/8" (3.2mm) thick. Birch plywood was used for things like servo mounts, the rocket pods and hip pods.
Brass sheet, tubing, rod and music wire is manufactured by K&S Metals.
I buy Aluminum sheet from Online Metals.
As far as electronics are concerned it's quite the laundry list-
2 | × | ID-12 RFID tag readerSparkfun part # SEN-11827 (LA version is replacement) |
2 | × | XBee Series 1 module Sparkfun part # WRL-11215 |
2 | × | Adafruit XBee Adapter board Adafruit Product ID: 126 |
2 | × | Arduino ProMini 328 5V Sparkfun part # DEV-11113 |
1 | × | Arduino ProMini 328 3.3V Sparkfun part # DEV-11114 |
1 | × | Arduino Pro 328 5V Sparkfun part # DEV-10915 |
1 | × | Adafruit Wave Shield Adafruit Product ID: 94 |
1 | × | Pololu 5V DC/DC converter D24V5F5-steps down the helmet 7.4V battery voltage for the ProMini |
5 | × | Hitec HS-5055MG sub-micro servo for the forearm gauntlet /hip pods- Servocity.com |
8 | × | Hitec HS-85MG micro servo for the shoulder rocket pods/ hip pods- Servocity.com |
3 | × | Hitec HS-82MG servo micro for the forearm gauntlet pod/shoulder rocket pods- Servocity.com |
2 | × | Hitec HS-485HB standard servo for the back flaps- Servocity.com |
1 | × | Hitec HS-5087MH micro servo for the helmet chin section- Servocity.com |
1 | × | Hitec HS-7245MH mini servo for the helmet faceplate- Servocity.com |
4 | × | 16mm RFID button tag (125 kHz) Sparkfun part # SEN-09417 |
2 | × | Luxeon Rebel high power white LED for the lights in the boots Sparkfun part # BOB-09656 |
1 | × | Sharp GP2D120XJ00F Infrared Proximity Sensor Sensor for the bottom of the boot Sparkfun part # SEN-08959 |
8 | × | RJ45 8-pin connector Ethernet cable connector Sparkfun part # PRT-00643 |
8 | × | Breakout Board for RJ45 Sparkfun part # BOB-00716 |
1 | × | 7027 "BuckToot" LED Driver Module to power the Luxeon LEDs Sparkfun part # COM-09642 |
4 | × | JST RCY Connector for the helmet battery packs Sparkfun part # PRT-10501 |
6 | × | AAA NiMH cells 1.2V for the helmet battery pack - local grocery store |
2 | × | RFID reader breakout Sparkfun part # Product SEN-08423 |
1 | × | SD/MicroSD Memory Card (4 GB SDHC) Adafruit Product ID: 102 |
4 | × | Straight Break Away Headers - for making connectors/servo leads Sparkfun part # PRT-00116 |
4 | × | Female Headers for making connectors/servo leads Sparkfun part # PRT-00115 |
2 | × | Adafruit Perma-Proto Quarter-sized Breadboard for mounting connectors, etc. Adafruit Product ID: 589 |
6 x TIP 120 transistors for turning on LEDs and triggering sound effects. Digkey sells them.
10 x power slide switches. These connect all of the individual power sources in the suit. Digikey sells them.
1 x Adafruit tactile on/off power switch for helmet- Adafruit Product ID: 1092
2 x 4-40 swivel links (pkg of 4)- you need two links for the helmet, two for the forearm missile and four for the hip pods- Servocity.com
2 x 4-40 12" length threaded rod- used to make the helmet and hip pod servo linkages- Servocity.com
34 x PLCC-2 package SMT white LEDs- 10 for the eyes and 24 for the chest light. You could easily substitute standard LEDs. I buy these in bulk on eBay but retailers like Digikey also sell them.
34 x 1206 package 100 Ohm SMT resistors- 10 for the eyes and 24 for the chest light.You could easily substitute standard resistors. I buy these surplus from a local shop but retailers like Digikey also sell them.
1- SMD prototyping board- used for soldering the surface mount LEDs and resistors for the eyes. Sparkfun part # PRT-08708
16 x 5mm white LEDs- for the hip pods.
16 x 100 Ohm resistors (1/8 Watt)- for the hip pods.
I also used a LOT of wire! The wire and Ethernet cables I used came from salvaged electronics- primarily computers and printers. I definitely recommend using stranded wire as it's a lot more flexible, which is pretty important since a suit like this will see a fair bit of movement.
Zip ties and various sizes of heat shrink tubing will also come in very handy.
Step 3: Build Tips
Notes about mechanics and suit construction:
Greg's suit is molded fiberglass. It is unlikely that a foam suit would be rigid enough to support the animatronic systems without some sort of reinforcement, especially in the shoulders as a large area has to be cut away.
It would also be best to have a finished assembled (but not painted) wearable suit before adding any animatronic system. It is important to know exactly how much room you have to work with and how it fits the suit performer before adding animatronics.
There are lots of different ways the mechanics of this suit could have been constructed. We tried to use readily available materials found in hobby shops and hardware stores whenever possible to save time and money. Items such as the shoulder rocket pods and hip pod hinge assemblies could easily be 3d printed if so desired.
A few notes and tips concerning the use of servos in the build:
The servos listed are just what we used based on speed, power, durability and cost requirements. I would definitely recommend using metal gear servos with ball bearings. Nylon geared servos strip very easily, especially the micro and sub-micro variety.
Several of the servos will need to be changed to reverse rotation since the right and left side of various suit parts receive the same control signal. There are three options- use digital servos (easiest but most expensive), have the supplier change the rotation (Servocity.com does this) or change the rotation yourself by taking the servo apart and reversing the motor lead wires and the outer two pot wires. I changed them on the micro servos for the shoulder rockets and hip pods myself since I'm cheap. :)
We did elect to use high voltage digital servos in the helmet for the power they provide and the fact that their speed can be adjusted using a servo programmer. The servos for the hip pod sliding panels and gauntlet side panels also used digital servos since they needed to be powerful and swapping the wires on sub-micro servos can be really tricky. The other reason was because the standard sub-micro servos use nylon gears and we wanted to use metal gears for durability.
The servo position values in the code will probably need to be altered for another build since no two Iron Man suits are alike. The key when doing this is to make small changes in the values while paying attention to make sure the servos don't ever stall, as they can be easily damaged. If a servo does stall immediately turn off the power to the servos and make adjustments to the code.
Step 4: Wireless Helmet
The first item on our list was making the helmet open.
Figuring out how to make the helmet work was pretty tricky. We definitely wanted it to be wireless so it could be easily taken off but there's barely any room in the helmet for servos, let alone electronics. When Greg brought the helmet to me it had tracks already molded in the top for two small pivoting links that were attached to the top of the faceplate. The faceplate had two pivoting arms that allowed it to flip up and slide back. The first system I installed to motorize the helmet used two identical high voltage digital mini servos with a rod system that moved the faceplate and chin at the same time. As the servos pulled the rods the arms raised the faceplate and a second pivoting rod pushed the chin section open. While this system worked well it was eventually scrapped as it took up too much space around the sides of the helmet, especially in the temple area where the arm pivots were located.
Here's a video of the first helmet test. You can see the RFID reader and XBee radio on a breadboard test circuit at the beginning of the video-
The revised system works a bit different and is much simpler. I altered the original helmet system by changing it from a multi link/multi pivot system to a simple three pivot system. The arms that lifted the faceplate were removed as were their four pivots. The tracks in the top of the helmet were kept but the links had a tendency to bind as they pivoted so the links were reconstructed from scratch as fixed points and epoxied to the top of the helmet faceplate using ProPoxy 20 epoxy putty in a fixed position.
The servo mechanism was changed so one mini servo would open the faceplate while another would open the chin- that way the timing could be changed so the faceplate would open first and then the chin would open. When closing the helmet the chin would close first, then the faceplate. The faceplate servo has a brass arm that is silver soldered to a hinge that is fiberglassed into the top center section of the helmet. The brass plate that is soldered to the hinge tube is extended back a ways in order to support the helmet section as it would otherwise be too flexy to work properly. Both of the servos are attached to the helmet using high strength Velcro.
The chin servo was swapped out for a micro servo and it pushes a 4-40 threaded rod that opens the chin section- it's a pretty simple arrangement. Eventually the chin servo was relocated closer to the center of the chin section to make more room for one of the battery packs.
Here's the video of the revised helmet animatronics. Notice the removal of the arms needed to lift the faceplate-
On the electronics side, a split battery pack was constructed using six AAA NiMH cells for a total of 7.4V to power the high voltage digital servos. Originally we had planned on using LiPo packs but felt that NiMH cells would be a lot safer and less hassle in terms of battery management- see the FAQ section for more info. The two battery packs were wired up to an Arduino ProMini (3.3V version) along with a XBee radio. Power to the ProMini was stepped down to 5V using a Pololu DC/DC converter. The electronics were covered with heat shrink for protection. I use a Hitec X1 MF charger to charge the helmet battery packs.
A sealed push button power switch was added along with a transistor to turn on the LED lights for the eyes. The eyes were constructed using white SMT LEDs (any small LEDs will work) with milk jug material being used for the lenses. The lenses have a slit at the top so the wearer can see out and black foam sheet was used to block out the light on the inside of the helmet.
Finally all of the electronics were secured in the chin section of the helmet. Everything just barely fit in there without being able to be seen when the helmet is open. Overall we're very pleased with how the helmet turned out. It opens very quickly and we can change the speed of the servos along with the timing of the opening/closing sequence very easily.
So now the question is: "What if my helmet doesn't have tracks molded in the top of the helmet?"
If you have a Iron Man helmet from a kit or made it yourself using the pepakura method you can add molded tracks. Another friend of mine had a MkIV helmet he wanted to animate as a display piece. I used the same mechanical system as Greg's MkIII helmet but the MkIV didn't have tracks molded in the top of the helmet so I added them. The first thing I did was take a small round plastic rods and coat them with a thin layer of Vaseline- this is VERY important! The Vaseline acts as a mold release so you can remove the rods later. The rods were placed on the underside of the helmet where the tracks were to be located- it is important to get the tracks as parallel as possible or the links will bind as the faceplate opens.
Next I mixed up some ProPoxy 20 epoxy putty and built it up over the plastic rods. Once the epoxy putty cured I laid up some lightweight fiberglass cloth on top with some epoxy resin. The fiberglass cloth will reinforce the epoxy putty and make sure it doesn't debond from the underside of the helmet. Then I removed the plastic rods and cut the slots in the top of the helmet so the ball link guides could slide in the grooves. The slots in the top of the helmet must be narrower than the molded grooves so the ball link doesn't come out as the faceplate slides back.
I silver soldered the ball links that attach to the top of the faceplate but there is another, simpler option. You can buy nylon balls in all different sizes- drill a hole through the ball and attach it to one end of the "L" shaped rod by flattening the rod slightly (this will help hold the ball on the rod) and put a drop of superglue on it to secure it.
One thing I found really helpful was to attach my rods to the faceplate with superglue (use an accelerator spray- baking soda also works) and slide the faceplate back to make sure it has a smooth motion. Once you get the positioning right then use the epoxy putty to secure them.
Step 5: Forearm Gauntlet Missile
Other than the helmet, one of the features we viewed as a "must have" item for the suit was the forearm missile.
Much like the helmet, the forearm gauntlet missile has some really tight packaging. There was also the issue that in the film when the gauntlet opens it's done as a visual effect (as are most all of the suit functions) so we had to figure out to turn the visual effect into a practical effect.
We had seen other missile compartments that people had done but they usually only had the top open- we wanted the sides to fold down as well. The other thing we wanted was for the missile pod to open up and back, just like in the movie. We also wanted the missile to extend outward- in for a penny, in for a pound!
To make the opening compartment the fiberglass gauntlet was first cut apart into the appropriate sections and a plastic base plate was epoxied into the opening. The base plate gives a nice flat surface to mount the servos. Each of the cut side panels has a 4-40 screw epoxied onto the inside forward point using Propoxy 20. Onto this screw was fitted a swivel link with a rod that was epoxied into the forward section of the gauntlet. This formed a single pivot multidirectional hinge for the front of each of the side panels.
To make the side panels fold down two sub-micro servos have their arms fitted with a small section of bent music wire that was epoxied to the back of each of the side panels. The servos are attached to the base plate using high strength Velcro. As the servo arms rotate the side panels drop down. A very simple and reliable system.
The missile housing was constructed using thin birch plywood sheet. To make the housing move up and back a small parallelogram linkage was fabricated and attached to the micro servo that raises the housing. The servo is attached to the gauntlet base plate using high strength Velcro. The forward hinge uses a 4-40 swivel link attached to the plywood housing- a small hole is drilled in the missile housing and the swivel link rod is epoxied in place. The rear link uses music wire that pivots in brass tubes epoxied to both the servo and the plywood housing. The face of the missile housing was built up using Apoxie Sculpt.
The missile is moved forward in the housing by a sub-micro servo with a long arm. The servo is mounted to the underside of the pod and the arm extends through the bottom of the pod. A short length of music wire is attached to the servo arm and goes through the back center of the missile so as the servo arm rotates the missile extends and retracts through the pod opening. The missile is a short length of wood dowel sanded to shape.
The AA battery holders are held underneath the base plate along with a power switch and an Ethernet connector. The Ethernet connector is mounted to a small PCB with connectors for the servos and it also has extended wires that reach the gloves. An Ethernet cable runs from the Arduino in the back of suit, down the arm and then connects to the gauntlet. This cable carries the signals for the servos as well as signals and power to the RFID reader in the glove.
That's a whole lot of hardware in a very small space. Believe it or not his arm fits in there no problem- the opening is a lot bigger than it looks in the photo. The gauntlet worked perfect right out of the gate, which was awesome.
Step 6: Shoulder Rocket Pods
We really wanted opening shoulder rocket pods. Bad.
We thought it would be so cool to have shoulder rocket pods open up and unfold like in the movie. The trouble was there was no way they could ever fit in there and perform in a similar fashion- the suit simply didn't have the necessary internal volume. There is only about one inch of usable depth in the shoulder area. Those darn visual effects again...
Once I began taking measurements with Greg in the suit I wasn't so sure it could be done. Nobody had ever done it in a costume. I think I probably sketched a couple hundred designs trying to figure out a way to have the pod raise up and fold over. This was a key feature I really, really wanted. I didn't want to have a pod that opened like one of those pop up car headlamps where there is just a single panel that lifts up. I knew I couldn't have it perform like in the film with the entire shoulder section moving but I felt I could get something that looked really cool. Once I got the designs narrowed down I used a free program called ForceEffect Motion to play around with linkage mechanics. I used my design sketches as background images and then I would draw my linkage mechanics on top of them. This allowed me to very quickly explore a lot design options and animate the mechanics. It's an awesome app for doing work like this.
I finally settled on having a section of the shoulder split into two panels- one lifting/rotating forward and one lifting/rotating backward. This would give a decent sized opening for a proper size rocket pod. I wanted the rocket pod to be very close in size to the movie pod. The big trick to making it work was making the pod an open box so the servo could hide inside it- without that there was no way it would ever fit in the shoulder cavity.
The pod is constructed of birch plywood and pivots are fabricated from brass tube and music wire. As the pod servo arm rotates the rear of the rocket pod is pushed away from the servo. The pod servo is mounted to a 1/8" thick Aluminum plate that is attached to the forward shoulder panel servo. The rear panel servo has a similar Aluminum plate attached to it. The Aluminum plates have threaded holes in them for attaching the moving shoulder panels with small brass angle brackets, which are epoxied to the moving shoulder panels. The holes in the brass angle brackets are slotted to allow for a small range of height adjustment of the shoulder panel.
There was an enormous amount of trial and error fitting as once the shoulder sections were cut out of the fiberglass suit there would be no turning back- we had to be right on the money the first time. The panel openings were taped off and cut out using a Dremel tool with a cutoff wheel and then the servos were mounted inside the shoulder area using plywood mounts epoxied into place. Getting the panels to fit just right was a real challenge.
It took a bit of playing with the code to get the movements just right as the rear panel has to open first, then the front panel and finally the pod flipping over and then reversing the sequence to have them close.
While the finished pods are by no means movie accurate they look really cool when they open up. I think we surprised a lot of our Iron Man suit building friends when they saw them work for the first time!
Step 7: Hip Pods
Originally we hadn't planned on adding the hip pods.
Greg now knows me well enough to know that I tend to first say it can't be done or isn't probable and then fifteen minutes later I'd call him and tell him I figured it out- that's just my M.O. The hip pods are a perfect example of this. I first looked at the suit and said "no way." But of course it bugged me because it would be so cool to have them move... So first I figured out how to make them pop out of the hip section. Then I thought it would be great if they could rotate. Then I thought, well heck- might as well make the lever on the cover plate slide and have them light up with sound effects!
To make the pods pop out I took four small hinges and welded them together in pairs to make a parallelogram hinge and then added a micro servo to move the hinge. The servo linkage is made from two 4-40 swivel links and a small length of 4-40 threaded rod. The linkage attaches to the parallelogram hinge using a small brass angle section that is bolted to the hinge. The finished mechanism is very low profile. If you can't weld the hinges together they could be bolted together even joined together using an overlapping piece of wood or metal and epoxy or silver solder. Other options would be to machine them from metal or 3d print the hinges.
Getting the pods to fit right was tricky because the fiberglass hip section was molded as one piece so everything had to be cut apart and reconstructed. The faceplate of the pod was cut away and hollowed out to make a shell and a housing was made from ABS pipe. A backing plate was cut from birch plywood and screwed to the ABS pipe with small wood screws.
Several ideas were tried for the pod faceplate rotation system but ultimately I decided to drive the cover plate directly by a servo as that took up the least amount of space. The rotation servo is mounted to a piece of plywood that is bolted to the hinge assembly and plywood backing plate. LEDs are mounted in drilled holes in the ABS ring to simulate the flares.
A large servo wheel is mounted to the rotation servo and it drives the pod cover plate. To make the lever on the cover plate slide open a sub-micro servo is mounted to a plywood plate that is attached to the servo wheel. The servo output arm has a small slot cut in it and it is attached to the sliding cover plate lever with a small section of music wire that is epoxied in place on the backside of the sliding lever. The lever slides on a small hinge made from music wire and brass tubing- the hinge is epoxied to the large servo wheel. As the servo arm moves the hinge rotates slightly outward and the lever slides open. This particular mechanism required a lot of trial and error fitting to get it to move smoothly with very little friction.
Here's a video that shows the first test of the pod cover plate lever sliding open-
Since the suit hip section had been cut away in order to use the pods we had to reconstruct the flanges on the back hip section. Sintra sheet was cut, formed to shape and epoxied in place and then the seams were filled in with Apoxie Sculpt.
In the end the hip pods worked really well and I'm glad we went to the trouble of adding them!
Step 8: Back Flaps
The back flaps are fairly simple to animate.
The flaps were first held in place with tape in order to locate the hinges. Hinges were constructed using brass rod and tube and they were epoxied to the back of the flaps. The hinges were then mounted to the back of the upper torso by drilling holes and using epoxy putty to bond them in place. Control horns were mounted to the flaps and slots were cut in the upper back torso section so the control horns and connecting rods could fit through. The servos that move the back flaps are mounted to the inside of the upper back torso using high strength Velcro.
Step 9: Boots
We knew that we wanted to boots to light up and make a robotic clanking sound while walking.
I figured the easiest way to trigger this effect was to use a distance sensor on the underside of the boot- in this case the Sharp GP2D120XJ00F IR sensor. The sensor reads the distance from the boot to the ground and then a threshold value is set in the code so when the value exceeds the threshold the sensor tells the Arduino to turn on the light and activate the sound. Simple!
A cavity was carved out of the bottom of the boot with a Dremel tool and the sensor was mounted in place. A hole was drilled for the sensor wires as well as the wires for the high power Luxeon LED. The wires for these were bundled together and a connector was soldered on so they could be easily disconnected from the wires that ran down through the legs of the suit. Only one sensor is needed to trigger the Arduino so the sensor was mounted in the right boot since Greg begins walking with his right foot first.
Step 10: Electronics
The electronics system for this suit isn't really that complex once it's broken down into separate systems.
The reason I wanted to make the left side/right side and boots separate systems was so they could be run at the same time and if one system went down the rest of the suit would still operate.
The left side takes the RFID tag input from two fingers on the left hand and then the Arduino will operate either the helmet functions (via the XBee radio) or it will have the hip pods and back flaps run through a programmed sequence.
The right side takes the RFID tag input from two fingers on the right hand and then a second Arduino operates either the hip pods or shoulder rockets, depending on which tag is read. If the hip pods are selected then the Wave Shield is also triggered to play a sound effect.
The IR sensor in the right boot sends a signal to another Arduino that operates the lights for the boots and triggers the Wave Shield to play a sound effect.
For testing purposes I glued RFID tags and a tag reader to a glove to get an idea as to how easy it would be to operate, since the tag reader can only read one tag at a time. Reading two tags at the same time gives zero output. I was worried that since the fingers were in close proximity to one another this could be a problem, but it turns out it worked just fine.
The tag reader was then mounted to the inside of the fiberglass suit glove shell using adhesive foam tape. The back side of the board was then taped over to protect it and the lead wires. The glove shells fit over a batting glove so the wearer's hand never comes in contact with the board. The gloves have extension leads that connect to the gauntlets, which have Ethernet jacks for connecting to the Ethernet cables that run through the arms. The left gauntlet is pretty much empty while the right gauntlet has AA battery holders as well as a small connector board for the servo wires.
The three Arduino Pro Minis are mounted in the back of the upper torso section along with batteries and power switches for each system. The power switches listed in the materials section are rated at 4 Amps, which should suffice for the current draw of the various servos. I used TIP 120 transistors in the circuits because I always seem to have them on hand- you can use any switching transistor you want as long as it can handle the LED current draw in the various circuits.
The Wave Shield sits atop the Arduino Pro in the center and the transmitting XBee radio for the helmet is visible in the upper corner. There are also several Ethernet jacks visible- two for the arms, two for the legs and one for the Ethernet cable that runs to the hip section. Also visible is a board that has a few transistors on it- these take the signals from the Arduinos and turn on the boot lights and trigger the sound effects via the Wave Shield. The Wave Shield output is boosted by a (optional) small amplifier board. There is a small breadboard PCB in the upper corner that has connectors for the shoulder rocket servos and back flap servos. The two speakers were salvaged from an old monitor.
The boards are secured using foam tape as it holds them securely but they can still be removed and if wires get pulled nothing will get damaged. The Ethernet cables were also secured using hot glue a bit away from the connectors in order to provide some strain relief.
If I was to do it again I would probably create a single board down the center and have the Arduinos socketed along with a socketed transistor board using SMD transistors. I would also have the servo connectors on the center board. That would go a log way toward cleaning up the wiring.
The hip pod section uses a small breadboard PCB with an Ethernet connector to route the signals for the servos and LEDs in the pods. There is a small transistor board that is used to turn on the pod LEDs. The wires from the LEDs are run through the back of the pods near the hinge and heatshrink tubing is used protect the wires from potential damage caused by hinge movement.
Finally the AA batteries that provide power to the hip pod servos were mounted to the inside of the chest section near the chest light along with a switch. A power lead with a JST connector was run to the hip pod section.
Much to my surprise, everything actually worked the first time it powered up (even though I had breadboarded the circuits for testing.) The only thing I had to do was make adjustments to timing and servo movements in the code.
Step 11: Electronics- Left Side Schematic and Code
Here's the schematic for the left side control system.
There are a few notes on the diagram but it's pretty straightforward. When parts were purchased for the suit the ID12 tag reader was only available in a 5V version, which is powered by the Arduino. Since the servos are powered by a 6V battery pack it was easiest to just use a 9V battery for the Arduinos and 6V packs for the servos because you need to isolate the power supply for the Arduino due to the electrical noise generated by the servos.
Now that the ID12 is available in a low voltage version it would be simpler to power everything from a 6V battery pack and use a 3.3V Arduino Pro Mini and use a 3.3V DC/DC converter to supply isolated power the Arduino. The Wave Shield however will only operate on 5V.
In the code you will see that all four finger RFID tags are listed but only two tag IDs are recognized in the code. I just found it easier to list all of the tags I was using for the suit build and then single out the individual tag IDs for specific functions. Note that you will of course have to enter your own tag ID codes. For more info on RFID tag readers and identifying tag ID codes have a look at this great Bildr article.
Note that you will need to change the name of the hip pod flare audio file to "SOUND1.WAV" for the Wave Shield to play it. You also need to reverse the servo rotation direction for three of the hip pod servos since they are grouped in pairs that receive an identical signal.
Here's the code-
#include
#include "Servo.h" // include the servo library
Servo podServo; // servo to move hip pods
Servo leverServo; // servo to move hip pod levers
Servo rotateServo; // servo to rotate hip pods
Servo leftflapServo; // servo to move left back flap
Servo rightflapServo; // servo to move right back flap
NewSoftSerial mySerial = NewSoftSerial(2, 3);
int RFIDResetPin = 13;
int ledPin1 = 6; // control pin for left hip pod LEDs
int ledPin2 = 5; // control pin for right hip pod LEDs
int servoPin1 = 10; // control pin for left flap servo
int servoPin2 = 11; // control pin for right flap servo
int servoPin3 = 9; // control pin for pod servo
int servoPin4 = 8; // control pin for lever servo
int servoPin5 = 7; // control pin for rotate servo
int soundPin = 12; // control pin for flare sound
//Register your RFID tags here
char tag1[13] = "440085E77452"; // you will need to change this for your own tag
char tag2[13] = "440085FC330E";
char tag3[13] = "440085F97840";
char tag4[13] = "4400863914EF";
void setup(){
Serial.begin(9600);
mySerial.begin(9600);
podServo.attach(servoPin3); // attaches the servo on pin 9 to the servo object
leverServo.attach(servoPin4); // attaches the servo on pin 8 to the servo object
rotateServo.attach(servoPin5); // attaches the servo on pin 7 to the servo object
leftflapServo.attach(servoPin1); // attches the servo on pin 10 to the servo object
rightflapServo.attach(servoPin2); // attaches the servo on pin 11 to the servo object
podServo.write(155); // rotate the pod servo to 135 degrees
leverServo.write(145); // rotate the lever servo to 135 degrees
rotateServo.write(165); // rotate the pod rotation servo to 170 degrees
leftflapServo.write(170); // rotate the left flap servo to 170 degrees
rightflapServo.write(10); // rotate the right flap servo to 10 degrees
pinMode(ledPin1, OUTPUT); // sets the LED pin as an output
pinMode(ledPin2, OUTPUT); // sets the LED pin as an output
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
pinMode(soundPin, OUTPUT); // sets the sound pin as output
digitalWrite(soundPin, LOW); // turn off sound pin
pinMode(RFIDResetPin, OUTPUT);
digitalWrite(RFIDResetPin, HIGH);
}
void loop(){
char tagString[13];
int index = 0;
boolean reading = false;
while(Serial.available()){
int readByte = Serial.read(); //read next available byte
if(readByte == 2) reading = true; //begining of tag
if(readByte == 3) reading = false; //end of tag
if(reading && readByte != 2 && readByte != 10 && readByte != 13){
//store the tag
tagString[index] = readByte;
index ++;
}
}
checkTag(tagString); // check if it is a match
clearTag(tagString); // clear the char of all value
resetReader(); // reset the RFID reader
}
void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////
if(strlen(tag) == 0) return; // empty, no need to continue
if(compareTag(tag, tag1)){ // if matched tag1, do this
mySerial.print('A'); // sends tag read over XBee
}else if(compareTag(tag, tag2)){ // if matched tag2, do this
podServo.write(90); // rotate the pod servo to 90 degrees
delay(500); // wait half a second
leverServo.write(95); // rotate the lever servo to 90 degrees
delay(1000);
rotateServo.write(5); // rotate the pod rotation servo to 10 degrees
delay(1500);
leverServo.write(145);
delay(500);
digitalWrite(soundPin, HIGH); // turn sound on
delay(10); // wait ten milliseconds
digitalWrite(soundPin, LOW); // turn sound off
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50); // wait 50 milliseconds
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn off LEDs
digitalWrite(ledPin2, HIGH); // turn off LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn off LEDs
digitalWrite(ledPin2, HIGH); // turn off LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn off LEDs
digitalWrite(ledPin2, HIGH); // turn off LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn off LEDs
digitalWrite(ledPin2, HIGH); // turn off LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
delay(50);
digitalWrite(ledPin1, HIGH); // turn on LEDs
digitalWrite(ledPin2, HIGH); // turn on LEDs
delay(50);
digitalWrite(ledPin1, LOW); // turn off LEDs
digitalWrite(ledPin2, LOW); // turn off LEDs
leverServo.write(95); // rotate the lever servo to 90 degrees
delay(1500);
rotateServo.write(165); // rotate the pod servo to 135 degrees
delay(1000);
leverServo.write(145);
delay(500);
podServo.write(155); // rotate the pod servo to 135 degrees
delay(2000);
leftflapServo.write(125); // rotate the left flap servo to 125 degrees- full up
rightflapServo.write(55); // rotate the right flap servo to 55 degrees- full up
delay(500);
leftflapServo.write(170); // rotate the left flap servo to 170 degrees- full down
rightflapServo.write(10); // rotate the right flap servo to 10 degrees- full down
delay(500);
leftflapServo.write(125); // left flap full up
delay(500);
leftflapServo.write(170); // left flap full down
delay(500);
rightflapServo.write(55); // right flap full up
delay(500);
rightflapServo.write(10); // right flap full down
}else{
Serial.println(tag); //read out any unknown tag
}
}
void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
Serial.println(pin);
digitalWrite(pin, HIGH);
delay(250);
digitalWrite(pin, LOW);
}
void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
digitalWrite(RFIDResetPin, LOW);
digitalWrite(RFIDResetPin, HIGH);
delay(150);
}
void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
for(int i = 0; i < strlen(one); i++){
one[i] = 0;
}
}
boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////
if(strlen(one) == 0) return false; //empty
for(int i = 0; i < 12; i++){
if(one[i] != two[i]) return false;
}
return true; //no mismatches
}
Here's the code for the WaveShield, courtesy of Adafruit-
#include
#include
#include
#include "WaveUtil.h"
#include "WaveHC.h"
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define DEBOUNCE 100 // button debouncer
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
void setup() {
// set up serial port
Serial.begin(9600);
putstring_nl("WaveHC with 6 buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
// pin13 LED
pinMode(13, OUTPUT);
// enable pull-up resistors on switch pins (analog inputs)
digitalWrite(14, HIGH);
digitalWrite(15, HIGH);
digitalWrite(16, HIGH);
digitalWrite(17, HIGH);
digitalWrite(18, HIGH);
digitalWrite(19, HIGH);
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
}
void loop() {
//putstring("."); // uncomment this to see if the loop isnt running
switch (check_switches()) {
case 1:
playcomplete("SOUND1.WAV");
break;
case 2:
playcomplete("SOUND2.WAV");
break;
case 3:
playcomplete("SOUND3.WAV");
break;
case 4:
playcomplete("SOUND4.WAV");
break;
case 5:
playcomplete("SOUND5.WAV");
break;
case 6:
playcomplete("SOUND6.WAV");
}
}
byte check_switches()
{
static byte previous[6];
static long time[6];
byte reading;
byte pressed;
byte index;
pressed = 0;
for (byte index = 0; index < 6; ++index) {
reading = digitalRead(14 + index);
if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
{
// switch pressed
time[index] = millis();
pressed = index + 1;
break;
}
previous[index] = reading;
}
// return switch number (1 - 6)
return (pressed);
}
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
// call our helper to find and play this name
playfile(name);
while (wave.isplaying) {
// do nothing while its playing
}
// now its done playing
}
void playfile(char *name) {
// see if the wave object is currently doing something
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file "); Serial.print(name); return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV"); return;
}
// ok time to play! start playback
wave.play();
}
Attachments
Step 12: Electronics- Right Side Schematics and Code
Here's the schematic and code for the right side.
It's pretty similar to the left side, minus the XBee radio. The servos for the forearm missile all receive the same signal- one of the servos that opens the side cover will need to be reversed rotation. Two of the servos that open the forward and rearward shoulder rocket panel covers will also need to have their rotation reversed as they receive the same signal as the servos in the opposite shoulder.
Here's the code-
#include "Servo.h" // include the servo library
Servo forearmServo; // servos to move forearm missile
Servo rearcoverServo; // servo to move rear shoulder rocket pod cover
Servo forwardcoverServo; // servo to move forward shoulder rocket pod cover
Servo podServo; // servo to move shoulder rocket pod
int RFIDResetPin = 13;
int servoPin1 = 7; // control pin for forearm missile servos
int servoPin2 = 8; // control pin for rear shoulder rocket pod cover servo
int servoPin3 = 9; // control pin for forward rocket pod cover servo
int servoPin4 = 10; // control pin for shoulder rocket pod servo
//Register your RFID tags here
char tag1[13] = "440085E77452";
char tag2[13] = "440085FC330E";
char tag3[13] = "440085F97840";
char tag4[13] = "4400863914EF";
void setup(){
Serial.begin(9600);
forearmServo.attach(servoPin1); // attaches the servo on pin 7 to the servo object
rearcoverServo.attach(servoPin2); // attaches the servo on pin 8 to the servo object
forwardcoverServo.attach(servoPin3); // attaches the servo on pin 9 to the servo object
podServo.attach(servoPin4); // attaches the servo on pin 10 to the servo object
forearmServo.write(45); // rotate the forearm servos to 45 degrees
rearcoverServo.write(45); // rotate the rear cover servo to 45 degrees
forwardcoverServo.write(45); // rotate the forward cover servo to 45 degrees
podServo.write(45); // rotate the left flap servo to 45 degrees
pinMode(RFIDResetPin, OUTPUT);
digitalWrite(RFIDResetPin, HIGH);
}
void loop(){
char tagString[13];
int index = 0;
boolean reading = false;
while(Serial.available()){
int readByte = Serial.read(); //read next available byte
if(readByte == 2) reading = true; //begining of tag
if(readByte == 3) reading = false; //end of tag
if(reading && readByte != 2 && readByte != 10 && readByte != 13){
//store the tag
tagString[index] = readByte;
index ++;
}
}
checkTag(tagString); //Check if it is a match
clearTag(tagString); //Clear the char of all value
resetReader(); //reset the RFID reader
}
void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////
if(strlen(tag) == 0) return; //empty, no need to contunue
if(compareTag(tag, tag3)){ // if matched tag3, do this
forearmServo.write(135);
delay(2500);
forearmServo.write(45);
}else if(compareTag(tag, tag4)){ //if matched tag4, do this
rearcoverServo.write(70); // rotate the pod servo to 90 degrees
delay(500); // wait half a second
forwardcoverServo.write(100); // rotate the forward cover servo to 110 degrees
delay(500);
podServo.write(80); // rotate the pod servo to 80 degrees
delay(4000);
podServo.write(45); // rotate the pod servo to 45 degrees
delay(500);
forwardcoverServo.write(45); // rotate the forward coverservo to 90 degrees
delay(500);
rearcoverServo.write(45); // rotate the pod servo to 135 degrees
}else{
Serial.println(tag); //read out any unknown tag
}
}
void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
Serial.println(pin);
digitalWrite(pin, HIGH);
delay(250);
digitalWrite(pin, LOW);
}
void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
digitalWrite(RFIDResetPin, LOW);
digitalWrite(RFIDResetPin, HIGH);
delay(150);
}
void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
for(int i = 0; i < strlen(one); i++){
one[i] = 0;
}
}
boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////
if(strlen(one) == 0) return false; //empty
for(int i = 0; i < 12; i++){
if(one[i] != two[i]) return false;
}
return true; //no mismatches
}
Step 13: Electronics- Wireless Helmet Schematic and Code
Here's the schematic and code for the wireless helmet.
Since there's very little room in the helmet the wireless system was powered by a single 7.4V NiMH battery pack. The digital servos used in the helmet are designed to be operated on 7.4V so a 5V DC/DC converter is used to provide power for the Arduino, XBee and LEDs.
Here's the code-
#include "Servo.h" // include the servo library
Servo faceplateServo;
Servo chinServo;
int ledPin1 = 4; // control pin for LED eyes
int servoPin1 = 2; // control pin for face plate servo
int servoPin2 = 3; // control pin for chin
void setup() {
faceplateServo.attach(servoPin1); // attaches the servo on pin 2 to the servo object
chinServo.attach(servoPin2); // attaches the servo on pin 3 to the servo object
faceplateServo.write(30); // rotate face plate servo to 30 degrees
chinServo.write(95); // rotate chin servo to 95 degrees
pinMode(ledPin1, OUTPUT); // sets the LED pin as output
digitalWrite(ledPin1, HIGH); // turn on LED eyes
Serial.begin(9600);
}
void loop() {
// look for a capital A over the serial port and turn off LED
if (Serial.available() > 0) {
if (Serial.read() == 'A') { // reads tag over XBee
digitalWrite(ledPin1, LOW); // turn off LED eyes
delay(500); // wait half a second
faceplateServo.write(95); // rotate the face plate servo to 95 degrees
chinServo.write(20); // rotate the chin servo to 20 degrees
delay(4000); // wait 4 seconds
chinServo.write(95); // rotate the chin servo to 95 degrees
faceplateServo.write(30); // rotate the face plate servo to 30 degrees
digitalWrite(ledPin1, HIGH); // turn on LED eyes
}
}
}
Step 14: Electronics- Schematic and Code for the Boots
This is a pretty simple circuit. The Sharp IR sensor inputs a value into the Arduino which triggers the Luxeon boot lights and the Wave Shield to play an audio file. You will need to change the boot sound audio file to "SOUND2.WAV" in order for the Wave Shield to play it properly.
Here's the code-
// these constants won't change:
int triggerSensor = 1; // the sensor is connected to analog pin 1
int threshold = 750; // threshold value to decide when the sensor input triggers
int ledPin = 3; // control pin for LED
int soundPin = 2; // control pin for sound board
// these variables will change:
int sensorReading = 0; // variable to store the value read from the sensor pin
void setup() {
Serial.begin(9600); // use the serial port
pinMode(ledPin, OUTPUT); // sets the LED pin as an output
pinMode(soundPin, OUTPUT); // sets the sound pin as output
digitalWrite(ledPin, LOW); // turn off LED
digitalWrite(soundPin, LOW); // turn the sound off
}
void loop() {
// read the sensor and store it in the variable sensorReading:
int val = analogRead(triggerSensor);
// if the sensor reading is greater than the threshold:
if (val >= threshold) {
Serial.println(val);
digitalWrite(soundPin, HIGH); // turn the sound on
delay(10); // wait ten milliseconds
digitalWrite(soundPin, LOW); // turn the sound off
digitalWrite(ledPin, HIGH); // turn the LED on
delay(2400); // wait two seconds
digitalWrite(ledPin, LOW); // turn the LED off
}
}
Attachments
Step 15: Chest and Repulsor Lights
What Iron Man suit would be complete without lights?
For the chest light I created a simple PCB in EAGLE and soldered on the surface mount resistors and LEDs. The finished PCB was wired up and mounted behind the translucent chest piece. A similar lighting system could be made using standard LEDs and resistors with perfboard. With the hands we lucked out and didn't need to build the lighting system from scratch as Greg already had a repulsor light and sound system that was donated by a friend.
You could easily add repulsor lights to this system and trigger them with additional RFID tags by modifying the code. For an idea have a look here.
Step 16: Switch Operated Helmet
So what do you do if you don't want a wireless helmet?
Another friend of mine wanted to animate his MkIV helmet (in a very specific sequence) and he just wanted a simple push button to activate it. One push to open it and one push to close. The electronics are just like the wireless helmet except this time the XBee radio is replaced with a momentary switch. He also wanted a blinking red LED in the helmet so that's in the code too. The eyes appear to be really bright in the video because the helmet hasn't been painted and the back of the eyes aren't blacked out.
Here's the code needed-
const int servoPin1 = 2; // face plate servo connected to digital pin 1
const int servoPin2 = 3; // chin servo connected to digital pin 2
const int buttonPin = 6; // activation button connected to digital pin 6
const int ledPin1 = 4; // LED eyes connected to digital pin 4
const int ledPin2 = 5; // red LED connected to digital pin 5
#include <Servo.h>
Servo faceplateServo;
Servo chinServo;
void setup() {
faceplateServo.write(30); // initial position for face plate servo
chinServo.write(65); // initial position for chin servo
faceplateServo.attach(servoPin1);
chinServo.attach(servoPin2);
pinMode(buttonPin, INPUT); // LOW when pushed
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin1, HIGH); // turn LED eyes on
digitalWrite(ledPin2, LOW); // turn red LED off
}
void loop() {
static unsigned long lastPushedTime = 0;
static boolean faceplateClosed = true;
static boolean lastButtonState = HIGH;
boolean newButtonState = digitalRead(buttonPin);
// If the button is down and it has been a while since it was last down...
if (newButtonState == LOW && lastButtonState == HIGH && millis() - lastPushedTime > 100) {
lastPushedTime = millis();
if (faceplateClosed) {
faceplateServo.write(120); // Open faceplate
faceplateClosed = false;
delay(300); // wait a bit
digitalWrite(ledPin2, HIGH); // turn on red LED
delay(200);
digitalWrite(ledPin2, LOW); // turn off red LED
chinServo.write(20); // rotate the chin servo to 20 degrees
delay(100);
digitalWrite(ledPin1, LOW); // turn off LED eyes
delay(100);
digitalWrite(ledPin2, HIGH);
delay(200);
digitalWrite(ledPin2, LOW);
delay(200);
digitalWrite(ledPin2, HIGH);
delay(200);
digitalWrite(ledPin2, LOW);
delay(200);
digitalWrite(ledPin2, HIGH);
delay(200);
digitalWrite(ledPin2, LOW);
delay(200);
digitalWrite(ledPin2, HIGH);
delay(200);
digitalWrite(ledPin2, LOW);
delay(200);
digitalWrite(ledPin2, HIGH);
delay(200);
digitalWrite(ledPin2, LOW);
}
else { // faceplate is open
chinServo.write(65); // rotate chin servo to 65 degrees
delay(500); // wait half a second
faceplateServo.write(30); // rotate face plate servo to 30 degrees
delay(500);
digitalWrite(ledPin1, HIGH); // turn on LED eyes
delay(100);
digitalWrite(ledPin1, LOW); // turn off LED eyes
delay(100);
digitalWrite(ledPin1, HIGH);
delay(100);
digitalWrite(ledPin1, LOW);
delay(100);
digitalWrite(ledPin1, HIGH);
faceplateServo.write(30); // close flaceplate
faceplateClosed = true;
}
}
lastButtonState = newButtonState;
}
What if you want to use the RFID tag reader as a switch?
You can do that too. Instead of using a push button you could also activate the helmet by wiring a RFID tag reader directly to the helmet. This code will open the helmet for a specific number of seconds and then close it. There's also a second RFID tag read in the code if you want to add another function, such as a guantlet opening or a repulsor lighting up.
The code would look something like this-
#include "Servo.h" // include the servo library
Servo faceplateServo;
Servo chinServo;
int ledPin1 = 4; // control pin for LED eyes
int servoPin1 = 2; // control pin for face plate servo
int servoPin2 = 3; // control pin for chin
int RFIDResetPin = 13;
//Register your RFID tags here
char tag1[13] = "440085E77452"; // this needs to match your tag ID
char tag2[13] = "440085FC330E";
void setup(){
faceplateServo.attach(servoPin1); // attaches the servo on pin 2 to the servo object
chinServo.attach(servoPin2); // attaches the servo on pin 3 to the servo object
faceplateServo.write(30); // rotate face plate servo to 30 degrees
chinServo.write(95); // rotate chin servo to 95 degrees
pinMode(ledPin1, OUTPUT); // sets the LED pin as output
digitalWrite(ledPin1, HIGH); // turn on LED eyes
Serial.begin(9600);
pinMode(RFIDResetPin, OUTPUT);
digitalWrite(RFIDResetPin, HIGH);
}
void loop(){
char tagString[13];
int index = 0;
boolean reading = false;
while(Serial.available()){
int readByte = Serial.read(); //read next available byte
if(readByte == 2) reading = true; //begining of tag
if(readByte == 3) reading = false; //end of tag
if(reading && readByte != 2 && readByte != 10 && readByte != 13){
//store the tag
tagString[index] = readByte;
index ++;
}
}
checkTag(tagString); //Check if it is a match
clearTag(tagString); //Clear the char of all value
resetReader(); //reset the RFID reader
}
void checkTag(char tag[]){
///////////////////////////////////
//Check the read tag against known tags
///////////////////////////////////
if(strlen(tag) == 0) return; //empty, no need to contunue
if(compareTag(tag, tag1)){ // if matched tag1, do this
digitalWrite(ledPin1, LOW); // turn off LED eyes
delay(500); // wait half a second
faceplateServo.write(95); // rotate the face plate servo to 95 degrees
chinServo.write(20); // rotate the chin servo to 20 degrees
delay(4000); // wait 4 seconds
chinServo.write(95); // rotate the chin servo to 95 degrees
faceplateServo.write(30); // rotate the face plate servo to 30 degrees
digitalWrite(ledPin1, HIGH); // turn on LED eyes
}else if(compareTag(tag, tag2)){ //if matched tag2, do this
// write some code here for something to happen when tag2 is read
}else{
Serial.println(tag); //read out any unknown tag
}
}
void lightLED(int pin){
///////////////////////////////////
//Turn on LED on pin "pin" for 250ms
///////////////////////////////////
Serial.println(pin);
digitalWrite(pin, HIGH);
delay(250);
digitalWrite(pin, LOW);
}
void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
digitalWrite(RFIDResetPin, LOW);
digitalWrite(RFIDResetPin, HIGH);
delay(150);
}
void clearTag(char one[]){
///////////////////////////////////
//clear the char array by filling with null - ASCII 0
//Will think same tag has been read otherwise
///////////////////////////////////
for(int i = 0; i < strlen(one); i++){
one[i] = 0;
}
}
boolean compareTag(char one[], char two[]){
///////////////////////////////////
//compare two value to see if same,
//strcmp not working 100% so we do this
///////////////////////////////////
if(strlen(one) == 0) return false; //empty
for(int i = 0; i < 12; i++){
if(one[i] != two[i]) return false;
}
return true; //no mismatches
}
Step 17: Frequently Asked Questions
Q: I want to buy Iron Man armor. Do you sell Iron Man armor?
A: Sorry I do not produce nor do I sell Iron Man armor or helmets. My friend Greg acquired the molded fiberglass suit and helmet castings from Clinton Hoines of Tundra Designs and they were modified to accept the animatronics. The boots and gloves came from Replica Prop Forum member Zabana. Your best bet is to check out the Junkyard on The Replica Prop Forum as occasionally suits come up for sale there. For a really nice helmet kit check out Actiprops.
Q: Can I send my Iron Man costume to you to have animatronics installed?
A: Sorry, but I cannot take on any more Iron Man projects at this point in time.
Q: What is the difference between analog and digital servos?
A: Compared to analog servos, digital servos have a different type of control circuitry that allows for higher resolution (more accurate positioning), increased holding power and the ability to adjust control parameters such as direction of rotation, speed and deadband width. The downside is that digital servos can be noisier (often heard as a high pitch hum) and they consume more power than analog servos.
Q: Why did you use RFID sensors in the gloves?
A: I chose RFID because I basically needed a non contact switch to trigger the suit functions. The way that Iron Man gloves are constructed makes it very difficult to use a traditional push button switch. Plus with RFID you can add more tags to the glove fingers later on for more functions without adding additional control wires- something that you would have to do with a traditional switch.
The beauty of using RFID tags is that the technology applies to lots of other costumes as well. If you had a dinosaur costume you could use the tags to trigger a roar or you could even make an interactive costume for a party where guests have tags or tags are placed around the room and your costume does different things when it senses the tags. The same thinking applies for IR distance sensors- as you get closer to another person your costume could sense the distance and perform different functions at different distances.
Q: Why not use RC LiPo battery packs to power everything?
A: Originally we had planned to do just that but the reality is that the shortcomings of multi cell LiPos designed for radio control outweighed the benefits. The number one problem with most all multi cell RC LiPo packs is they have no built in safety circuits or regulation- you need to have a low voltage cutoff circuit in place so the battery voltage doesn't drop below a safe level (usually between 2.8- 3.0 V per cell.) If the individual cell voltage drops below this cutoff the cells can be damaged.
Another problem is the amount of current these multi cell packs can deliver- you need to put a fuse between the battery pack and your servos/control circuitry. I had a situation where a digital servo stalled and it pulled so much current the PCB in the servo melted its wiring and the LiPo pack puffed. I also had a low voltage cutoff connected to this and it destroyed that as well. This is not a situation you want to have when you have a helmet on your head that has LiPo batteries in it. You don't want to let the magic smoke out of your costume after you just spent several months building it.
The third issue is LiPo packs require a special charger and you need to be fastidious about how these packs are charged. Since this costume is to be worn primarily at conventions that's a less than ideal situation. Shipping anything with LiPos is also a pain due to shipping restrictions. In the end it just made more sense to use NiMH cells in the helmet and regular AA batteries and 9V batteries everywhere else.
Overall this build was an enormous learning experience.
It was a difficult build, somewhat frustrating at times and a real challenge to figure out ways to get the desired effects while making it as practical as possible and as convincing as possible while still fitting all that hardware inside a suit that someone has to wear. My house and garage looked like a hurricane had gone through it and deposited Iron Man parts everywhere. Many things didn't work as originally planned ( I think I revamped the helmet twice ) and I managed to fry a servo but in the end we stuck to it and it all worked out! As soon as Greg has the final fitting done the suit will get a complete repaint and we'll get a new video of him wearing it.
As always, if anyone has any questions just let me know- I'm always happy to help. :)
You can also visit the DIY Animatronics forum for help with your own projects.
Now I need to make a Whiplash costume so my friend and I can battle!