3DxPrinting Cosplay Costume

It’s got hints of Star Wars, Fallout, and Guardians of the Galaxy. It’s got lasers, EL wire and of course, NeoPixel LEDs. In this project, we’re mounting glowy electronics to some 3D printed parts to light up your face!

A 3D printed gas mask makes an interesting addition to any halloween costume and may even turn some heads at Comic Con.

This has three main pieces to it: the mask, the respirator and the costume goggles. Details like the grill, the secondary respirators and conduits make this an intricate looking build.

This guide will walk you through the process of 3d printing, wiring and assembling your very own LED Gas Mask.

This guide was written for the 'original' Gemma board, but can be done with either the original or M0 Gemma. We recommend the Gemma M0 as it is easier to use and is more compatible with modern computers!

Challenges and Expectations

The most difficult part in this project is the 3d printing. There are a total of 16 parts and it takes about 14 hours to print all of them. The mask part requires a 3d printing build area of 180mm x 150mm y 150mm z. Wiring the circuit and compontents to fit the parts require a bit of patience, finesse and careful soldering. 

Prerequisite Guides

We recommend walking-through the following guides to help you get a better introduction to the components. Once you have GEMMA configured with your Arduino IDE, continue following this project.


Tools & Supplies

You will need access to the follow tools. We also carry all of these lovely maker tools in the Adafruit shop.

PLA Filament

We recommend using PLA material for this project for best quality and minimal warping. Slice settings are recommened for printing on a Makerbot Replicator 2. Parts do not require support material. The mask part included build-in geometery for support.

Printing Ze Parts

These parts are optimized for printing on FDM desktop machines. The parts can be printed on surfaces such as blue tapers tape, glass, acrylic and flexible plates.  All of the parts have their orientations centered for printing piece by piece. We recommend printing parts individual for best quality. Tolerances should be snap-fit and tight. If things are too tight, you can however use a Dremel tool or sand paper to loosen up the openings. Parts in this project were printed on a Makerbot Replicator 2.


PLA @240c
90/90 speeds
2 Shells
10% Infill
0.2mm layer height

15+ Hours

Customize Design

The original solids are available to download and modify in Autodesk 123D Design. This model can be viewed and edited in the 123D web or desktop app. STL and 123DX file formarts available.

This diagram uses the original Gemma but you can also use the Gemma M0 with the exact same wiring!

Compontent Connections

The illustration above is a visual reference of the components and wiring. GEMMA micro-controller is the main board that runs the NeoPixel rings and laser diode. To power this circuit, a slide switch adapter is connected in between a rechargable 500mAh lithium polymer battery and GEMMA.

The two NeoPixel rings share the same data(D0), power(VOUT) and ground(GND) pins on GEMMA. The laser diode power is connected to 3V and GND on GEMMA.

Follow the circuit diagram and walk-through the assembly instructions to wire and connect the components together. 

The Arduino code presented below works equally well on all versions of GEMMA: v1, v2 and M0. But if you have an M0 board, consider using the CircuitPython code on the next page of this guide!

Install Arduino IDE

If you're new to GEMMA and the Arduino IDE, we have a great introduction tutorial to get you started with the program and configuration. 

You'll need to download our special flavor of the Arduino IDE that includes profiles for Adafruit micro-controllers. Walk through the guide and configure the GEMMA.

Arduino Sketch

Below is the code used in the project that animated the NeoPixel rings. Once you have installed the Adafruit Arduino IDE and configured the GEMMA. Copy the code below and paste it into a new sketch.

// SPDX-FileCopyrightText: 2014 Phil Burgess for Adafruit Industries
// SPDX-License-Identifier: MIT

#include <Adafruit_NeoPixel.h>

#define PIN       0
#define NUM_LEDS 24

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_LEDS, PIN);

uint8_t  mode   = 0,        // Current animation effect
         offset = 0;        // Position of spinner animation
uint32_t color  = 0xFF0000; // Starting color = red
uint32_t prevTime;          // Time of last animation mode switch

