3D Printing & Electronics

Build your own REZZ inspired glasses with NeoPixels and CircuitPython. 3D print the parts and use the Adafruit ItsyBitsy M4 to make hypnotic NeoPixel animations! Learn how to solder components and get started programming with CircuitPython.

DIY REZZ Glasses

REZZ is a Canadian DJ and producer of electronic dance music. Her trademark eye-wear feature LED animations that appear like swirls that spin and change color. Her music can be streamed on soundcloud. She also has videos and images up on her instagram.

NeoPixel Triple-Rings

These rings have 44 through-hole NeoPixel LEDs. The outside has 24, inner ring has 16 and the center has 4. All of the NeoPixel rings are on one board, which makes it easy to wire. The NeoPixel LEDs are diffused so they look soft and easy on the eyes.

Parts

1 x ItsyBitsy M4
Adafruit ItsyBitsy M4
1 x Lipo Backpack
Trinket/ItsyBitsy Lipo Backpack
2 x NeoPixel Triple-Ring
44 NeoPixel Triple-Ring Board
1 x Reversable USB cable
USB A to micro B reversible to get it connected easily the first time
1 x Slide Switch
Slide Switch
1 x 400mAh Battery
400mAh Battery
1 x 4-Wire Ribbon Cable
30AWG SIlicone Cover Stranded-Core Ribbon Cable
1 x M2 x 12mm Screws
Phillips Pan Head. Secures arms to frames.
What's smaller than a Feather but larger than a Trinket? It's an Adafruit ItsyBitsy M4 Express featuring the Microchip ATSAMD51! Small,...
$14.95
In Stock
Whether they're rings, strips, panels, matrices, we love glowing up projects with LEDs. And here's an interesting new board! Is it half of an electronic Oreo cookie? Nay!...
Out of Stock
If you have an ItsyBitsy or Pro Trinket you probably know it's the perfect little size for a portable project. This LiPoly backpack makes it really easy to do! Instead of wiring 2...
$4.95
In Stock
These nice switches are perfect for use with breadboard and perfboard projects. They have 0.1" spacing and snap in nicely into a solderless breadboard. They're easy to switch...
$0.95
In Stock
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...
$6.95
In Stock
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...
$1.95
In Stock
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also fully reversible! That's right, you will save seconds a day by...
$3.95
In Stock

The diagram below provides a visual reference for wiring of the components. This diagram was created using the software package Fritzing.

Adafruit Library for Fritzing

Use Adafruit's Fritzing parts library to create circuit diagrams for your projects. Download the library or just grab individual parts. Get the library and parts from GitHub - Adafruit Fritzing Parts.

Power

The ItsyBitsy M4 is powered by 400mAh battery via the Lipo Backpack. This allows the USB port from the ItsyBitsy M4 to charge the 400mAh battery. A slide switch is connected to the two switch pin on the Lipo Back. 

  • BAT from Lipo Backpack to BAT on ItsyBitsy M4
  • Ground from Lipo Backpack to GND on ItsyBitsy M4
  • 5V from Lipo Backpack to USB on ItsyBitsy M4

Slide Switch

A 2-pin slide switch is wired to the switch pins on the Trinket/ItsyBitsy Lipo Backpack. 

NeoPixel Rings

The two 44x triple-rings are daisy chained with three wired connections, data, voltage and ground. The right ring is connected to the ItsyBitsy M4.

  • V+ from NeoPixel Ring to Vhi on ItsyBitsy M4
  • G from NeoPixel Ring to G on ItsyBitsy M4
  • DIN from NeoPixel Ring to Pin #5 on ItsyBitsy M4

Setup ItsyBitsy M4 with CircuitPython

We'll need to get our board setup so we can run the CircuitPython code. Let's walk through these steps to get the latest version of CircuitPython onto your board. 

The Mu Python Editor

Mu is 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! While you can use any text editor with your code, Mu makes it super simple.

Installing or upgrading CircuitPython

You should ensure you have CircuitPython 4.0 or greater on your board. Plug your board in with a known good data + power cable (not the cheesy USB cable that comes with USB power packs, they are power only). You should see a new flash drive pop up.

