Cosplay Props with NeoPixels

In this project, you'll learn how to add triggered lighting effects to your cosplay props. The electronics used in this prop are great for cosplay weapons or really anything that needs to flash when you press a button.

Triggered Lighting Effects

Inside the barrel is a single NeoPixel. Mounted behind the trigger is a little push button, so when the trigger is squeezed, it actuates the button and lights up the NeoPixel. The  Adafruit Trinket and 500mAh lipo battery are fitted inside the magazine and the entire prop is 3D printed.

DIY Electronics

The electronics used in this project are easy to use and can be mounted in all sorts of builds. In its most basic form, the circuit consists of an Adafruit Trinket micro-controller, push button and single NeoPixel. The power can be supplied by either a USB battery pack or rechargable lipoly battery via JST breakout. When the button is pressed, the NeoPixel flashes for 1/3 of a second. The animation fades through a color gradient and creates a "light blast" effect. It’s easy to change the colors in the gradient and you can scale the animation by increasing the number of pixels.

Prerequisite Guides

We suggest walking through the following guides to get a better understanding of the components and Arduino IDE. We also have great tutorials on learning how to solder.

Parts

All of the components used in this project are listed below and in the right hand sidebar. 

Tools & Supplies

You'll need some tools and supplies to complete this project, but feel free to improvise and use any materials you like.

Wired Connections

The circuit diagram above shows how the components will be wired together. This won't be 100% exact in the actual circuit but it's a very close approximation.

  • Data In from NeoPixel to Pin #0 on Trinket
  • Pwr from NeoPixel to BAT on Trinket
  • GND from NeoPixel to GND on Trinket
  • Pin #2 on Trinket to Button
  • GND on Trinket to Button
  • SW Pin on JST Switched Breakout to Positive Pad on Trinket
  • GND Pin on JST Switched Breakout to Negative Pad on Trinket
  • JST from Battery to JST on Switched Breakout

Battery Power

The circuit will be powered by a 3.7V 500mAh Lithium ion battery via JST connection. The battery plugs directly into the Switched JST-PH 2-pin breakout board.

Getting Code Onto Trinket

In this portion of the guide, we'll get code uploaded to the Adafruit Trinket micro-controller. If you don't write / understand code, don't to worry! You don't need to be a programmer to be able to upload prewritten code :-) 

We'll walk you through the whole process. 

First, visit the Trinket tutorial page by clicking the button below. Follow the instructions to download & setup the Arduino IDE and install drivers.

Make sure you are able to get sketches compiled and uploaded, especially the blink example in the tutorial. Once you are comfortable with using the Trinket, you can continue!

Install Adafruit NeoPixel Library

Next, we need to add support for NeoPixels.

Visit the Adafruit NeoPixel tutorial to install the NeoPixel library!

Uploading Code to Board

Now that we have the Adafruit boards & NeoPixel library installed, we can get our code ready to upload onto the board. Select all of the code listed below in the black box and copy it to your clip board. Then, in Arduino IDE, paste it in the sketch window (making sure to overwrite anything currently there). Next, goto the Tools menu > Board and select Adafruit Trinket (if you're using the 3V Adafruit Trinket version use Trinket 8Mhz. If you're using the 5V Trinket, select Trinket 12Mhz). Now you can click on the "check mark" icon to verify the code. If it's all good, we can continue to upload the code to the board.

Connect USB Data Cable to Trinket

Be sure to use a micro USB cable that can transfer data - A USB cable that ONLY charges devices will simply not work. Plug it into the microUSB port on the Adafruit Trinket board and the USB port on your computer (try to avoid connecting to a USB hub). As soon as you plug it in, you'll see a red LED blink on the Adaruit Trinket - This let's you know the board is ready to except code. While the LED is blinking, click on the Upload button (It's a right arrow icon, next to the chekc mark). The Arduino IDE will notify you if the upload is successful and completed.

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIXEL_PIN    0  // Pin connected to neo pixels
#define FIREPIN      2  // Fire button
#define PIXEL_COUNT  1  // Count of neo pixels

int buttonState = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  
  strip.begin();
  strip.show();

  pinMode(FIREPIN, INPUT_PULLUP);

}

// Linear interpolation of y value given min/max x, min/max y, and x position.
float lerp(float x, float x0, float x1, float y0, float y1)
{
  // Clamp x within x0 and x1 bounds.
  x = x > x1 ? x1 : x;
  x = x < x0 ? x0 : x;
  // Calculate linear interpolation of y value.
  return y0 + (y1-y0)*((x-x0)/(x1-x0));
}

