Need to turn your Elvis jumpsuit up to 11? Adafruit to the rescue.
In this quick project, we added 40 programmable lights to an off-the-shelf Elvis costume. NeoPixels and CircuitPython made this easy. Wiring it up took a few hours.
Parts used:
- Circuit Playground Express
- Two packs of Flora RGB Smart NeoPixel v2
- Circuit Playground Express Enclosure
- 3x AAA battery holder with power switch
- Wires and solder
- Glue gun and lots of glue sticks
- Velcro to attach to costume
How'd it go?
Success! This was for a gymnastics competition awards banquet in Memphis, and it survived the all-night party.
- The wiring harness was a little too bulky, that could be thinned out a lot.
- It only took a little bashed-together python code to make the whole thing appropriately ridiculous:
Step 1: Planning
- Bought the Elvis costume cape at a local party shop ($30). It's nice; red underside and printed top.
- Used a seamripper to split the layers apart JUST at the neck, allowing access to the inside.
- Photographed cape and then added 20 colored dots where lights should go.
- ...then said "nope" and added (and ordered) 20 more.
The wiring plan was 7 separate strands with no more than 7 lights per strand, for two reasons:
- When something broke loose during the party we'd only lose a few lights.
- No thin wire would need to carry power for 40 LEDs
Decided not to use conductive thread, because these chains are a bit long, so resistance might be too high.
Instead, I ended up using a mismash of spare wires I happened to have, and it ended up a little too thick.
Step 2: Place the lights and wire it up!
This took a very long time, and I made just a couple of wiring errors but caught those early.
- Tape the lights in place on the outside of the cape
- Poke holes (seamripper again) to get the wires through
- Thread wires from one light to the next, soldering each one in to keep it secure
- After everything's in place and tested, GOOP IT ALL UP with the glue gun, wires and eveything (glue sticks aren't conductive)
- Once in a while, connect the wires to CircuitPlayground and run some test code (see full code below)
####################################################### # SparkleCape prototype by EJ March 2023 # for Adafruit Circuit Playground Express # Connections: # A1 -> "red" light strand in wiring diagram # A2 -> "yellow" light strand in wiring diagram # A3 -> "blue" light strand in wiring diagram # A4 -> "green" light strand in wiring diagram # # Warning: This code was written quickly by a monkey, and was not well tested. # It should only be used to look ridiculous while dancing or receiving awards. import board import time import digitalio import neopixel import random print('Howdy') # Just so I know when Mu connected # This is the main class; it checks for button presses and updates the lights class SparkleCape(): def __init__(self): self.cpg_pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2, auto_write=False) self.cape_pixels_r = neopixel.NeoPixel(board.A1, 10, brightness=0.5, auto_write=False) self.cape_pixels_y = neopixel.NeoPixel(board.A2, 10, brightness=0.5, auto_write=False) self.cape_pixels_b = neopixel.NeoPixel(board.A3, 10, brightness=0.5, auto_write=False) self.cape_pixels_e = neopixel.NeoPixel(board.A4, 10, brightness=0.5, auto_write=False) self.cape_chains = [self.cape_pixels_r, self.cape_pixels_y, self.cape_pixels_b, self.cape_pixels_e] self.num_links = 7 self.cape_sparks = [[255]*self.num_links]*len(self.cape_chains) self.base_color = [[255, 0, 0], [255, 255, 0], [0, 0, 255], [0, 255, 0]] self.spark = 255 self.current_spark = 0 self.spark_drain = 50 self.sparkle_mode = 0 self.num_sparkle_modes = 5 self.pressed_last_time = False self.brightness = 255 self.buttons = ButtonsModule() self.rainbow_phase = 1 self.brite = 0.0 self.current_rb = (0,0,0) # This gets called pretty often to change the light colors def periodic_update(self): # press buttons to change sparkle mode pressed = (self.buttons.left() or self.buttons.right()) if pressed and not self.pressed_last_time: self.sparkle_mode = (self.sparkle_mode + 1) % self.num_sparkle_modes self.pressed_last_time = pressed # eye and tail lights self.cape_chains[3][0] = (0, 0, self.brightness) self.cape_chains[3][1] = (self.brightness, 0, 0) # Original white-sparks (this one's my favorite) if self.sparkle_mode == 0: # drift to base color for ci in range(3): for ch in range(self.num_links): self.cape_chains[ci][ch] = ((self.cape_chains[ci][ch][0]) >> 1, (self.cape_chains[ci][ch][1]) >> 1, (self.cape_chains[ci][ch][2]) >> 1) # bright sparkles num_new_sparks = 3 for i in range(num_new_sparks): r = random.randint(0, 65535) ci = r % 3 ch = (r >> 8) % self.num_links self.cape_chains[ci][ch] = (255, 255, 255) # Rainbow cycle is pretty cool elif self.sparkle_mode in (1, 2): num_colors = 50 if self.sparkle_mode == 2: num_colors = 20 current_color = self.rainbow_phase self.rainbow_phase += 1 self.rainbow_phase %= num_colors self.cape_chains[3][0] = (0, 0, 0) self.cape_chains[3][1] = (0, 0, 0) for ch in range(self.num_links): t = int(current_color + 1 * ch) % num_colors rainbow_color = rainbow(t, num_colors) rainbow_color = (rainbow_color[0] >> 1, rainbow_color[1] >> 1, rainbow_color[2] >> 1) for ci in range(3): self.cape_chains[ci][ch] = rainbow_color # Rainbow flash (good for dance floor) elif self.sparkle_mode == 3: num_colors = 50 self.brite += 0.05 if self.brite > 1.0: self.brite = 0.0 t = random.randint(0, num_colors - 1) self.current_rb = rainbow(t, num_colors) self.cape_chains[3][0] = (0, 0, 0) self.cape_chains[3][1] = (0, 0, 0) rainbow_color = self.current_rb rainbow_color = (int(rainbow_color[0] * self.brite), int(rainbow_color[1] * self.brite), int(rainbow_color[2] * self.brite)) for ch in range(self.num_links): for ci in range(3): self.cape_chains[ci][ch] = rainbow_color # Original runway test pattern (I used this to verify my wiring was correct) elif self.sparkle_mode == 4: self.spark -= self.spark_drain if self.spark < 0: self.current_spark = (self.current_spark + 1) % self.num_links self.spark = 255 for ci in range(3): self.cape_chains[ci][self.current_spark] = (max(self.base_color[ci][0], self.spark), max(self.base_color[ci][1], self.spark), max(self.base_color[ci][2], self.spark)) class ButtonsModule: def __init__(self): self.left_button = digitalio.DigitalInOut(board.D4) self.right_button = digitalio.DigitalInOut(board.D5) self.slide_switch = digitalio.DigitalInOut(board.D7) self.left_button.switch_to_input(pull=digitalio.Pull.DOWN) self.right_button.switch_to_input(pull=digitalio.Pull.DOWN) self.slide_switch.switch_to_input(pull=digitalio.Pull.UP) def left(self): if self.left_button is None: return False return self.left_button.value def right(self): if self.right_button is None: return False return self.right_button.value def switch(self): if self.slide_switch is None: return False return self.slide_switch.value # Thanks to https://www.arnevogel.com/rgb-rainbow/ # Given a complete rainbow of n colors, this returns the ith color def rainbow(i,n): r = 0 g = 0 b = 0 stepsize = int((255*6)/n) progress = i*stepsize sw = int(progress/255) if sw == 0: b = 255 r = progress%255 elif sw ==1: r = 255 b = progress%255 elif sw ==2: r = 255 g = progress%255 elif sw ==3: g = 255 r = progress%255 elif sw ==4: g = 255 b = progress%255 elif sw ==5: b = 255 g = progress%255 return r, g, b def run_all(): cape = SparkleCape() while True: cape.periodic_update() time.sleep(0.05) run_all()