If the drive is CIRCUITPY, then open the boot_out.txt file to ensure the version number is 4.0 or greater. 

Adafruit CircuitPython 5.0.0-beta.0 on 2019-11-19; Adafruit ItsyBitsy M4 Express with samd51g19

Download the Adafruit CircuitPython Library Bundle

In order to run the code, we'll need to download a few libraries. Libraries contain code to help interface with hardware a lot easier for us.

Use the ItsyBitsy M4 page on Installing Libraries to get the library that matches the major version of CircuitPython you are using noted above, i.e. 4.x for the versiond starting with 4, 5.x for the versions starting with 5, etc.

To run the code for this project, we need the two libraries in the Required Libraries list below. Unzip the library bundle and search for the libraries. Drag and drop the files into a folder named lib on the CIRCUITPY drive (create the folder if it is not already on the ItsyBitsy M4).

Required Libraries 

  • neopixel.mpy
  • adafruit_fancyled

Once we have all the files we need, a directory listing will look similar to above as far as files and directories.

Upload Code

Click on the download link below to grab the main code directly from GitHub. Rename the file to code.py and drop it onto the CIRCUITPY main (root) directory. The code will run properly when all of the files have been uploaded including libraries.

Use any text editor or favorite IDE to modify the code. We suggest using Mu as noted above.

# pylint: disable=import-error

"""
NeoPixel goggles inspired by Rezz

No interactive controls; speed, color and directions randomize periodically.
"""

from random import random, randrange
from time import monotonic
import board
import neopixel
import adafruit_fancyled.adafruit_fancyled as fancy

# Configurable defaults

BRIGHTNESS = 0.15  # 0.0 (off) to 1.0 (max brightness)

# Global variables

# Declare NeoPixel object. Data from ItsyBitsy pin 5 because it has built-in
# level shifting. Each LED eye has 44 pixels, so 88 total. Leave brightness
# at 1.0 here (NeoPixel library runs faster at full brightness) and adjust
# the global BRIGHTNESS above instead (used later when selecting HSV colors).
PIXELS = neopixel.NeoPixel(
    board.D5, 88, auto_write=False, brightness=1.0, pixel_order=neopixel.RGB)

# MODE indicates the current animation state through several bit fields.
# Bit 0 indicates the second eye is x-axis mirrored (1) or an exact copy
# of the first (0). Bit 1 indicates hue is slowly cycling (2) vs holding
# steady (0). Bit 2 indicates the middle of the 3 LED rings moves the
# opposite (4) or same (0) direction as the other 2.
MODE = randrange(8)  # 0 to 7
# Every few seconds, one of the above attributes is randomly toggled.
# This keeps track of the last time.
TIME_OF_LAST_MODE_SWITCH = 0
# HUE works around the color wheel, see FancyLED docs.
HUE = random()
# Relative position of MIDDLE of 3 rings, 0 to 143
MIDDLE_POS = randrange(144)
# Relative position of INNER and OUTER rings, 0 to 143
POS = randrange(144)
# Amount to increment POS and MIDDLE_POS each frame
SPEED = 2 + random() * 5

# The MIRROR_X and OFFSET(OUTER,MIDDLE,INNER) arrays precompute some values
# for each pixel so we don't need to repeat that math every frame or LED.
MIRROR_X = []
OFFSET_OUTER = []
OFFSET_MIDDLE = []
OFFSET_INNER = []
for i in range(24):
    MIRROR_X.append(67 - ((i + 11) % 24))
    OFFSET_OUTER.append(i * 6)
for i in range(16):
    MIRROR_X.append(83 - ((i + 7) % 16))
    OFFSET_MIDDLE.append(i * 9)
for i in range(4):
    MIRROR_X.append(87 - ((i + 2) % 4))
    OFFSET_INNER.append(i * 36)


def set_pixel(index, color):
    """Set one pixel in both eyes. Pass in pixel index (0 to 43) and
       color (as a packed RGB value). If MODE bit 0 is set, second eye
       will be X-axis mirrored, else an exact duplicate."""
    # Set pixel in first eye
    PIXELS[index] = color
    # Set pixel in second eye (mirrored or direct)
    if MODE & 1:
        PIXELS[MIRROR_X[index]] = color
    else:
        PIXELS[44 + index] = color