// Get the color of a pixel within a smooth gradient of two colors.
uint32_t color_gradient(uint8_t start_r, // Starting R,G,B color
                        uint8_t start_g,
                        uint8_t start_b, 
                        uint8_t end_r,   // Ending R,G,B color
                        uint8_t end_g,
                        uint8_t end_b,
                        float pos)       // Position along gradient, should be a value 0 to 1.0
{
  // Interpolate R,G,B values and return them as a color.  
  uint8_t red   = (uint8_t) lerp(pos, 0.0, 1.0, start_r, end_r);
  uint8_t green = (uint8_t) lerp(pos, 0.0, 1.0, start_g, end_g);
  uint8_t blue  = (uint8_t) lerp(pos, 0.0, 1.0, start_b, end_b);
  return Adafruit_NeoPixel::Color(red, green, blue);
}

// Set all pixels to the specified color.
void fill_pixels(Adafruit_NeoPixel& pixels, uint32_t color)
{
  for (int i=0; i < pixels.numPixels(); ++i) {
    pixels.setPixelColor(i, color);
  }
  strip.show();
}

void animate_gradient_fill(Adafruit_NeoPixel& pixels, // NeoPixel strip/loop/etc.
                           uint8_t start_r,           // Starting R,G,B color
                           uint8_t start_g,
                           uint8_t start_b, 
                           uint8_t end_r,             // Ending R,G,B color
                           uint8_t end_g,
                           uint8_t end_b,
                           int duration_ms)           // Total duration of animation, in milliseconds
{
  unsigned long start = millis();
  // Display start color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(start_r, start_g, start_b));
  // Main animation loop.
  unsigned long delta = millis() - start;
  while (delta < duration_ms) {
    // Calculate how far along we are in the duration as a position 0...1.0
    float pos = (float)delta / (float)duration_ms;
    // Get the gradient color and fill all the pixels with it.
    uint32_t color = color_gradient(start_r, start_g, start_b, end_r, end_g, end_b, pos);
    fill_pixels(pixels, color);
    // Update delta and repeat.
    delta = millis() - start;
  }
  // Display end color.
  fill_pixels(pixels, Adafruit_NeoPixel::Color(end_r, end_g, end_b));
}

void loop() { 
  uint8_t  i;
  //Button switch
  buttonState = digitalRead(FIREPIN);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is LOW:
  if (buttonState == LOW) {     
  // Run It:
  // Nice flash and fade out over about 3/4 of a second:
    animate_gradient_fill(strip, 255, 255, 255, 0, 0, 255,150);
  // Then flash from purple to nothing over a longer period.
    animate_gradient_fill(strip, 0, 100, 50, 0, 0, 50, 150);
    animate_gradient_fill(strip, 0, 0, 20, 0, 0, 0, 150);
  } 
  
  else {
     strip.setPixelColor(i, 0,0,0); //Button not pressed, turn off pixels
     strip.show(); //Show no pixels
  }
}

3D Printed Parts

There's a total of 20 parts. The most of the parts (with the exception of the magazine) are oriented to 3D print "as-is" and does not require any support material.

Slice Settings

Most of these settings will need to charge depending on your 3D printers configuration, and choice of material. Below are the settings we used on a Sigma BCN3D printer using PLA filament.

  • 220C extruder – 65C heated bed
  • 20% Infill – 0.2mm layer height
  • 60mm/s travel – 150mm/s default speed
  • 0.4mm nozzle – 100% extrusion multiplier

Large Build Volume

Some of the parts may be to large to fit on the bed of a smaller 3D printer. The tallest part requires at least 155mm of Z-height. The X and Y requires a minimum of 135mm by 128mm of print volume.

Download & Remix

If you're interested in making changes to the design, the source is public so you can download it the original in many different formats such as IGS, STEP, SAT, Google SketchUp, etc.

Power Trinket with Lipo Battery

We'll start the electronics by connecting the JST Switched Breakout to the Adafruit Trinket. We need two pieces of wire to connect the power and ground. The wires can be short. Use wire strippers to remove a small amount of insultation from the tips of each wire. Then, tin them by applyng a small amount of solder.

Connect Wires to Power Trinket

On the bottom of the Adafruit Trinket are power and ground pads. We can use these to connect the two wires. Apply a small amount of solder to both pads. Then, connect the wires to the pads.

Connect Trinket to JST Switched Breakout

Now we can connect the power wire from the Trinket to the SW pin on the JST breakout. Then, connect the ground wire from the Trinket, to the ground pin on the JST breakout.

Test Powering Trinket

Plug in the JST connector from the battery to the JST breakout and flip the switch to ON. The green LED from the Adafruit Trinket will light on, indicating that it's reaching power.

Measure NeoPixel Wires

This prop will require some specific wire lengths for the NeoPixel. I did a "dry fit" to see how long the wires will need to be. It's a good idea to use more than enough wire since we can always shorten them later. We'll need three wires for the NeoPixel.

