"By the Eye of Agamotto!"
The Eye of Agamotto. An awesome amulet, the top talisman, the most excellent eye, bling from beyond... call it what you will, but no Dr. Strange costume would be complete without it. Hang it from your neck, clasp it to your cloak or display it in your trophy room next to your orb; this is one accessory worth making and with this instructable I try to make it as simple as possible!
Step 1: Background
For almost a year (yes, I plan Halloween costumes a year in advance... who doesn't?) I've been planning on doing a Dr. Strange costume. During that same time I wanted to learn how to program and use an Arduino. Born out of both was this project, my first real Arduino IDE coded project, the Eye of Agamotto.
That's right, I chose this as my first project.
Did I bite off more than I could chew? Yes. But I have also been working on this for about 6 months, so I've had plenty of time to learn.
Was it worth it? Absolutely!
The reaction I got from NYCC '15 attendees was great, especially when it got dark out and the glowing Eye of Agamotto could really shine!
Step 2: Tools and Materials
- 2.2" 18-bit color TFT LCD display with microSD card breakout
- ILI9340Adafruit Pro Trinket - 5V 16MHz
- Hall effect sensor - US5881LUA (x2)
- Adafruit Pro Trinket LiIon/LiPoly Backpack
- Lithium Ion Polymer Battery - 3.7v 1200mAh or a 9V battery and connector
- SD/MicroSD Memory Card
- 2-inch (50mm) Clear Glass Cabochon
- Wires/Ribbon Cable
- 10k Resistor (x2)
- M2x4 (2mm x 4mm) screws (x6)
- Perf Board (optional, for wiring hall effect sensors)
- Gold Chain
- Gold Spray Paint
- Switch (optional but recommended)
- Velcro (optional)
- Soldering Iron
- 3D Printer or a Print Service
- Wire Cutter
- Hot Glue Gun
- Acetone and Chamber
- Masking Tape
- Double-Sided Tape
- Fine Steel Wool
- Cotton Swabs
Software & Image files
Step 3: Concept
There were a few things I wanted this build to do to really make the Eye of Agamotto, and the Dr. Strange costume, stand out as really magical. There have been a few really good Dr. Strange costumes but only one I've seen actually do anything involving animating the Eye.
That said, I wanted to not only add animations to the Eye, but make it reactive to my "spells". The best way I figured to do this was to incorporate hall effect sensors to make it look like I was activating the Eye with only a slight touch of my finger (for more about hall effect sensors and Arduino see this tutorial). This allowed me to activate the Eye to open and look around with one touch, then get to "angry mode" with another touch. The code eventually runs to a set point and turns off the display.
Video and finished shots by the oh so talented Sara.
Step 4: Creating Images
Images were created with publicly available images of an iris and a fire gif. I uploaded both into GIMP and made modifications so that they fit within a 240x320 pixel area (the aspect ratios remained 1:1). When designing and modifying the images (and any future images I may use, see the Improvements section of this 'ible) I essentially treat the viewing area as 320x320 pixels (or really 320 pixels in diameter). The top and bottom portions of the viewing area (i.e. the 40 pixels above and 40 pixels below that would ideally be there if the screen was a square 320x320 pixels) are blocked by the eye lids, but I still animate the space as if they were there to make the eye appear as if it's completely round.
The iris was resized to 160 pixels in diameter and the levels were augmented to accentuate the red channel. The red channel and yellow channel were further accentuated in the "bleye.bmp" file where I inserted the iris into a frame of the fire gif with some yellow highlights to create an "angry eye".
I then "animated" the fire by splitting the fire gif into frames using the GAP extension of GIMP and dividing the images up into four equal sections framing the iris. This gives them approximately the same load time. Their positioning is then handled by the code so that they "fit" back in the image appropriately. This then gives the illusion that the fire is moving in a ring, albeit slower than I would have wanted. It did, however, prove as a simple and elegant work around to animating the entire viewing area, which would have looked too much like a slide show.
Things to keep in mind are:
- Images must be saved in 24 bit color
- No alpha channel is allowed (no transparency in the image)
- When exporting as a BMP in GIMP, choose the "Do not save color space information" option
- Use images that are only 240x320 pixels or less, they are not automatically scaled by the display
- Save the images in portrait mode, not landscape (you may need to rotate them if you have text)
- If only a portion of the image changes, consider only changing that portion as a smaller BMP (images are overlayed on top of the previous image at the coordinates you specify)
- Use only BMPs, any other image type are either not supported or supported only with additional modification to the code or changing the microcontroller
- You cannot tell the microcontroller/display to place a picture off the screen (i.e. outside of the 0,0:240,320 plane)
- Any image file you create cannot have more than 8 characters in the prefix (i.e. "picture.bmp" is allowed but not "picturefile.bmp")
Once you download the images (they are also supplied as a zip file in the github link in the Code section), place them on the root directory of your SD card (i.e. the main folder you open when clicking on the SD card in your computer). Any files you create to be displayed can also be stored here, though you'll have to add them to the code or rename files to match and replace mine. Once you place the files on the SD card, you can eject it from your computer and put it in the SD card slot of the display.
Step 5: Designing the 3D Print
I designed the whole 3D print in 123D Design. This was my first time using the program and my first time designing a 3D print. I was a learning experience, however the program was fairly intuitive.
The 3D print needed to have 3 parts which would fit together to make it all work. With that in mind, all parts were designed so that they could be bonded or screwed together.
The hardest part was keeping all aspects and parameters of the components in mind when designing the 3D printed bezel. The "eye ball socket" needed to fit the cabochon, which in turn needed to line up with the display. The cutout for the display needed to be a certain height so that it fit securely. The space inside needed to allow for wires, and a battery, and the microcontroller... you see how it can get complicated.
After several iterations and about 3 months of intermittent work, I had a final model. I "test fitted" everything virtually by creating 3D versions of the Trinket, backpack, battery, display, and cabochon.
When I was satisfied with the design, I exported each individual piece as an STL file. You can access the full 3D print file here:
Feel free to download, print or edit to your liking. If you do make any changes, let me know, I'd love to see what you make!
Step 6: 3D Printed Parts
The parts were printed on a standard deposition-type printer by folks at my local hobby shop, 3DX Hobbies. They did a great job walking me through the print design and helping me with a few last minute adjustments so that the parts would be robust enough to print and use. If you don't have a 3D printer and are unfamiliar with resources in your area, use something like 3D Hubs, which connects you with printers in your area, or Shapeways.
When printing, feel free to print in whatever color filament you have, we will be painting it later so the filament color isn't an issue. Darker filaments, however, may allow the paint color to "pop" better and hide any residual glow from the components inside.
Step 7: Preparing the 3D Print
After several hours/days of printing the parts were finally ready to be picked up! However, there are still a few more steps left in order to really make the 3D printed Eye bezel look amazing.
First, clean any print supports off with a flat blade knife or scraper. You may also want to sand or file the parts at this point to remove any pieces that are clearly aberrant.
Second, prepare an acetone bath chamber (see this excellent tutorial from Make). I simply used a steel gallon paint can, a few paper towels and four magnets. I placed the dry towels along the inside of the can and secured them there with magnets. Then I saturated the towels with pure acetone and shook out any excess (do this outside away from any flame sources). Using the lid as my base, I bathed the front of the bezel in acetone vapor for 3 hours and the back for 2 hours. Make sure you don't let the acetone touch the actual print. Also, use a metal lid to support the back of the bezel so that it can sit flat. Allow the parts to dry in the open air for about thirty minutes prior to handling.
Once I was done I had shiny smooth prints, but I also noticed that the back of the bezel was sagging towards the center. A quick hit with a heat gun (or a blow dryer on high) was all it took to flatten it out.
The acetone bath did a great job of smoothing out those print lines, however the spray paint adheres best to a surface that isn't smooth or shiny. Using my fine steel wool, I sanded around all features of the front and back of the bezel, including inside the "eye lids". Steel wool allows for you to get into all those crevices around the front of the bezel. I then taped off the inside of the bezel, this is necessary to protect surfaces you will later need unpainted to help with bonding the parts (see Assembling the Eye).
Next, paint the front and back of the bezel with thin, overlapping coats of gold spray paint. You may chose to first prime the surface, but I found this unnecessary. I used at least 8 thin coats of paint, allowing 10 minutes in between to dry, then repositioning the parts. Hanging the front of the bezel inside a box using two sticks (one long one on top of a box and another small one inside the bezel) yields the best results. Just make sure you paint the inside of the "eye lids", but not the inside of the bezel, which you should have taped off.
Step 8: The Code
Perhaps the longest and most arduous part of the whole build. The 3D print may have taken me 3 months to design, but the code has been a work in progress for 6 months. Mostly because I'm a noob, but also because I had to utilize a bunch of "tricks" to get the Trinket to animate the eye.
See, Arduinos aren't really suited for animations, especially animations that are as large as this. Sure a tiny bitmap may work, but it'll most likely eat up a lot of system memory and your sketch essentially becomes a one-trick-pony. So I had to consult a lot of sources to not only get the Trinket to animate, but also fit the sketch on the microcontroller with added space for other functionality. I did though, with a lot of help. Sites/blogs that I consulted and borrowed from are listed below, those I used in the sketch are credited within the code:
Um, yeah, so I was busy.
So what you see here is an evolution of understanding while standing on the shoulders of many people who actually know what they're doing. Hence, my code may be a little unpolished and bulky, but it works. You can access it via my github link:
Upload the code in the .ino file in the above link to your Trinket 5V Pro (any other microcontroller will need to be compensated for in the code). Be sure to read up on how to use the Trinket bootloader first. You won't be able to run the sketch and see the animations until you assemble everything in the next step.
The trick was to handle most of the "animation" with a little feature the ILI9340 controller in the display allows for. When the eye looks back and forth along the x-axis (really the y-axis, since the display is intended to be vertical) the image isn't really being animated, it's actually scrolling, like you would with text. This allows the microcontroller and display to do the arduous and time-consuming loading of the bitmap only once (done with the backlight off so you can't see it), all other animation in this view is accomplished by "scrolling" up and down (or left and right in our case).
Step 9: Wiring
I prototyped everything out on an Arduino Uno R3 with the Trinket Pro in mind, so when it came time to transferring it over everything was already compatible (great feature btw). Using the Trinket meant that everything was able to fit in the slim-line encasement of the bezel I designed, but the downside was a lot of soldering in a really tiny space.
All this with a twenty year old hunk of junk soldering iron... challenging but not impossible.
I tried my best to make the wiring diagram clear while also matching the pictures of the actual project. The wire color for all wires going from the Trinket to the LCD match, however I augmented the colors of the two hall sensors to make it easier to see. I also eschewed making a mock up of the LiPo backpack in fritzing (it took me long enough to make the 2.2" TFT LCD screen), so please understand that the slide switch is meant to represent the backpack and the switch (for more info on how to wire see the product page).
Below I go through some steps on how to wire each component up. It's difficult to show in pictures, so I figured a little narrative wouldn't hurt.
Wiring the LCD:
- Using 3" of a ribbon cable (10 strands) or a number of single, color-coded wires (believe me, you'll want different colors), strip the last ⅛" to ¼", twist, and solder to the LCD following the diagram above. Helping hands are really helpful (no pun intended) here, just use one clamp to hold the screen board and the other to hold the ribbon cable.
- Follow the diagram and the code (see steps below) to wire all wires to their respective pins. You'll want to wire all 8 info pins with the exception of the 5V (Vin) and ground.
- When wiring, you will want the wires protruding from the "front" of the microcontroller and the "back" of the LCD display.
- Wire everything so that when both the LCD display and the microcontroller are sitting front up, there is no twist and minimal crossing of the wires.
Wiring the hall effect sensors (do this with both):
- Wiring the hall effect sensors is a little less straight forward, consult the product page before beginning.
- To start, bend each of the three pins on both hall sensors to form a tight 180° hook.
- Solder a 5" piece of wire to pin 1 and cover with heat shrink tubing.
- Solder a 5" piece of wire to pin 2 and cover with heat shrink tubing.
- Solder a 3" piece of wire to pin 3 and cover with heat shrink tubing.
- To the wire coming from pin 3, solder a 10k resistor and a 3" piece of wire (the "listen" wire) and cover with heat shrink tubing (the newly soldered wire needs to be soldered parallel with the resistor, not in series with it).
- To the free end of the 10k resistor, solder the wire coming from pin 1 and another 3" long wire (the "power" wire).
- Solder the "listen" wire to the respective pin on the microcontroller (A1 or A2, Digital 15 or 16).
Wiring the backpack and power pins:
- If using a 500mA LiPo battery or higher, connect the pads on the back of the backpack labeled "100mA chrg rate default Short jumper for 0.5A".
- Break the connection in between the two pads for the power switch and solder in two 3" long wires (see product overview page for instructions).
- Insert the power switch into the back encasement cutout intended for the switch, test the poles for which to use when flipping the switch, then fold over the one you don't need to hold the switch in place.
- Solder each wire coming from the backpack to separate poles (see picture), it doesn't matter which one goes where.
- You can wire the backpack two ways, stacked or loose. Loose allows you to use the attachment points in the 3D print (see picture) but is more suited if you are going sans-backpack and wiring a battery connection straight to the microcontroller. Stacked is more inline with the intention of the backpack, but involves some adjusting to fit within the 3D printed bezel.
- If Stacked:
- Use the provided male header pins to space the backpack from the microcontroller (the black pin piece goes between the backpack and microcontroller). Solder in place (see product page).
- Solder the LCD GND and both wires from hall effect sensors' pin 2 to the backpack GND.
- Solder the LCD VIN and both "power" wires from the hall effect sensors to the microcontroller 5V.
- If Stacked:
- Using 3" long wires...
- Solder the backpack BAT to the microcontroller BAT.
- Solder the backpack GND along with the LCD GND and both wires from hall effect sensors' pin 2 to the microcontroller GND.
- Solder the backpack 5V to the microcontroller BUS.
- Solder the LCD VIN and both "power" wires from the hall effect sensors to the microcontroller 5V.
Step 10: Assembling the Eye
Now you should have a beautifully painted bezel, all the electronics connected, a glass cabochon, a couple pieces of double-sided tape, some acetone (and cotton swabs), and a small piece (~1") of Velcro.
To assemble the Eye:
- Start by cutting and placing two rectangles of double-sided tape so that they fit within the inside of the lid (the 3D print has been designed to accept only the thickness of the double-sided tape listed in the materials section).
- Polish the cabochon and press it into the "eye socket", hold it in place for 15 seconds to set it well.
- If you haven't done so already, load the SD card (with images) into the card holder on the LCD display.
- Position the LCD screen within the rectangular cutaway inside the bezel with the screen facing down.
- Dry fit the rectangular screen holder into place, it has been designed to fit snugly and in only one conformation to allow for the wires of the LCD to protrude unobscured.
- Take the screen holder out and apply a thin coat of acetone to all edges abutting the bezel surface.
- Quickly put the screen holder in place and hold tight, applying a few more layers of acetone every minute to fuse the pieces.
- Wait 5 minutes for the acetone to evaporate and the pieces to be fully fused.
- Add the Velcro to one side of the battery (see image) then to the back of the screen holder where there are no mounting holes.
- If you are screwing the microcontroller in (the mounting holes are spaced perfectly for the Trinket Pro) screw it in with 3 of the M2 screws (the holes are 2mm in diameter). The image shows the microcontroller being screwed in for demonstration purposes, since the backpack is attached, I ultimately did not screw it in.
- If you are leaving the microcontroller loose (I did), wedge it in between the mounting holes, with the back of the bezel screwed on it will stay without moving.
- Put the sensor attached to pin A1 (D15) in the slot at the very top of the bezel (it's a slim raised rectangle) so that the chamfered side faces the bezel wall. Hot glue it in place.
- Put the sensor attached to pin A2 (D16) in one of the side slots of the bezel (another slim raised rectangle) so that the chamfered side faces the bezel wall. Hot glue it in place.
- Attach the battery to the backpack and test to see if it powers on the microcontroller when switched on.
- Test the microcontroller one last time by placing the South side of a magnet near the hall effect sensor connected to A1 (D15).
- Line the holes in the back of the bezel up with the holes in the three triangular pillars in the bezel encasement and attach with 3 of the M2 screws. Do not over tighten.
- Add your gold chain
- Whenever you need to charge the battery you will need to remove the back of the bezel and charge via a micro USB line.
Step 11: Finished!
Congratulations, you're done! You now have in your possession one of the most powerful magical amulets in existence!
I used the Eye of Agamotto for 12 hours intermittently at its debut at NYCC 2015 and it held a charge wonderfully. What helps is the on/off switch in the back that I turned to off during panels and other downtime.
Step 12: Improvements
Because I'm masochistic, I've already started a list of improvements for version 2. Why? Because what I envisioned for this project was a lot crazier than what I actually attained... that and I already did most of the work!
- Upgrade to a Teensy to acquire faster refresh rates for actual animations (still BMP based) , the capabilities of which are evident by this blog post. The goal is to get about 15 fps, which is not possible (nor intended) for the Trinket. The current build was more a personal challenge to see what I could do with the Trinket... now I know.
- After upgrading (see above), finding some way of including the animations I made in GIMP using the following tutorials:
I made some great loopable GIFs this way (see the attached images) that can easily be framed out and saved as individual BMPs and animated using standard codes on Teensy.
- I built the original bezel to accommodate 4 hall effect sensors, so adding two more could mean extra functionality in the code.
- Adding animatronics! My original design, build and code involved movable eye lids and from what I could tell, it would have worked! Only issue is that the parts were too small to print so I had to scrap it two weeks before I debuted it and I cut that portion out of the code. It wasn't a total loss though, I was able to slim up the bezel to make it a lot less clunky.