# Main loop, repeat indefinitely...
while True:

    # Check if 5 seconds have passed since last mode switch
    NOW = monotonic()
    if (NOW - TIME_OF_LAST_MODE_SWITCH) > 5:
        # Yes. Save the time, change ONE mode bit, randomize speed
        TIME_OF_LAST_MODE_SWITCH = NOW
        MODE ^= 1 << randrange(3)
        SPEED = 2 + random() * 5

    # Generate packed RGB value based on current HUE value
    COLOR = fancy.CHSV(HUE, 1.0, BRIGHTNESS).pack()

    # Draw outer ring; 24 pixels, 8 lit
    for i in range(24):
        j = (POS + OFFSET_OUTER[i]) % 72
        if j < 24:
            set_pixel(i, COLOR)
        else:
            set_pixel(i, 0)
    # Draw middle ring; 16 pixels, 6 lit
    for i in range(16):
        j = (OFFSET_MIDDLE[i] + MIDDLE_POS) % 72
        if j < 27:
            set_pixel(24 + i, COLOR)
        else:
            set_pixel(24 + i, 0)
    # Draw inner ring; 4 pixels, 3 lit
    for i in range(4):
        j = (POS + OFFSET_INNER[i]) % 144
        if j < 108:
            set_pixel(40 + i, COLOR)
        else:
            set_pixel(40 + i, 0)

    # Push new state to LEDs
    PIXELS.show()

    # If MODE bit 1 is set, advance hue (else holds steady)
    if MODE & 2:
        HUE += 0.003

    # Increment position of inner & outer ring
    POS = (POS + SPEED) % 144
    # Middle ring advances one way or other depending on MODE bit 2
    if MODE & 4:
        MIDDLE_POS = (MIDDLE_POS - SPEED) % 144
    else:
        MIDDLE_POS = (MIDDLE_POS + SPEED) % 144

Double Check

See the directory listing above and double check that you have all the files listed to make this project function. If any are missing or in an incorrect directory, move them so they're in the right places.

3D Printed Parts

STL files for 3D printing are oriented to print "as-is" on FDM style machines. Original design source may be downloaded using the links below.

  • rezz-frame.stl
  • rezz-arm-bat.stl
  • rezz-arm-itsy.stl
  • rezz-arm-grip-left.stl
  • rezz-arm-grip-right.stl
  • rezz-itsy-box.stl
  • rezz-bat-box.stl
  • rezz-bat-cover.stl

Exploded View

The CAD animation shows how the parts fit together. The two arms are secured to the frames with two M2 x 12mm long machine screws. The purple arm grips are printed in TPU flexible filament. The enclosures houses the electronics. The enclosures are superglued to the arms. The battery box has a snap-fit cover.

Slicing Parts

No supports are required. Slice with setting for PLA material. The arm grips will need to be printed in TPU flexible material. Adjust slice settings accordingly to materials. 

The parts were sliced using CURA using the slice settings below.

  • PLA filament 220c extruder
  • 0.2 layer height
  • 10% gyroid infill
  • 60mm/s print speed
  • 60c heated bed

Design Source Files

The project assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, SAT and more. Electronic components like Adafruit's board, displays, connectors and more can be downloaded from our Adafruit CAD parts GitHub Repo.

Lipo Battery Arm

The rezz-arm-bat.stl and rezz-bat-box.stl parts are attached together with super glue. Use the mounting holes to line up the parts. Reference the top and bottom photos to get the correct placement.

ItsyBitsy Arm

The rezz-arm-itsy.stl and rezz-itsy-box.stl parts are attached together with super glue. Use the mounting holes to line up the parts. Reference the top and bottom photos to get the correct placement.

Connect Arms to Frame

The two arms are attached to the frame. Press the hinges from the arms into the knuckles on the sides of the frame.

Installing Hinges

Press the hinge and knuckles together so that the 2mm diameter hole is visible through out the hinge. Use a M2 threading tool to tap threads into the plastic.

Installed Arms

Install both arms into the frames. Double check the orientation of the arms and wear them to test fit and verify the parts are installed correctly.

Install Screw

Insert a M2 x 12mm machine screw through the top of the hinges. Fasten the screw until it's installed all the way through the hinge.

