Overview
Custom NeoPixel Apparel
In this project, we’re making a light up hat with bluetooth controlled NeoPixels. We took this on our recent trip to Disney World and just floored the cast members and park goers.
This is a really fun project for folks just getting started with electronics. This guide will show you how to add a NeoPixel strip to a hat and wire up the electronics.
Bluetooth Controlled NeoPixels
The Adafruit Bluefruit nRF52840 has everything you need to add BLE to your projects. You can remotely control NeoPixels using the Bluefruit LE app for iOS or Android.
BLE Remote Control
In this project, we’ll use the color picker and the control pad to trigger different animations. You can also use an Apple Watch to remotely control the NeoPixels from your wrist. This can be really handy for those times you might not be able to pull out a mobile device.
Prerequisite Guides
Walk through these guides to get familiar with Circuit Python, Bluefruit and NeoPixels.
Parts
- Snapback Adjustable Hat – Black/Gray
- Adafruit nRF52840 Feather
- 500mAh Battery
- Mini Skinny NeoPixel Strip 60 per meter
- Flush diagonal cutters
- Wire Strippers
- Helping Third Hands
- PCB Stickvise
- 3-pin JST cable - Female
- 3-pin JST cable - Male
- 4 Wires Silicone Cover Stranded-Core Ribbon Cable
- Rainbow Crystals for NeoPixels
Page last edited March 08, 2024
Text editor powered by tinymce.
Circuit Diagram
Circuit Diagram
This provides a visual reference for wiring of the components. They aren't true to scale, just meant to be used as reference. This diagrams was created using the Fritzing software package.
Wired Connections
The NeoPixel strip is wired to the nRF52840 Feather using 3-pin JST connectors. A slide switch is wired to the enable and ground.
Powering
The Adafruit nRF52840 Feather can be powered via USB or JST using a 3.7v LiPo battery. In this project, a 500mAh LiPo battery is used. The battery is rechargeable via the USB port on the Adafruit Feather. The slide switch is wired to the enable and ground pins on the Adafruit nRF52840 Feather – This switches the 3V regulator on and off. The battery can still recharge while the 3V regulator is switched off.
NeoPixel Strip Wiring
- DATA IN from NeoPixel to Pin #6 on nRF52840 Feather
- GND from NeoPixel to GND on nRF52840 Feather
- +5V PWR from NeoPixel to 3V on nRF52840 Feather
Be sure you use the end that says Din and not Dout.
Page last edited March 08, 2024
Text editor powered by tinymce.
Software
Install CircuitPython
The Adafruit nRF52840 Feather ships with CircuitPython but it's best to go ahead and update it to the latest version. This project needs version 5.0.0-beta.0 or higher. It's super easy with the circuitpython.org website, just click the link below to launch the page. There you can choose to install stable release or beta.
Quick Start
- Connect board to computer via a known good USB data cable and double press the reset button.
- Download the CircuitPython UF2 and upload to the FTHR840BOOT drive.
- Open CIRCUITPY drive and upload the required libraries (listed below) and code.py
The Adafruit CircuitPython Libraries
Download the CircuitPython library bundle and unzip the folder. Create a new folder in the CIRCUITPY drive and name it "lib". The following libraries are required to run the code properly. Double check to ensure all of the files and folders are inside the lib folder on the CIRCUITPY drive.
- adafruit_ble
- adafruit_bluefruit_connect
- adafruit_fancyled
- neopixel.mpy
Mu Python Editor
Check out Mu, it's a simple Python editor that works with Adafruit CircuitPython hardware. It's written in Python and works on Windows, MacOS, Linux and Raspberry Pi. The serial console is built right in so you get immediate feedback from your board's serial output!
Upload code.py
Click the link below to download the project zip – this contains the code. Upload the code.py file to the CIRCUITPY drive. That's it! You're ready to start controlling your lights with the Bluefruit LE connect app. The rainbow animation is programmed to automatically play after boot.
# SPDX-FileCopyrightText: 2019 Phillip Burgess for Adafruit Industries
# SPDX-FileCopyrightText: 2019 Dan Halbert for Adafruit Industries
# SPDX-FileCopyrightText: 2019 Erin St Blaine for Adafruit Industries
#
# SPDX-License-Identifier: MIT
""" FancyLED Palette and Color Picker Control with BlueFruit App
Code by Phil Burgess, Dan Halbert & Erin St Blaine for Adafruit Industries
"""
import board
import neopixel
import adafruit_fancyled.adafruit_fancyled as fancy
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.button_packet import ButtonPacket
from adafruit_bluefruit_connect.color_packet import ColorPacket
NUM_LEDS = 60 # change to reflect your LED strip
NEOPIXEL_PIN = board.D13 # change to reflect your wiring
# Palettes can have any number of elements in various formats
# check https://learn.adafruit.com/fancyled-library-for-circuitpython/colors
# for more info
# Declare a 6-element RGB rainbow palette
PALETTE_RAINBOW = [fancy.CRGB(1.0, 0.0, 0.0), # Red
fancy.CRGB(0.5, 0.5, 0.0), # Yellow
fancy.CRGB(0.0, 1.0, 0.0), # Green
fancy.CRGB(0.0, 0.5, 0.5), # Cyan
fancy.CRGB(0.0, 0.0, 1.0), # Blue
fancy.CRGB(0.5, 0.0, 0.5)] # Magenta
# Declare a Purple Gradient palette
PALETTE_GRADIENT = [fancy.CRGB(160, 0, 141), # Purples
fancy.CRGB(77, 0, 160),
fancy.CRGB(124, 0, 255),
fancy.CRGB(0, 68, 214)]
# Declare a FIRE palette
PALETTE_FIRE = [fancy.CRGB(0, 0, 0), # Black
fancy.CHSV(1.0), # Red
fancy.CRGB(1.0, 1.0, 0.0), # Yellow
0xFFFFFF] # White
# Declare a Water Colors palette
PALETTE_WATER = [fancy.CRGB(0, 214, 214), # blues and cyans
fancy.CRGB(0, 92, 160),
fancy.CRGB(0, 123, 255),
fancy.CRGB(0, 68, 214)]
# Declare a NeoPixel object on NEOPIXEL_PIN with NUM_LEDS pixels,
# no auto-write.
# Set brightness to max because we'll be using FancyLED's brightness control.
pixels = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_LEDS, brightness=1.0,
auto_write=False)
offset = 0 # Positional offset into color palette to get it to 'spin'
offset_increment = 1
OFFSET_MAX = 1000000
ble = BLERadio()
uart_service = UARTService()
advertisement = ProvideServicesAdvertisement(uart_service)
def set_palette(palette):
for i in range(NUM_LEDS):
# Load each pixel's color from the palette using an offset, run it
# through the gamma function, pack RGB value and assign to pixel.
color = fancy.palette_lookup(palette, (offset + i) / NUM_LEDS)
color = fancy.gamma_adjust(color, brightness=0.25)
pixels[i] = color.pack()
pixels.show()
# set initial palette to run on startup
palette_choice = PALETTE_RAINBOW
# True if cycling a palette
cycling = True
while True:
# Advertise when not connected.
ble.start_advertising(advertisement)
while not ble.connected:
if cycling:
set_palette(palette_choice)
offset = (offset + offset_increment) % OFFSET_MAX
# Now we're connected
while ble.connected:
if uart_service.in_waiting:
packet = Packet.from_stream(uart_service)
if isinstance(packet, ColorPacket):
cycling = False
# Set all the pixels to one color and stay there.
pixels.fill(packet.color)
pixels.show()
elif isinstance(packet, ButtonPacket):
cycling = True
if packet.pressed:
if packet.button == ButtonPacket.BUTTON_1:
palette_choice = PALETTE_RAINBOW
elif packet.button == ButtonPacket.BUTTON_2:
palette_choice = PALETTE_GRADIENT
elif packet.button == ButtonPacket.BUTTON_3:
palette_choice = PALETTE_FIRE
elif packet.button == ButtonPacket.BUTTON_4:
palette_choice = PALETTE_WATER
# change the speed of the animation by incrementing offset
elif packet.button == ButtonPacket.UP:
offset_increment += 1
elif packet.button == ButtonPacket.DOWN:
offset_increment -= 1
if cycling:
offset = (offset + offset_increment) % OFFSET_MAX
set_palette(palette_choice)
BLE Connect App
Use the Bluefruit LE app to control the NeoPixels. The color picker sends solid colors. The control pad features buttons for up to four different animations. Get started by installing the Bluefruit LE connect app for iOS or Android.
- Open the app and find the CIRCUITPY from the list of discoverable devices.
- Tap on the connect button to load the Modules page.
- Locate and tap on Controller from the list of modules.
- Tap on either Control Pad or Color Picker from the list of modules
Changing the NeoPixel Count
Once you've got the code in your editor, look near the top and find this line:
pixel = neopixel.NeoPixel(board.D6, 28)
If you soldered to a pin other than pin 6, change D6 to reflect the correct pin. The last number (28) tells the board how many NeoPixels we have. If you have more or less than 28, change this number to reflect your actual setup.
Customizing Palettes
The code features four different color palettes for the animations accessed from the Control Pad: a rainbow, a purple gradient, a "fire" and a "water" palette. You can customize these fairly easily in the code. The power of the FancyLED library allows you so much control when it comes to choosing custom colors and animating them smoothly.
Find the palette definitions in the code:
# Declare a 6-element RGB rainbow palette
PALETTE_RAINBOW = [fancy.CRGB(1.0, 0.0, 0.0), # Red
fancy.CRGB(0.5, 0.5, 0.0), # Yellow
fancy.CRGB(0.0, 1.0, 0.0), # Green
fancy.CRGB(0.0, 0.5, 0.5), # Cyan
fancy.CRGB(0.0, 0.0, 1.0), # Blue
fancy.CRGB(0.5, 0.0, 0.5)] # Magenta
# Declare a Purple Gradient palette
PALETTE_GRADIENT = [fancy.CRGB(160, 0, 141), # Purples
fancy.CRGB(77, 0, 160),
fancy.CRGB(124, 0, 255),
fancy.CRGB(0, 68, 214)]
# Declare a FIRE palette
PALETTE_FIRE = [fancy.CRGB(0, 0, 0), # Black
fancy.CHSV(1.0), # Red
fancy.CRGB(1.0, 1.0, 0.0), # Yellow
0xFFFFFF] # White
# Declare a Water Colors palette
PALETTE_WATER = [fancy.CRGB(0, 214, 214), # blues and cyans
fancy.CRGB(0, 92, 160),
fancy.CRGB(0, 123, 255),
fancy.CRGB(0, 68, 214)]
You can use CRGB values or CHSV values to choose colors, or use them both at the same time. There are also multiple ways to declare values and a lot of control over how spread out the gradients can be.
This is explained in detail in the FancyLED guide so take a look to find out all you need to know about creating your own custom color palettes.
Page last edited March 08, 2024
Text editor powered by tinymce.
NeoPixel Strip Setup
Choosing a NeoPixel Strip
In this project we’ll be using a Mini Skinny NeoPixel strip with 60 pixels per meter. The hat used here was purchased from Lids.com – Snapback Adjustable Hat - Black/Gray
Measure Strip
Start by laying out our NeoPixel strip to figure out how many pixels we can fit on our hat. In my hat, I used a total of 49 NeoPixels which covers most of the front.
Pixel Data Flow
Flip the strip over to see labels for the ground, voltage and data pads. The arrow indicates the flow of data. Follow the arrow and locate the first pixel in the strip. We'll need to cut the strip to short it down to fit on the front of the hat.
Starting Pixel
Place the strip over one of the seams and skip the first pixel. It will become easier if the first pixel if cut this off rather than remove the existing cable.
Last Pixel
Wrap the NeoPixel strip across the front of the hat and mark the pixel that just about reaches the second seam – This will be the last pixel where we'll cut the strip.
Sacrificial Pixel
Carefully cut off the first pixel using flush diagonal cutters. Try to leave as much of the copper pad as possible – This extra space will allow for a stronger connection when soldering the 3-pin JST cable.
Pixel Count
Thoroughly count each LED element on the strip to determine the exist number of pixels in the strip. Count twice, cut once!
Cutting Strip
We can use wire cutters to cut across the pads on the strip. Be sure to count your pixels twice before cutting it down to size. Try to cut evenly across the three solder pads so you leave enough area for attaching wires.
No Foil Backing Crystals
These crystals have no foil backing so they’re great for adorning NeoPixels. This makes the LEDs look more like rhinestones and less like, well LEDS.
Install Crystals
Just a drop of super glue is all you need to bond the crystals, we just need to be precise with the placement.
Precise Placement
With the small size of these crystals, I found placing them rather tricky. For a finer control, perhaps try using a set of jewelers tweezers.
Page last edited March 08, 2024
Text editor powered by tinymce.
Wire NeoPixel Strip
JST Quick Connects
Use these 3-pin JST cables to connect the strip to the Feather. These cables makes it easy to connect and disconnect.
Cut Cables Short
You can cut the cables short using flush diagonal cutters. I made mine rather short, around an 1 inch (24mm) long.
Wiring
Lay out the components to map out the circuit. We'll connect the male JST connector to the NeoPixel strip and the female connector to the Feather.
Tinning Wires
You can tin the wires by adding a bit of solder to the exposed wires. This prevents the strands of wires from fraying and makes it easier to solder.
Solder NeoPixel Strip
Now we can attach the wires to the pads on the NeoPixel strip by soldering them in place. Third helping hands can help you keep those wires in place while soldering.
Be sure the white wire (data) goes to the Din pin on the strip. The NeoPixels will not light of white is connected to the Dout pin (on the opposite side of the strip).
Page last edited March 08, 2024
Text editor powered by tinymce.
Feather Wiring
Wiring BLE Feather
Next we’ll wire up the Adafruit Feather. I used a stick vise to secure the PCB while soldering wires.
Solder JST Cable
We’ll solder the JST cable female to ground, voltage and any of the available data pins. In this project, the code is set to Pin #6. If you decide to change this, you will need to reflect that in the code.
Page last edited March 08, 2024
Text editor powered by tinymce.
Switch Wiring
Solder Slide Switch
Wire up a small 2-wire cable to the middle pin and either one of the pins on either side.
Wire Switch to BLE Feather
We’ll wire up a the slide switch to the ground and enable pins on the back of the board.
Hot Glue Switch
You can use a bit of hot glue to secure the switch to the PCB. We can also use hot glue to insulate the exposed pins.
Power Switch
This allows us to turn off the 3-volt regulator and still recharge a LiPo battery over USB.
Page last edited March 08, 2024
Text editor powered by tinymce.
Hat Assembly
Hat Installation
The Adafruit Feather and LiPo battery fits nicely inside the lining of the hat. Just unfold the flap and drop in the feather and battery. You can secure the electronics but I kept them loose so I can quickly remove them if needed.
Slit
To make the wiring more discreet, fit the JST connector through the slit. You can use a seam ripper to create a clean opening. Cutting the fabric can leave frayed edges so you’ll need to be careful.
Thread JST Cable
With the incision now large enough, you can insert the connector and pull the wiring through.
Adjust Strip
Take a moment to adjust the placement of the strip and ensure it's in a position that looks straight.
Affix NeoPixel Strip
I used hot glue to affix the NeoPixel strip to the front of the hat. My glue gun has a fine tipped nozzle which I found to be really helpful.
Secure NeoPixel Strip
Press the strip onto the hat to make sure the hot glue has a good hold of the fabric.
Manage Hot Glue Application
You’ll want to be careful not to use too much glue or it may leave a stain on the outside. Otherwise, I found this to work pretty well.
Install the NeoPixel Strip
And there you have it! That’s how you can add NeoPixels to your hat. You can use the switch to power the circuit on and off.
Adding Bling
You can add crystals to each NeoPixel for additional diffusion.
The crystals appear really nice as is and looks even better with the LEDs on.
Page last edited March 08, 2024
Text editor powered by tinymce.