NeoPixel Wires

Once we have our three wires cut, we can use wire strippers to remove some insulation. Then, we can tin the tips by applying small amounts of solder. I recommend using a set of helping third hands to assist you while soldering.

Connect Wires to NeoPixel

Now we can connect the wires to the NeoPixel. On the bottom of the Mini NeoPixel PCB are three pads labeled, 5V, DIN and GND. I suggest tinning the pads. Then, solder the three wires to these pads.

Use Heat Shrink Tubing

Pieces of heat shrink tubing will keep the wires together. Cut pieces of tubing and slide them over the wires – apply heat to tighting the tubing. 

Connect Wires to Push Button

I suggest using wire strippers to remove insulation and then tinning the tips of each wire. Now we can connect the wires to the legs on the push button. 

Heat Shrink Tubing on Button Wires

Again, adding heat shrink tubing to the wires – This time for the button!

Connect Ground Wires to Ground on Trinket

Since the Adafruit Trinket only has one GND pin, I tied the ground wires from the NeoPixel and push button together. Then, inserted them into the GND pin on the Adafruit Trinket. Now I can solder the two ground wires in place.

Connect Button to Trinket

The second wire from the push button will connect to pin number 2 on the Adafruit Trinket.

Connet NeoPixel Power to Trinket

The power wire from the NeoPixel will connect to the BAT pin on the Adafruit Trinket.

Connect NeoPixel Data to Trinket

The Data In wire from the NeoPixel will connect to pin number 0 on the Adafruit Trinket.

Final Circuit Test

With all of our components wired up, we can test the final circuit! The arduino code should already be uploaded to the Adafruit Trinket – If you haven't yet, please do so now!

Glue Blade Base Halves

I used E6000 adhesives to glue most of the parts. The main base of the blade is split into two halves which will need to be glued together. Use clamps to keep the parts together while the adhesive cures.

Glue Blade Sections

The middle and tip of the blade will need to be glued to the bottom base of the blade. Again, use clamps to keep these parts together while they dry.

Glue Handle Grips

Glue the handle grips to both halves of the handle. Take note the grips with the holes will go with the halve that has holes.

Insert Pixel to Front Barrel

The NeoPixel can fit through the hole on the bottom of the back barrel and out the other end.

Insert Pixel to Back Barrel

Then, we can thread the NeoPixel through the front barrel and pull it all the way through.

Mount NeoPixel to Barrel

Now we can mount the NeoPixel to the front facing plate of the barrel by pressing it in until it clicks into place.

Glue Barrel Face

Once the NeoPixel is mounted, we can glue the facing barrel to the front of the barrel.

Assemble Parts

Join the back and front barrel parts together. The key from the front barrel goes into the slot on the back barrel.

Install Trigger and Guard

The keys from the trigger fit into the slide on the trigger guard. The trigger guard snaps into the key on the handle.

Install Button to Handle

The pushbutton can rest in the cavity right behind the trigger.

Fit Wires Into Handle

With those pieces in place, we can nestle the wires into the channel grove on the inside of the handle halve.

Assemble Handle Halves

Then, carefully place the second halve of the handle on top and secure the two pieces together with machine screws.

Install Barrel to Handle

The barrel assembly slots into the keys on the handle assembly. Press the two together until they click into place.

Install Components into Magazine

Now we can carefuly fit the components into the magazine. You'll need to power the circuit on before installing. Power the circuit off when not in use.

Install Blade into Handle

The blade assebly attaches to both the trigger guard and the front barrel. The key from the blade slots into the trigger guard. The top of the blade snaps into the lower receiever.

Test Pushbutton and Trigger

Squeeze the trigger to actuate the push button. The slots in the trigger guard and handle allows the trigger to slide.

Complete Build

And that’s it for the build, I think this is a really awesome way to get triggered lighting effects, especially for cosplay props, but this would also work for costumes. The electronics I used in this project are great for cosplay weapons or really anything that needs to flash when you press a button.

Share Your Prop!

If you've made a cosplay prop using electronics front Adafruit, we'd love to see and share it on our blog! Send us an email, tweet at us, or tag us on instagram.

Future developements

Turning the circuit on/off could be much easier with a slide switch mounted somewhere on the outisde of the prop. Currently, the circuit must be taken out of the magazine to turn it on/off and put the wiring at risky of being damaged.

Trigger with Sensors

Want to make this project a gillion times better? This project could definiately use of an accelerometer, vibration switch or capacitive touch. Instead of the pushbutton triggering the NeoPixel animation, the force of acceleration or the jult of viberation could trigger the light. The easiest way to get a more interactive actuation is to use a vibration switch in place of the push button – it's basically a drop in replacement.

This guide was first published on Nov 09, 2016. It was last updated on Nov 09, 2016.