Secured Arms

Ensure the screw is installed as straight as possible through the hinge. Using a tapping tool to create threads into the hinges makes this much easier.

Assembled Frame

Test fit the assembled frames. Put them on and try them out. Double check the arms are installed in the correct orientation.

Data in and out

Follow the photo to reference the correct orientation that the two rings will be connected. Note the left and right rings. The data out from the right ring will be connected to the data in on the left ring.

Ring Wire

Use a 3-wire silicone cover stranded core ribbon cable to connect the two rings together. Measure and cut a piece of ribbon cable to be 4.5cm (1.7in) in length. Use wire stripers to remove a bit of insulation from the tips of each wire. Tin the tips by adding a bit of solder. This will prevent the strands of wire from fraying.

Wire Left Ring

Solder the ribbon cable to the three pins on the left ring. GND, DI and 5V. Third helping hands keep the PCBs in place while soldering.

Wire Right Ring

Solder the ribbon cable from the left ring to the right ring. Connect GND to GND, DO to DI and 5V to 5V. A second pair of helping hands was used to assist in keeping the PCBs secured while soldering.

Rings Wired

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

ItsyBItsy Wiring

Measure and cut a 3-wire ribbon cable to be 9.5cm (3.74in) in length. Use wire stripers to remove a bit of insulation from the tips of each wire. Tin the tips by adding a bit of solder. This will prevent the strands of wire from fraying.

Connect Wire to Right Ring

Attach the cable to the right ring by soldering the wires to the three pins. Use a helping hands tool to keep the PCB in place while soldering.

Connected Left and Right Rings

Double check the wiring to ensure the solder joints are solid.

Rings Frame Preinstallation

Orient the set of rings with the assembled frames to get an idea of the placement. The left ring is on the side with the Lipo Backpack and battery while the right ring is on the arm with the ItsyBitsy M4. 

Install Rings

Start by inserting the left ring into the right eye of the frame. Pull the left ring all the way through. Pass the cable from the right ring through the right eye.

Install Rings (Continued)

Orient the right ring so the cable is parallel with the arm. The LED rings should be upright and match the photo. The left and right circular ring holes on the frame feature bumps along the inner edges that will stop the PCBs from being pushed through. Insert the PCB at an angle in between the bumps to install.

Ring Installation (Continued)

Insert the left ring through the left eye on the frame. Push the PCB all the way through and orient so the LEDs are parallel with the arms and lined up with the right ring. Press fit the left ring into the left eye so the PCB is flush with the frame.

Install Wiring

Insert the ribbon cable from the rings through the holes on the side of the eye socket. Thread the ribbon cable through the center hole on the arm. Press the wiring into the channel on the arm.

Install Wiring (Continued)

Pull the ribbon cable through the other side of the arm.

Frame Installed Wires

Thoroughly inspect the frames and ensure the two rings are installed properly.

Lipo Backpack

A slide switch will need to be wired to the Trinket/ItsyBitsy Lipo Backpack. This PCB enables the ItsyBitsy M4 to have USB battery recharging.

Wire Switch

Connect a short 2-wire ribbon cable to the slide switch. The ideal length of wire is around 2.5cm (1in) which is pretty short! Note the pins on the switch have been shorted. Only use the middle pin and either far left or right pin.

Cut Trace

The pins on the Trinket/ItsyBitsy Lipo Backpack need to be cut in order to enable on/off switch functionality. Use diagonal flush snips to cut the trace. Use the mounting hole as an anchor. 

Wired Switch

Solder the two wires from the slide switch to the switch pins on the Trinket/ItsyBitsy Lipo Backpack. Solder the wires from the top of the PCB.

Wire for Lipo Backpack

Measure and cut a 30.5cm (12in) 3-wire ribbon cable. This will be used to connect the Trinket/ItsyBisty Lipo Backpack to the ItsyBisty M4.

Cut Ground Short

Measure out one wire to be 9cm (3.5in) in length. Use wire cutters to cut the wire. Peal away the (longer) excess wire from the 3-wire ribbon cable. The shorter wire will be connected to one of the ground pads on the left ring.

Connect Cable to Lipo Backpack

