TREEFORT MUSIC FESTIVAL WORKSHOP: HOW TO MAKE AN INTERACTIVE WEARABLE LED PROJECT

 

Getting the opportunity to share some skills about how the world of electronics works is a core part of the Sensebellum experience.

Recently for the 2024 TreeFort Music Festival in Boise, Idaho Sensebellum was invited to host a workshop at HackFort on the topic of making an interactive wearable LED project.

On this page we will share the code, some support files, as well as links to the parts that were used.




PARTS


TOOLS

  • Soldering Iron

  • Wire Strippers

  • Phillips #1 Screw Driver

  • 3D Printer

  • USB Micro Cable

  • Computer


LIBRARIES


CODE


Hello World Blink


import board
import digitalio
import time

led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT

while True:
    led.value = not led. value
    time.sleep(1)

Test LED Ring


import board
import neopixel
import time

# Configure the setup
pixel.pin = board.D1

# The in connected to the NeoPixels
# Number of pixels in the NeoPixel ring
num pixels = 16
pixels = neopixel.NeoPixel(pixel_pin, num pixels, brightness=0.3,
auto write=False)

def blink(color. delay) :
    pixels.fill(color)
    pixels.show()
    time.sleep(delay)
    pixels.fill((0, 0, 0))
    pixels. show()
    time.sleep(delay)

while True:
    # Blink the LEDs in red
    blink((255, 0, 0), 1)
    # Color (R, G, B), Delay in seconds
    

Test Microphone


import board
import analogio
import time

# Initialize the microphone
mic = analogio.AnalogIn(board.A1)

while True:
    # Read the microphone value
    mic_value = mic.value
    # Print the microphone value
    print ("Microphone value:", mic_value)
    # Wait a little before reading again
    time.sleep(0.1)
    

Test Capacitive Switch


import board
import touchio
import neopixel
import time

# Setup capacitive touch on A2
touch pad = board. A2
touch = touchio.TouchIn (touch pad)

# Setup NeoPixel LED
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)
led on = False # Track LED state

while True:
    if touch. value:
    # Check if touch pad is touched
        led on = not led on # Toggle LED state
        if led on:
            pixel.fill((255, 255, 255)) # Turn LED on (white)
        else:
            pixel.fill((0, 0, 0)) # Turn LED off
        while touch. value:
            pass # Wait for the touch to be released to avoid multiple toggles
        time.sleep(0.1) # Debounce delay to ensure stable toggle behavior
        

Full Program


import board
import neopixel
import analogio
import touchio
import time

# Setup for NeoPixels
num_pixels = 16
pixels = neopixel.NeoPixel(board.D1, num_pixels, brightness=0.1, auto_write=False)

# Setup for microphone
mic = analogio.AnalogIn(board.A1)

# Setup for capacitive touch on A2
touch = touchio.TouchIn(board.A2)

# Configuration variables
lower_bound = 45000
upper_bound = 1000
mode = 0  # Start in audio-reactive mode
rainbow_speed = 0.05  # Adjusted speed for visible cycling

last_mode_change = time.monotonic()

# Function to calculate the re_scaled value
def calculate_re_scale(raw_value):
    if raw_value >= lower_bound:
        return raw_value
    elif raw_value <= upper_bound:
        return 65535 + raw_value
    return raw_value  # Avoiding None to simplify logic

# Rainbow cycle helper function
def wheel(pos):
    if pos < 85:
        return (pos * 3, 255 - pos * 3, 0)
    elif pos < 170:
        pos -= 85
        return (255 - pos * 3, 0, pos * 3)
    else:
        pos -= 170
        return (0, pos * 3, 255 - pos * 3)

# Function to display rainbow across all pixels
def rainbow_cycle():
    for i in range(num_pixels):
        rc_index = (i * 256 // num_pixels) + int(time.monotonic() * 1000 / rainbow_speed) % 256
        pixels[i] = wheel(rc_index & 255)

# Main loop
while True:
    # Check for mode change
    if touch.value and (time.monotonic() - last_mode_change > 0.3):
        mode = (mode + 1) % 3
        last_mode_change = time.monotonic()
        print(f"Switched to mode ")
        time.sleep(0.1)  # Debounce

    if mode == 0:  # Audio-reactive mode
        raw_value = mic.value
        re_scale = calculate_re_scale(raw_value)
        real_value = (re_scale - lower_bound) / (65535 + upper_bound - lower_bound)
        brightness_level = int(255 * max(0, min(real_value, 1)))
        pixels.fill((brightness_level, brightness_level, brightness_level))
        print(f"Raw value: , Re_scale: , Brightness: ")

    elif mode == 1:  # Rainbow cycle mode
        rainbow_cycle()
        pixels.show()  # Update the display to show the rainbow
        # No delay needed here as rainbow_cycle's speed is controlled by rainbow_speed

    elif mode == 2:  # Red mode
        pixels.fill((255, 0, 0))

    # For modes 0 and 2, ensure LEDs are updated and a slight delay is introduced
    if mode != 1:
        pixels.show()
        time.sleep(0.03)
      


 

A special thank you to Sean wakeley, Mike Taylor, and the rest of the awesome team at hackfort and treefort!