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.

Angled shot of a Adafruit Feather nRF52840 Express.
The Adafruit Feather nRF52840 Express is the new Feather family member with Bluetooth Low Energy and native USB support featuring the nRF52840!  It's...
$24.95
In Stock
Circuit Playground with crystals on 10 LEDs, glowing rainbow
Bedazzle your board with these No-Foil Flat Back SS16 Rainbow Crystals. They're a lot like the crystals you see decorating clothes, bags and phones. But unlike...
$2.95
In Stock
Angled shot of a Lithium Ion Polymer Battery 3.7V 500mAh with JST-PH connector.
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This...
$7.95
In Stock
4 wire Silicone Cover Stranded-Core Ribbon Cable
For those who are fans of our silicone-covered wires, but are always looking to up their wiring game. We now have Silicone Cover Ribbon cables! These may look...
Out of Stock
Third Hand Magnifier with two alligator grabbers and Magnifying Glass
The classic 'third hand tool,' as seen on every desk! We have one next to our Panavise jr, they complement each other well. This...
Out of Stock
Stickvise PCB Vise on table
Are you still looking for that perfect PCB holder? The low profile PCB Stickvise might be just the thing you need!In performing the simple task...
Out of Stock
Red and black diagonal flush cutters
These are the best diagonal cutters, large super-comfortable grip to use and have strong nippers for perfect trimming of wires and leads. I've used my pair every day for years.
$7.25
In Stock
Red and black multi-size wire stripplers, closed
These are the finest wire strippers we have used, and if you have to do a lot of wiring, you will agree! They have soft rounded grips - very comfortable to use, and precision ground...
$14.95
In Stock
Angled shot of STEMMA JST PH 3-Pin to Male Header Cable - 200mm.
This cable will let you turn a JST PH 3-pin cable port into 3 individual wires with high-quality 0.1" male header plugs on the end. We're carrying these to match up with our...
Out of Stock
Angled shot of JST PH 3-Pin Socket to Color Coded Cable - 200mm
This cable will let you turn a JST PH 3-pin cable socket into 3 individual tinned wires. These are great to match up with our JST 3-PH cables, for extending and connecting...
$0.95
In Stock
Video of an Adafruit NeoPixel Digital RGB LED Strip with all the LEDs illuminating various colors.
So thin. So mini. So teeeeeeny-tiny. It's the 'skinny' version of our classic NeoPixel strips!These NeoPixel strips have 60 digitally-addressable pixel Mini LEDs per...
$99.80
In Stock
Adafruit NeoPixel Digital RGB LED Strip with all the LEDs in a rainbow
So thin. So mini. So teeeeeeny-tiny. It's the 'skinny' version of our classic NeoPixel strips!These NeoPixel strips have 144 digitally-addressable pixel Mini LEDs...
Out of Stock

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 3V on nRF52840 Feather
  • +5V PWR from NeoPixel to Ground on nRF52840 Feather

Be sure you use the end that says Din and not Dout.

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.

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.

Remove Sheathing

We won’t be using the silicone sheathing so we can remove it.

Extra Bling

To make the pixels extra shiny, use the Adafruit rainbow crystals on each pixel.

Circuit Playground with crystals on 10 LEDs, glowing rainbow
Bedazzle your board with these No-Foil Flat Back SS16 Rainbow Crystals. They're a lot like the crystals you see decorating clothes, bags and phones. But unlike...
$2.95
In Stock

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.

Bedazzled Pixels

These give the LEDs a shimmery effect that looks great even when they’re turned off.

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.

Wire Stripping

Using wire strippers, remove a bit of insulation from the tips of each wire.

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).

Wired NeoPixel Strip

Double check the solder joints are solid.

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.

Wired BLE Feather

Now the feather just needs a way to turn the circuit on and off.

Connect JST to BLE Feather

Plug in the male JST connector into the female JST connector on the Feather. Make sure the registration keys are lined up, it should snap fit!

Slide Switch Wires

We'll need to make two wired connections to connect the switch to the Feather.

Solder Slide Switch

Wire up a small 2-wire cable to the middle pin and either one of the pins on either side. 

Wired Slide Switch

Double check the solder joints to ensure they're solid.

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.

Connect Battery

The battery plugs into the port on the side of the feather.

Test Circuit

With the code and libraries uploaded, we can plug in the NeoPixel strip and test out the circuit.

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.

Make A Hole

Create a small incision in the seam of the hat using a sharp hobby knife.

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.

This guide was first published on Aug 13, 2019. It was last updated on Aug 13, 2019.