Introduction: How to Make Zelda's Bow
My wife and I are working on creating Zelda and Link costumes for cosplay. In my opinion, the coolest weapon that Zelda uses is the bow that she has in Twilight Princess and Super Smash Bros.
All of the versions of Zelda's bow that I was finding online were either painted or used reflective tape to give the appearance of light. I wanted to take it to the next level and create a bow that actually lights up and has effects. The model is also made to be modular enough to remove the electronics and replace/repair individual parts without too much headache.
This instructable shows how I 3D printed Zelda's bow and added multi-colored lights.
Step 1: Tools and Materials
The following materials are needed to create Zelda's Bow:
- 3D Printer and filament (I used a Rostock Max v2, silver Hatchbox PLA from Amazon, and clear PLA from ebay)
- Arduino Gemma
- 56 Neopixels
- 1 mini boat rocker switch
- 2 6x6mm momentary switches with a 6mm or longer button
- 1/4" x 1/16" Neodymium magnets, you'll need around 76 at least
- 22ga hook up wire
- soldering iron
- removable mounting putty
- Gorilla glue
- super glue
- Wood filler
- Rustoleum filler primer
- Rustoleum gold spray paint
- 3 AAA batteries
- (optional) quick connectors for making sections more easily removable
Step 2: 3D Print
Print the STL files in the attached ZIP file. There are a lot of pieces and they are organized in the folder by quadrant.
The clear pieces do have some duplication, but I printed them individually to make sure I always had the outside section down on the print bed so that it is smooth.
The ZIP file also contains the Arduino code that you will need later.
Attachments
Step 3: Assemble the Bow Sections
Each section of the bow is broken into 4 pieces to make it easier to print on a smaller printer. I did include the whole body section file in case you want to cut them differently.
The body sections are joined mostly with dovetail joints for added strength. I used a combination of super glue and Gorilla glue for joining the pieces. Gorilla glue expands to fill gaps, so it is useful when things don't fit perfectly.
Step 4: Glue the Magnets and Handle
Glue the magnets in pairs to make sure the polarity is correct. I marked the outside of the magnets with a sharpie, then glued the marked sides down with super glue.
Remember to keep the magnets far apart while the glue is drying. If you get them too close together, they will snap together and and potentially stick together forever with super glue.
For the light trays, glue the magnet pairs to the legs first and let it dry, then glue the other side of the magnets to the body. Take care to make sure the trays are clear of the sides and the inner magnet pegs.
The handle is meant to be glued to one half of the bow, allowing the other half to be removed. I glued it to the top left and bottom left sides.
Step 5: Test Fit and Painting
My clear pieces needed some sanding to fit properly, so now is the time to do it. Don't glue them in place yet.
Put in the light trays and make sure that all of the halves snap together nicely. Snap on the handle door and see how everything fits together.
The bow does have some flex at this stage, but once the clear pieces are glued in and everything is in place, it will be more solid. Remove the clear parts and the light trays.
I use wood filler to fill in any gaps before painting. Once that is dry and sanded, use filler primer on the whole bow. I like to sand to 400 grit, then spray a final coat of primer to make sure it is smooth. Finally, spray paint the bow gold (or whatever color you pick).
Once the bow is dry, glue the clear pieces in place.
Step 6: Electronics
There are a lot of electronics crammed inside the bow. It is a tight fit, but it can all make it. I decided to use mounting putty for the lights and Arduino so that they can be adjusted and removed easily.
Note the light patterns in the photos. The button to change the color follows a waterfall from the center of the bow outwards on all 4 sides at once. The Arduino and batteries are in the bottom left section of the bow and have a unique wiring pattern, but the other 3 sides use the pattern seen in the other photo.
Solder the wires to the lights and connect them all together. Add quick disconnects here if you'd like to. I could not fit them on the side with the batteries, but the top half has quick disconnects, along with the buttons in the handle and the light wires between the two halves.
This is the most time-consuming part by far. If I made an upgraded version of the bow, I'd find a better way to mount the lights.
Wire the buttons and the power switch and glue them onto the handle. You can change the pins used in the Arduino code before putting it on the Gemma.
Fitting batteries inside the bow turned out to be a challenge. I ended up making a custom battery holder and wiring it together with sections of 22ga wire. I used a strip of electrical tape to hold them in place. The tray is attached via a pair of magnets on the bottom. This will make changing batteries easy.
Step 7: Arduino
Load the Arduino code from the ZIP file onto the GEMMA. You'll need the Neopixel library from Adafruit installed so follow the instructions in the link.
You can open up the full Arduino code from the ZIP file in the Arduino IDE, so I won't simply paste the entire code file here. Instead, I'm going to explain everything in sections. Please forgive the formatting from pasting the code here. I promise that it is much nicer in the actual code file.
#include <Adafruit_NeoPixel.h>
#define LED 1
#define BTN1 0
#define BTN2 2
int lastButton1State = LOW;
int lastButton2State = LOW;
This section includes the Neopixel library that provides the control methods for the lights. The LED pin on the Gemma is 1, and the buttons are on 0 and 2. If you are using a different Arduino or wiring scheme, change these here. Finally, we store the last state of each of the buttons so that we don't continuously trigger the button behavior if you hold down the button. We only want that to happen once per click.
int ledCount = 56;
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ledCount, LED, NEO_GRB + NEO_KHZ800);
I used 56 LEDs in my build, so I set that as a variable. The strip object is initialized to 56 LEDs, the defined LED pin, and the values for Gemma and WS2812b type LEDs.
uint32_t colors[5] = {strip.Color(255, 255, 0), // yellow
strip.Color(127, 0, 255), // purple
strip.Color(0, 255, 0), // green
strip.Color(255, 0, 0), // red
strip.Color(0, 0, 255)}; // blue
int currentColor = 0;
int maxColor = 5;
int defaultBrightness = 50;
I decided to use 5 colors in the cycle. Yellow is the standard color, Zelda wears purple, and the rest just looked cool. The currentColor and maxColor values allow us to cycle through the 5 colors. The max brightness is 255, so I set it to 50 to allow a lot of room to grow in the fire mode.
void setup() {
// initialize the pushbutton pin as an input:
pinMode(BTN1, INPUT_PULLUP);
pinMode(BTN2, INPUT_PULLUP);
strip.begin();
for (int i = 0; i < ledCount; i++)
{
strip.setPixelColor(i, colors[currentColor]);
}
// Get brighter
for (int i = 5; i < defaultBrightness; i += 2)
{
strip.setBrightness(i);
strip.show();
delay(50);
}
}
This is the method called when the bow is turned on. It initializes the buttons and the lights, sets the color to yellow, and gradually increases the brightness from 0 to 50.
void loop(){
for (int i = 0; i < 2000; i++)
{
int button1State = digitalRead(BTN1);
if (button1State != lastButton1State)
{
lastButton1State = button1State;
if (button1State == LOW)
changeColor();
}
int button2State = digitalRead(BTN2);
if (button2State != lastButton2State)
{
lastButton2State = button2State;
if (button2State == LOW)
fireArrow();
}
delay(5);
}
pulse();
}
This is where the Arduino will will looping most of the time, waiting for a button press. I wanted the buttons to be responsive, so it checks for button clicks for about 10 seconds (2000 iterations times a 5ms delay) before it shows the idle pulse effect. If a button is pressed, it shows that effect before returning to this method and continuing the loop.
void pulse()
{
// Get slightly dimmer
for (int i = defaultBrightness; i > defaultBrightness / 2; i -= 5)
{
strip.setBrightness(i);
strip.show();
delay(50);
}
// Get brighter
for (int i = defaultBrightness / 2; i < defaultBrightness; i += 5)
{
strip.setBrightness(i);
strip.show();
delay(50);
}
}
This is the idle effect. We want it to be fast so that we don't miss a button click. It steps the brightness down by 5 every 50ms until it gets to half of the idle brightness, then returns to normal.
void changeColor()
{
currentColor++;
if (currentColor == maxColor)
{
currentColor = 0;
}
int i1 = 2;
int i2 = 27;
int i3 = 28;
int i4 = 55;
// Loop through and change color
for (int i = 0; i < 14; i++)
{
// Set colors
strip.setPixelColor(i1, colors[currentColor]);
strip.setPixelColor(i2, colors[currentColor]);
strip.setPixelColor(i3, colors[currentColor]);
strip.setPixelColor(i4, colors[currentColor]);
// Update iterators
if (i == 3)
i1 = 1;
else if (i == 4)
i1 = 6;
else if (i == 5)
i1 = 0;
else if (i == 6)
i1 = 7;
else
i1++;
i2--;
i3++;
i4--;
// Update and wait a bit
strip.show();
delay(50);
}
}
When the color change button is clicked, the LEDs are changed to the next color in the loop. I made the lights start at the middle of the bow and quickly change color in a domino effect going outwards. This piece of code is weird because the lights are in a long string, but we have divided them into 4 sections. The first section is wired differently from the other 3 sections, so the i1 iterator needs special handling to follow the correct order.
void fireArrow()
{
// Get slightly dimmer
for (int i = defaultBrightness; i > 20; i -= 5)
{
strip.setBrightness(i);
strip.show();
delay(20);
}
// Get brighter
for (int i = 20; i < 250; i += 5)
{
strip.setBrightness(i);
strip.show();
delay(30);
}
// Stay bright a bit
delay(800);
// Get dimmer
for (int i = 250; i > defaultBrightness; i -= 10)
{
strip.setBrightness(i);
strip.show();
delay(30);
}
}
Finally, the fire effect sets the bow to full brightness for just shy of a second, then dims back down to idle.
Hopefully all of this makes sense. If you want to modify the colors or effects, it should be fairly easy to adjust them.
Step 8: Assemble
Once all of the electronics and in place and working, simply snap everything in place which is easy since everything is magnetized. Your bow is ready to be used!
Not pictured is the bow string. I plan on using simple elastic string for this for visual effect and so that it doesn't put much pressure on the bow pieces.
I'm happy with how this prop turned out and I think it will look great with my wife's Zelda costume. Tell me if you have any ideas for improvements or if you have any questions on things I missed or didn't explain in enough detail.
Thanks!