Solder the three wires to the pins on the back of the Trinket/ItsyBitsy Lipo Backpack. Ensure the short wire is soldered to the ground pin. The installation requires the wires to be soldered from the bottom of the PCB.

Wired Lipo Backpack

Double check the wiring is solid on the slide switch and Trinket/ItsyBitsy Lipo Backpack.

Install Lipo Backpack

Insert the cable from the Trinket/ItsyBitsy Lipo Backpack through the hole on the left arm. Pull the wiring all the way through so the PCB and switch are inside the enclosure.

Fit Components

Insert the slide switch at an angle into the holder on the side of the enclosure. The slide switch is press fitted and secured in place. Orient the Trinket/ItsyBitsy Lipo Backpack PCB so it's in the right position and press it into the enclosure. Reference the photo for correct placement.

Switch Install

The slide switch is accessible through the hole on the back of the enclosure on the left arm.

Ground Wire Install

Insert the cable from the Trinket/ItsyBitsy Lipo Backpack through the hole on the side of the left eye on the frames. Carefully fit the short wire through the hole.

Nose Bridge

String the rest of the cable under the wiring on nose bridge up and over the right ring. Position the wiring so it neatly goes across the two rings.

Solder Ground

Carefully attach the short wire to the nearest ground pad on the left ring. A pair of tweezers can assist handling of the wire. Please be careful not to damage the frame or arms with the soldering iron.

Install Lipo Backpack Wiring

Thread the cable from the Trinket/ItsyBitsy Lipo Backpack through the hole on the right eye. Insert the cable through hole in the enclosure on the right arm. Press the wiring down into the channel on the right arm.

Lipo Backpack Wiring Installed

Pull the wiring from the Trinket/ItsyBitsy Lipo Backpack through the other side of the right arm.

Installed Wiring

Two sets of ribbon cables are now ready to connect to the ItsyBitsy M4. The length of wiring ought to be enough to reach the pins on the ItsyBitsy M4.

Connect to ItsyBitsy M4

Solder the 3-wire cable from the rings to the pins on the bottom of the ItsyBitsy M4. Connect ground wire to the ground(G) pin, data in wire to pin #5 and 5V wire to Vhi pin. The Vhi pin is ideal for powering NeoPixels through USB or battery.

Wire Lipo Backpack Wires

Solder the two wires from the Trinket/ItsyBitsy Lipo Backpack to the BAT and USB pins on the ItsyBitsy M4. Check the continuity with a multi-meter to check which wire is connect to the BAT and USB pins.

Install ItsyBisty

Carefully install the ItsyBitsy M4 into the enclosure. Insert the PCB at an angle so one side is under the clips. Press the PCB into the case to snap fit it into place. Slide the PCB down so it's flush with the case.

Install Wires

Check the wiring and ensure it's fitted into the channels on the arms.

Connect Battery

Plug in the 400mAh battery to the JST port on the Trinket/ItsyBitsy Lipo Backpack. Orient the battery so it's matching the photo. Place the battery into the enclosure.

Install Cover

Place the battery cover over the case on the left arm. Insert the cover at an angle so one side is lined up with the groves on the edge. Firmly press together to snap fit into place.

Assembled Glasses

Use the slide switch to turn the circuit on and off. Recharge the battery over microUSB by plugging in the ItsyBitsy M4 to computer or 5V wall adapter.

USB Connect

The ItsyBisty M4 is easily accessible on the side of the right arm. This fully reversible USB cable is our favorite.

Recharging Battery

Check the LEDs on-board the Trinket/ItsyBitsy Lipo Backpack to see the status of the battery.

  • Red LED means the battery is recharging.
  • Green LED means the battery has been fully recharged.
NeoPixels will stay on while the battery is recharging. Change the brightness to 0 on line 17 in the code.py file to turn off the NeoPixels.

Wearable

Wearing a hat helps support the weight of the glasses. Tucking the arms under the hat can help keep them secured.

Going Beyond

There's room for improving the comfort of the glasses. Perhaps some sugru to create a makeshift nose bridge. Wearing these glasses for long periods of time can cause discomfort.

This guide was first published on Jan 01, 2020. It was last updated on Jan 01, 2020.