void setup() {
  pixels.setBrightness(85); // 1/3 brightness
  prevTime = millis();      // Starting time

void loop() {
  uint8_t  i;
  uint32_t t;

  switch(mode) {

   case 0: // Random sparkles - just one LED on at a time!
    i = random(NUM_LEDS);           // Choose a random pixel
    pixels.setPixelColor(i, color); // Set it to current color
    pixels.show();                  // Refresh LED states
    // Set same pixel to "off" color now but DON'T refresh...
    // it stays on for now...both this and the next random
    // pixel will be refreshed on the next pass.
    pixels.setPixelColor(i, 0);
    delay(10);                      // 10 millisecond delay
   case 1: // Spinny wheel
    // A little trick here: pixels are processed in groups of 8
    // (with 2 of 8 on at a time), NeoPixel rings are 24 pixels
    // (8*3) and 16 pixels (8*2), so we can issue the same data
    // to both rings and it appears correct and contiguous
    // (also, the pixel order is different between the two ring
    // types, so we get the reversed motion on #2 for free).
    for(i=0; i<NUM_LEDS; i++) {    // For each LED...
      uint32_t c = 0;              // Assume pixel will be "off" color
      if(((offset + i) & 7) < 2) { // For each 8 pixels, 2 will be...
        c = color;                 // ...assigned the current color
      pixels.setPixelColor(i, c);  // Set color of pixel 'i'
    pixels.show();                 // Refresh LED states
    delay(50);                     // 50 millisecond delay
    offset++;                      // Shift animation by 1 pixel on next frame
    if(offset >= 8) offset = 0;    // Reset offset every 8 pixels

    // More animation modes could be added here!

  t = millis();                    // Current time in milliseconds
  if((t - prevTime) > 8000) {      // Every 8 seconds...
    mode++;                        // Advance to next animation mode
    if(mode > 1) {                 // End of modes?
      mode = 0;                    // Start over from beginning
      color >>= 8;                 // Next color R->G->B
      if(!color) color = 0xFF0000; // Preiodically reset to red
    pixels.clear();                // Set all pixels to 'off' state
    prevTime = t;                  // Record the time of the last mode change

Installing Arduino libraries is a frequent stumbling block. If this is your first time, or simply needing a refresher, please read the All About Arduino Libraries tutorial.If the NeoPixel library is correctly installed (and the Arduino IDE is restarted), you should be able to navigate through the “File” rollover menus as follows:


From the Tools→Board menu, select the device you are using: 

  • Adafruit Gemma M0
  • Adafruit Gemma 8 MHz 
  • Connect the USB cable between the computer and your device. The original Gemma (8 MHz) need the reset button pressed on the board, then click the upload button (right arrow icon) in the Arduino IDE. You do not need to press the reset on the newer Gemma M0 or Trinket M0.

When the battery is connected, you should get a light show from the LEDs. Refer to the NeoPixel Uberguide for more info.

GEMMA M0 boards can run CircuitPython — a different approach to programming compared to Arduino sketches. In fact, CircuitPython comes factory pre-loaded on GEMMA M0. If you’ve overwritten it with an Arduino sketch, or just want to learn the basics of setting up and using CircuitPython, this is explained in the Adafruit GEMMA M0 guide.

These directions are specific to the “M0” GEMMA board. The original GEMMA with an 8-bit AVR microcontroller doesn’t run CircuitPython…for those boards, use the Arduino sketch on the “Arduino code” page of this guide.

Below is CircuitPython code that works similarly tothe Arduino sketch shown on a prior page. To use this, plug the GEMMA M0 into USB…it should show up on your computer as a small flash drive…then edit the file “code.py” with your text editor of choice. Select and copy the code below and paste it into that file, entirely replacing its contents (don’t mix it in with lingering bits of old code). When you save the file, the code should start running almost immediately (if not, see notes at the bottom of this page).

If GEMMA M0 doesn’t show up as a drive, follow the GEMMA M0 guide link above to prepare the board for CircuitPython.

# SPDX-FileCopyrightText: 2017 Phil Burgess for Adafruit Industries
# SPDX-License-Identifier: MIT
import time

import board
import neopixel

    import urandom as random  # for v1.0 API support
except ImportError:
    import random

numpix = 24  # Number of NeoPixels
pixpin = board.D0  # Pin where NeoPixels are connected
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)

mode = 0  # Current animation effect
offset = 0  # Position of spinner animation
color = [255, 0, 0]  # RGB color - red
prevtime = time.monotonic()  # Time of last animation mode switch

while True:  # Loop forever...

    if mode == 0:  # Random sparkles - lights just one LED at a time
        i = random.randint(0, numpix - 1)  # Choose random pixel
        strip[i] = color  # Set it to current color
        strip.write()  # Refresh LED states
        # Set same pixel to "off" color now but DON'T refresh...
        # it stays on for now...bot this and the next random
        # pixel will be refreshed on the next pass.
        strip[i] = [0, 0, 0]
        time.sleep(0.008)  # 8 millisecond delay
    elif mode == 1:  # Spinny wheels
        # A little trick here: pixels are processed in groups of 8
        # (with 2 of 8 on at a time), NeoPixel rings are 24 pixels
        # (8*3) and 16 pixels (8*2), so we can issue the same data
        # to both rings and it appears correct and contiguous
        # (also, the pixel order is different between the two ring
        # types, so we get the reversed motion on #2 for free).
        for i in range(numpix):  # For each LED...
            if ((offset + i) & 7) < 2:  # 2 pixels out of 8...
                strip[i] = color  # are set to current color
                strip[i] = [0, 0, 0]  # other pixels are off
        strip.write()  # Refresh LED states
        time.sleep(0.04)  # 40 millisecond delay
        offset += 1  # Shift animation by 1 pixel on next frame
        if offset >= 8:
            offset = 0
    # Additional animation modes could be added here!

    t = time.monotonic()  # Current time in seconds
    if (t - prevtime) >= 8:  # Every 8 seconds...
        mode += 1  # Advance to next mode
        if mode > 1:  # End of modes?
            mode = 0  # Start over from beginning
            # Rotate color R->G->B
            color = [color[2], color[0], color[1]]
        strip.fill([0, 0, 0])  # Turn off all pixels
        prevtime = t  # Record time of last mode change

This code requires the neopixel.py library. A factory-fresh board will have this already installed. If you’ve just reloaded the board with CircuitPython, create the “lib” directory and then download neopixel.py from Github.

Grill Details

To give the grill a shinny background, add a piece of aluminum foil. Use the printed part as a template to guide an xacto knife to cut out the shape. A layer of glue stick will secure the foil to the grill. Let the sticky adhesives dry before applying a layer of super glue to the grill and onto the mask.

Attaching Costume Goggles

Place the costume goggles over the top of the mask with the bridge piece in-front of the mask. With one hand, hold both the mask and goggles together then use the other hand to add a binder clip. Use a pair of pliers to remove the handles  from the binder clip.

Secondary Respirators

The secondary respirators are attached to the mask with cylinderical pegs. These pegs are inserted into the holes of the secondary respirator parts. Strips of conduit are fitted into the large opening on the back of each secondary respirator.

Prep Wires

In this project we're using 26AWG silicone coated stranded wires for more flexiblity. Measure and cut six pieces of wire according to the photo. Strip and tin the tips of each wire. With all six wires striped and tinned, combine two pieces together to make a set of 3 wired.

Wire Up NeoPixel Rings

Secure the rings into place with a Panavise Jr or third-helping hand to assist you while soldering. Tin the data, ground and power pins on the NeoPixel ring. Solder the wires to the 16 and 24 NeoPixel Ring.

Mount NeoPixel Rings

Before inserting the rings into the mount, ensure the side with the cylindical walls is facing up. Insert the 16 NeoPixel ring into the part with the wires threaded through the openings. Pull the wires all the way through and press the ring inside the channels snaping it into place.  Do the same with the 24 NeoPixel ring, only through the larger channel and openings. With both the rings snapped into place, and wires pulled all the way through, group the wires together and insert them through the gemma mounting part.

Wire Gemma and Laser Diode

Secure GEMMA to a third-helping hand. Keep the ring mount and circuit close and secured. Ensure wires are through the GEMMA mounting part.

Solder the wires from the NeoPixel rings to GEMMA. Power to VOUT. Data to D0. Ground to Ground

Solder the red positive wire from the laser diode to 3V on GEMMA. Solder the black common ground wire to the GND pin on GEMMA. With the wires soldered, place the GEMMA into the mount part and group the wiring so that it flows through the opening near the JST port on GEMMA. 

Install Circuit into Large Respirator 

Insert the laser diode in through the large respirator part with the diode going through out the smaller opening. The ring mount part is inserted through the large respirator and pushed down until it reaches the end stopper.  Ensure it's all the way in by pressing the edges down.

Install Respirator Connector

With the ring mount and laser diode installed, grab the respirator connector and pull the laser and slide switch adapter through the opening with the pegs facing towards the diode. Apply funtak (mounting putty) to the surface of the connector and press it down to the large respirator. Ensure to pull the slide switch all the way through the connector. 

Assemble Features

Grab a piece of conduit and cut it down to about 5cm. Insert conduit into the circular opening in the side of the mask for both secondary respirator pieces. Grab the strand of EL wire and start threading it through one of the conduits.

Routing EL Wire Part 1

The secondary respirators include holes sized for EL Wire to pass through. Continue threading EL Wire until you reaching the end of the part. Once the EL Wire has been threaded all the way through the conduit and secondary respirator, you'll need to pull the EL wire until you have about a quater of a meter (or just long enough be able to put the inverter in your pocket and wear the mask). You'll need about 1 meter and some slack of EL wire to thread through the two secondary respirators, the large respirator, and the two ring mounts that are placed inside the costume goggles.

Routing EL Wire Part 2

Insert the EL wire through the large respirator and thread it through the various openings. You can mix it up and thread it however you like, just don’t over do it - You’ll still need to thread the other side with the remaining length of EL wire. Once you have a loop or two of EL wire exposed on the large respirator, thread the remaining length through the other secondary respirator. You may want to temperarly remove the conduit to make it easier. Pull the EL Wire all the way through the side of the mask.

Routing EL Wire Part 3

Thread the remining EL Wire through one of the holes in the EL mounting ring. Pull the wire all the way through until you have enough to fit inside one of the eye sockets in the costume goggles. Fit the EL wire into the mounting ring by pressing it down into the channel. Thread EL wire tip through the second hole and pull all the way through. Press down the EL wire again to snap it into the ring mount. Insert the ring mount into one of the eye sockets of the costume googles.

EL Wire Rings

Repeat the same steps for the second EL Wire ring mount. You'll need to leave a bit of slack to allow the two ring mounts enough length to spread apart. When mounting the ring mounts into the costume goggles,  orient the parts so that the EL wire is positioned towards the bottom.

Installing Respirators

Insert the laser diode into the front opening of the mask part. Pull the wire all the way through and start fitting the large respirator towards the opening. Carefully fit the slide switch adapter into the opening. Orient the respirator so that the pegs line up with the openings in the mask. Press the large respirator into the mask until the pegs are visable inside the mask. Now you can insert the secondary respirators into the holes on the side of the mask.

Access to On/Off Power Switch

Ensure you have enough wire in the slide switch adapter so that it is reachable when parts are assembled together. You can optionally extend the wire with a JST extension cable.

Laser Diode Eye Wear

Insert the laser diode through one of the EL wire ring mouts (and costume goggle). Position the laser mount part over the laser diode and press it through the opening. You may need to add a piece of eletrical tape on the diode for a tight fit. Place the laser mount part over the costume goggle socket and secure the eye cover part back onto the costume goggle.

Make it wearable

Add pieces of weather-proof foaming to the mask to make it more confortable when wearing. This roll of foam includes self-adhesive backing similar to foam tape. You can get a roll at your local super market in the DIY section. Add a piece of foam to the inside of the mask, near the nose bridge area. 

Mounting Battery 

Insert a 500mAh lithium polymer battery into the lipo pocket part. Add a peice of double-stick foam tape to the lipo pocket and attach it to the inside of the mask. A good location for the pocket is right above the opening of the respirator.

LED diffuser and cover

Place the LED diffuser part over the large respirator and press it down into place. Press along the edges of the diffuser until it reaches the full depth of respirator. Lay the cover over the respirator part and press it down to snap it closed.

Final Build

There might be excess EL Wire. If you want to hide it, you can coil it up and secure to the surface of the mask or simply let go down your ear and hind it behind your back. Maybe you want to wrap around a hat and show it off, its up to you! The EL inverter can be placed in your pants or jacket pocket. 

Wear It!

Before fitting the mask over your face, make sure there aren't any sharp or pointing parts coming from the conduit (if there's sharp edges, you can trim them off with scissors). Try adjusting the EL wire away from the bridge of your nose. Adjust the goggles and ensure the straps are fastened and tight. 

This guide was first published on Oct 02, 2014. It was last updated on Oct 02, 2014.