Light-Up Reactive Ukulele Problems (Feather Sense)

For Adafruit customers who seek help with microcontrollers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
eeeeeepic
 
Posts: 20
Joined: Mon May 14, 2018 10:36 am

Light-Up Reactive Ukulele Problems (Feather Sense)

Post by eeeeeepic »

Hi there! I'm having issues with the Adafruit light-up reactive ukulele project (https://learn.adafruit.com/light-up-reactive-ukulele). I just finished soldering it together, but am not seeing any of the Side Light Neopixel Strand light up, unfortunately. This uses the Feather Sense and Propmaker Featherwing.

The code.py I used is the exact one from the project with no modifications. My modifications from the original project are to use a straight M-F USB cable instead of one I soldered myself, and only using the single Side Light strand (and not adding on the light extension).

The lib file of my CIRCUITPY includes:

- adafruit_apds9960
- adafruit_bus_device
- adafruit_led_animation
- adafruit_lsm6ds
- adafruit_register
- adafruit_bmp280.mpy
- adafruit_lis3mdl.mpy
- adafruit_sht31d.mpy
- neopixel.mpy

The tutorial asks for adafruit_lsm6ds.mpy but I can't find that in the basic library to copy over.

Here's some photos of the board setup:

Image
Image
Image
Image
Image

And video of the lights flashing:

https://streamable.com/jjp7tk

Let me know if you have any ideas - thanks in advance! Really excited to get this project moving. :)

User avatar
mikeysklar
 
Posts: 13824
Joined: Mon Aug 01, 2016 8:10 pm

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by mikeysklar »

Since you are only using one strip did you change the code in regards to the number NeoPixels? I believe the guides example utilizes 24 pixels per strip.

Soldering looks really good on the propmaker pins.

You are correct that there is no longer an adafruit_lsm6ds.mpy, but there is a folder in the CircuitPython library bundle titled:

adafruit_lsm6ds/

so you will want to copy the folder and it's contents to your lib folder.

Please make sure you libraries are in sync with the current CircuitPython release.

User avatar
eeeeeepic
 
Posts: 20
Joined: Mon May 14, 2018 10:36 am

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by eeeeeepic »

mikeysklar wrote:Since you are only using one strip did you change the code in regards to the number NeoPixels? I believe the guides example utilizes 24 pixels per strip.

Soldering looks really good on the propmaker pins.

You are correct that there is no longer an adafruit_lsm6ds.mpy, but there is a folder in the CircuitPython library bundle titled:

adafruit_lsm6ds/

so you will want to copy the folder and it's contents to your lib folder.

Please make sure you libraries are in sync with the current CircuitPython release.
I didn't adjust the Neopixel count, which seems like a silly thing I should have considered! I'll give it a shot tomorrow and report back. :)

Thanks for the compliment on the soldering! This was my first time soldering a row of pins onto a board like this (most of my experiments have been with Flora/Gem boards so far, which require a lot less precision) so I was pretty nervous, haha!

I did copy that library and the current Python release over; glad to see it confirmed that it was the right folder.

Thanks again for your help - I'll let you know how it goes!

User avatar
eeeeeepic
 
Posts: 20
Joined: Mon May 14, 2018 10:36 am

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by eeeeeepic »

No luck just yet, unfortunately! I ran it through the mu editor but it mostly just seemed to find syntax errors to report. Anything you can see here that might be causing the issue? (I modified it to try and limit it to the 60 lights per strand.)

Code: Select all

"""
LED Ukulele with Feather Sense and PropMaker Wing
Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!
Written by Erin St Blaine & Limor Fried for Adafruit Industries
Copyright (c) 2019-2020 Adafruit Industries
Licensed under the MIT license.
All text above must be included in any redistribution.

MODES:
0 = off/powerup, 1 = sound reactive, 2 = non-sound reactive, 3 = tilt
Pluck high A on the E string to toggle sound reactive mode on or off
Pluck high A♭ on the E string to cycle through the animation modes
"""

import time
import array
import digitalio
import audiobusio
import board
import neopixel
import ulab.numerical as numerical
import ulab.extras as extras
import ulab as np
import adafruit_lsm6ds
from adafruit_led_animation.helper import PixelMap
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.animation.chase import Chase
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.color import colorwheel
from adafruit_led_animation.color import (
    BLACK,
    RED,
    ORANGE,
    BLUE,
    PURPLE,
    WHITE,
)

MAX_BRIGHTNESS = 0.3 #set max brightness for sound reactive mode
NORMAL_BRIGHTNESS = 0.1 #set brightness for non-reactive mode
VOLUME_CALIBRATOR = 50 #multiplier for brightness mapping
ROCKSTAR_TILT_THRESHOLD = 200 #shake threshold
SOUND_THRESHOLD = 430000 #main strum or pluck threshold

# Set to the length in seconds for the animations
POWER_ON_DURATION = 1.3
ROCKSTAR_TILT_DURATION = 1

NUM_PIXELS = 60  # Number of pixels used in project
NEOPIXEL_PIN = board.D5
POWER_PIN = board.D10

enable = digitalio.DigitalInOut(POWER_PIN)
enable.direction = digitalio.Direction.OUTPUT
enable.value = False

i2c = board.I2C()

pixels = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_PIXELS, brightness=1, auto_write=False)
pixels.fill(0)  # NeoPixels off ASAP on startup
pixels.show()


#PIXEL MAPS: Used for reordering pixels so the animations can run in different configurations.
#My LED strips inside the neck are accidentally swapped left-right,
#so these maps also correct for that


#Bottom up along both sides at once
pixel_map_reverse = PixelMap(pixels, [
    0, 60, 1, 59, 2, 58, 3, 57, 4, 56, 5, 55, 6, 54 7, 53, 8, 52, 9, 51, 10,
    50, 11, 49, 12, 48, 13, 47, 14, 46, 15, 45, 16, 44, 17, 43, 18, 42, 19, 41, 20,
    40, 21, 39, 22, 38, 23, 37, 24, 36, 25, 35, 26, 34, 27, 33, 28, 32, 29, 31, 30,
    ], individual_pixels=True)

#Starts at the bottom and goes around clockwise
pixel_map_around = PixelMap(pixels, [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 
    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
    ], individual_pixels=True)

pixel_map_radiate = PixelMap(pixels, [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 
    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
    ], individual_pixels=True)

pixel_map_sweep = PixelMap(pixels, [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 
    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
    ], individual_pixels=True)

pixel_map_skip = PixelMap(pixels, [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 
    48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
    ], individual_pixels=True)

pixel_map = [
    pixel_map_reverse,
    pixel_map_around,
    pixel_map_radiate,
    pixel_map_sweep,
    pixel_map_skip,
]

#Set up accelerometer & mic
sensor = adafruit_lsm6ds.LSM6DS33(i2c)
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK,
                       board.MICROPHONE_DATA,
                       sample_rate=16000,
                       bit_depth=16)

NUM_SAMPLES = 256
samples_bit = array.array('H', [0] * (NUM_SAMPLES+3))

def power_on(duration):
    """
    Animate NeoPixels for power on.
    """
    start_time = time.monotonic()  # Save start time
    while True:
        elapsed = time.monotonic() - start_time  # Time spent
        if elapsed > duration:  # Past duration?
            break  # Stop animating
        powerup.animate()

def rockstar_tilt(duration):
    """
    Tilt animation - lightning effect with a rotating color
    :param duration: duration of the animation, in seconds (>0.0)
    """
    tilt_time = time.monotonic()  # Save start time
    while True:
        elapsed = time.monotonic() - tilt_time  # Time spent
        if elapsed > duration:  # Past duration?
            break  # Stop animating
        pixels.brightness = MAX_BRIGHTNESS
        pixels.fill(TILT_COLOR)
        pixels.show()
        time.sleep(0.01)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.03)
        pixels.fill(WHITE)
        pixels.show()
        time.sleep(0.02)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.005)
        pixels.fill(TILT_COLOR)
        pixels.show()
        time.sleep(0.01)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.03)

# Cusomize LED Animations  ------------------------------------------------------
powerup = RainbowComet(pixel_map[3], speed=0, tail_length=15, bounce=False)
rainbow = Rainbow(pixel_map[4], speed=0, period=6, name="rainbow", step=2.4)
rainbow_chase = RainbowChase(pixel_map[3], speed=0, size=3, spacing=5, step=10)
rainbow_chase2 = RainbowChase(pixel_map[2], speed=0, size=10, spacing=1, step=8)
chase = Chase(pixel_map[1], speed=0.1, color=RED, size=1, spacing=6)
rainbow_comet = RainbowComet(pixel_map[2], speed=0, tail_length=20, bounce=True)
rainbow_comet2 = RainbowComet(
    pixel_map[0], speed=0, tail_length=60, colorwheel_offset=80, bounce=True
    )
rainbow_comet3 = RainbowComet(
    pixel_map[1], speed=0, tail_length=15, colorwheel_offset=80, step=4, bounce=False
    )
strum = RainbowComet(
    pixel_map[3], speed=0, tail_length=15, bounce=False, colorwheel_offset=50, step=4
    )
lava = Comet(pixel_map[3], speed=0.01, color=ORANGE, tail_length=20, bounce=False)
sparkle = Sparkle(pixel_map[4], speed=0.01, color=BLUE, num_sparkles=10)
sparkle2 = Sparkle(pixel_map[1], speed=0.05, color=PURPLE, num_sparkles=4)

# Animations Playlist - reorder as desired. AnimationGroups play at the same time
animations = AnimationSequence(
    rainbow,
    rainbow_chase,
    rainbow_chase2,
    chase,
    lava,
    rainbow_comet,
    rainbow_comet2,
    AnimationGroup(
        sparkle,
        strum,
        ),
    AnimationGroup(
        sparkle2,
        rainbow_comet3,
        ),
    auto_clear=True,
    auto_reset=True,
)


MODE = 0
LASTMODE = 1 # start up in sound reactive mode
i = 0

# Main loop
while True:
    i = (i + 0.5) % 256  # run from 0 to 255
    TILT_COLOR = colorwheel(i)
    if MODE == 0:  # If currently off...
        enable.value = True
        power_on(POWER_ON_DURATION)  # Power up!
        MODE = LASTMODE

    elif MODE >= 1:  # If not OFF MODE...
        mic.record(samples_bit, len(samples_bit))
        samples = np.array(samples_bit[3:])
        spectrum = extras.spectrogram(samples)
        spectrum = spectrum[:128]
        spectrum[0] = 0
        spectrum[1] = 0
        peak_idx = numerical.argmax(spectrum)
        peak_freq = peak_idx * 16000 / 256
#        print((peak_idx, peak_freq, spectrum[peak_idx]))
        magnitude = spectrum[peak_idx]
#         time.sleep(1)
        if peak_freq == 812.50 and magnitude > SOUND_THRESHOLD:
            animations.next()
            time.sleep(1)
        if peak_freq == 875 and magnitude > SOUND_THRESHOLD:
            if MODE == 1:
                MODE = 2
                print("mode = 2")
                LASTMODE = 2
                time.sleep(1)
            elif MODE == 2:
                MODE = 1
                print("mode = 1")
                LASTMODE = 1
                time.sleep(1)
    # Read accelerometer
        x, y, z = sensor.acceleration
        accel_total = x * x + y * y # x=tilt, y=rotate
#         print (accel_total)
        if accel_total > ROCKSTAR_TILT_THRESHOLD:
            MODE = 3
            print("Tilted: ", accel_total)
        if MODE == 1:
            VOLUME = magnitude / (VOLUME_CALIBRATOR * 100000)
            if VOLUME > MAX_BRIGHTNESS:
                VOLUME = MAX_BRIGHTNESS
#             print(VOLUME)
            pixels.brightness = VOLUME
#             time.sleep(2)
            animations.animate()
        elif MODE == 2:
            pixels.brightness = NORMAL_BRIGHTNESS
            animations.animate()
        elif MODE == 3:
            rockstar_tilt(ROCKSTAR_TILT_DURATION)
            MODE = LASTMODE

User avatar
eeeeeepic
 
Posts: 20
Joined: Mon May 14, 2018 10:36 am

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by eeeeeepic »

Hi again,

So, I found one error - it turns out this is a 90 pixel strand, not a 60 one. I had ordered the 60, and my order history indicates that, but in the email it was switched to a 90 LED Side Strand? Not complaining, mind you! More lights are always great!

As such I've updated the code to the following, but am still getting a flashing error. The error is a long green, long yellow, break, short yellow x 2, short cyan x 4. Which indicates an error at Line 24... which is importing ulab.extras as extras. I cannot even guess what the problem might be there, and a Google hasn't helped either. The code seems to clear mu's check process without issue. Any suggestions?

Code: Select all

"""
LED Ukulele with Feather Sense and PropMaker Wing
Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!
Written by Erin St Blaine & Limor Fried for Adafruit Industries
Copyright (c) 2019-2020 Adafruit Industries
Licensed under the MIT license.
All text above must be included in any redistribution.

MODES:
0 = off/powerup, 1 = sound reactive, 2 = non-sound reactive, 3 = tilt
Pluck high A on the E string to toggle sound reactive mode on or off
Pluck high A♭ on the E string to cycle through the animation modes
"""

import time
import array
import digitalio
import audiobusio
import board
import neopixel
import ulab.numerical as numerical
import ulab.extras as extras
import ulab as np
import adafruit_lsm6ds
from adafruit_led_animation.helper import PixelMap
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.animation.chase import Chase
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.color import colorwheel
from adafruit_led_animation.color import (
    BLACK,
    RED,
    ORANGE,
    BLUE,
    PURPLE,
    WHITE,
)

MAX_BRIGHTNESS = 0.3  # set max brightness for sound reactive mode
NORMAL_BRIGHTNESS = 0.1  # set brightness for non-reactive mode
VOLUME_CALIBRATOR = 50  # multiplier for brightness mapping
ROCKSTAR_TILT_THRESHOLD = 200  # shake threshold
SOUND_THRESHOLD = 430000  # main strum or pluck threshold

# Set to the length in seconds for the animations
POWER_ON_DURATION = 1.3
ROCKSTAR_TILT_DURATION = 1

NUM_PIXELS = 90  # Number of pixels used in project
NEOPIXEL_PIN = board.D5
POWER_PIN = board.D10

enable = digitalio.DigitalInOut(POWER_PIN)
enable.direction = digitalio.Direction.OUTPUT
enable.value = False

i2c = board.I2C()

pixels = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_PIXELS, brightness=1, 
                           auto_write=False)
pixels.fill(0)  # NeoPixels off ASAP on startup
pixels.show()


# PIXEL MAPS: Used for reordering pixels so the animations can run 
# in different configurations.
# My LED strips inside the neck are accidentally swapped left-right,
# so these maps also correct for that


# Bottom up along both sides at once
pixel_map_reverse = PixelMap(pixels, [
    0, 90, 1, 89, 2, 88, 3, 87, 4, 86, 5, 85, 6, 84, 7, 83, 8, 82, 9, 81, 10,
    80, 11, 79, 12, 78, 13, 77, 14, 76, 15, 75, 16, 74, 17, 73, 18, 72, 
    19, 71, 20, 70, 21, 69, 22, 68, 23, 67, 24, 66, 25, 65, 26, 64, 27, 
    63, 28, 62, 29, 61, 30, 60, 31, 59, 32, 58, 33, 57, 34, 56, 35, 55, 
    36, 54, 37, 53, 38, 52, 39, 51, 40, 49, 41, 48, 42, 47, 43, 46, 44, 
    45,
    ], individual_pixels=True)

# Starts at the bottom and goes around clockwise
pixel_map_around = PixelMap(pixels, [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22, 23, 24, 25, 26, 27, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64,
    63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45,
    44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
    76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 
    ], individual_pixels=True)

# Radiates from the center outwards like a starburst
pixel_map_radiate = PixelMap(pixels, [
    75, 73, 76, 27, 28, 74, 77, 26, 29, 73, 78, 25, 30, 72, 79, 24, 31, 71, 80,
    23, 32, 70, 81, 22, 33, 69, 82, 21, 34, 68, 83, 20, 35, 67, 84, 19, 36, 66,
    85, 18, 37, 65, 38, 86, 17, 64, 39, 87, 16, 63, 40, 88, 15, 62, 41, 89, 14,
    61, 42, 90, 13, 60, 43, 12, 59, 44, 11, 58, 45, 10, 57, 46, 
    9, 56, 47, 8, 55, 48, 7, 54, 49, 6, 53, 50, 5, 52, 51, 
    4, 3, 2, 1, 0,
    ], individual_pixels=True)

# Top down along both sides at once
pixel_map_sweep = PixelMap(pixels, [
    51, 52, 50, 53, 49, 54, 48, 55, 47, 56, 46, 57, 45, 58, 44, 59, 43, 60, 
    42, 61, 41, 62, 40, 63, 39, 64, 38, 65, 37, 66, 36, 67, 35, 68, 34, 69, 
    33, 70, 32, 71, 31, 72, 30, 73, 29, 74, 28, 75, 27, 76, 27, 77, 26, 78, 
    25, 79, 24, 80, 23, 81, 22, 82, 21, 83, 20, 84, 19, 85, 18, 86, 17, 87, 
    16, 88, 15, 89, 14, 90,
    ], individual_pixels=True)

# Every other pixel, starting at the bottom and going upwards along both sides
pixel_map_skip = PixelMap(pixels, [
    0, 90, 2, 88, 4, 86, 6, 84, 8, 82, 10, 80, 12, 78, 14, 76, 16, 74, 18, 72,
    20, 70, 22, 68, 24, 66, 26, 64, 29, 62, 31, 60, 33, 58, 35, 56, 37, 54, 39, 
    52, 41,     50, 43, 48, 45, 46, 47, 
    ], individual_pixels=True)

pixel_map = [
    pixel_map_reverse,
    pixel_map_around,
    pixel_map_radiate,
    pixel_map_sweep,
    pixel_map_skip,
]

# Set up accelerometer & mic
sensor = adafruit_lsm6ds.LSM6DS33(i2c)
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK,
                       board.MICROPHONE_DATA,
                       sample_rate=16000,
                       bit_depth=16)

NUM_SAMPLES = 256
samples_bit = array.array('H', [0] * (NUM_SAMPLES+3))

def power_on(duration):
    """
    Animate NeoPixels for power on.
    """
    start_time = time.monotonic()  # Save start time
    while True:
        elapsed = time.monotonic() - start_time  # Time spent
        if elapsed > duration:  # Past duration?
            break  # Stop animating
        powerup.animate()

def rockstar_tilt(duration):
    """
    Tilt animation - lightning effect with a rotating color
    :param duration: duration of the animation, in seconds (>0.0)
    """
    tilt_time = time.monotonic()  # Save start time
    while True:
        elapsed = time.monotonic() - tilt_time  # Time spent
        if elapsed > duration:  # Past duration?
            break  # Stop animating
        pixels.brightness = MAX_BRIGHTNESS
        pixels.fill(TILT_COLOR)
        pixels.show()
        time.sleep(0.01)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.03)
        pixels.fill(WHITE)
        pixels.show()
        time.sleep(0.02)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.005)
        pixels.fill(TILT_COLOR)
        pixels.show()
        time.sleep(0.01)
        pixels.fill(BLACK)
        pixels.show()
        time.sleep(0.03)

# Cusomize LED Animations  ---------------------------------------------------
powerup = RainbowComet(pixel_map[3], speed=0, tail_length=25, bounce=False)
rainbow = Rainbow(pixel_map[4], speed=0, period=6, name="rainbow", step=2.4)
rainbow_chase = RainbowChase(pixel_map[3], speed=0, size=3, spacing=15, 
                             step=10)
rainbow_chase2 = RainbowChase(pixel_map[2], speed=0, size=10, spacing=1, 
                              step=18)
chase = Chase(pixel_map[1], speed=0.1, color=RED, size=1, spacing=6)
rainbow_comet = RainbowComet(pixel_map[2], speed=0, tail_length=45, 
                             bounce=True)
rainbow_comet2 = RainbowComet(
    pixel_map[0], speed=0, tail_length=50, colorwheel_offset=80, bounce=True
    )
rainbow_comet3 = RainbowComet(
    pixel_map[1], speed=0, tail_length=25, colorwheel_offset=80, step=4, 
    bounce=False
    )
strum = RainbowComet(
    pixel_map[3], speed=0, tail_length=25, bounce=False, colorwheel_offset=50, 
    step=4
    )
lava = Comet(pixel_map[3], speed=0.01, color=ORANGE, tail_length=40, 
             bounce=False)
sparkle = Sparkle(pixel_map[4], speed=0.01, color=BLUE, num_sparkles=10)
sparkle2 = Sparkle(pixel_map[1], speed=0.05, color=PURPLE, num_sparkles=4)

# Animations Playlist - reorder as desired. AnimationGroups play at 
# the same time
animations = AnimationSequence(
    rainbow,
    rainbow_chase,
    rainbow_chase2,
    chase,
    lava,
    rainbow_comet,
    rainbow_comet2,
    AnimationGroup(
        sparkle,
        strum,
        ),
    AnimationGroup(
        sparkle2,
        rainbow_comet3,
        ),
    auto_clear=True,
    auto_reset=True,
)


MODE = 0
LASTMODE = 1  # start up in sound reactive mode
i = 0

# Main loop
while True:
    i = (i + 0.5) % 256  # run from 0 to 255
    TILT_COLOR = colorwheel(i)
    if MODE == 0:  # If currently off...
        enable.value = True
        power_on(POWER_ON_DURATION)  # Power up!
        MODE = LASTMODE

    elif MODE >= 1:  # If not OFF MODE...
        mic.record(samples_bit, len(samples_bit))
        samples = np.array(samples_bit[3:])
        spectrum = extras.spectrogram(samples)
        spectrum = spectrum[:128]
        spectrum[0] = 0
        spectrum[1] = 0
        peak_idx = numerical.argmax(spectrum)
        peak_freq = peak_idx * 16000 / 256
#        print((peak_idx, peak_freq, spectrum[peak_idx]))
        magnitude = spectrum[peak_idx]
#         time.sleep(1)
        if peak_freq == 812.50 and magnitude > SOUND_THRESHOLD:
            animations.next()
            time.sleep(1)
        if peak_freq == 875 and magnitude > SOUND_THRESHOLD:
            if MODE == 1:
                MODE = 2
                print("mode = 2")
                LASTMODE = 2
                time.sleep(1)
            elif MODE == 2:
                MODE = 1
                print("mode = 1")
                LASTMODE = 1
                time.sleep(1)
    # Read accelerometer
        x, y, z = sensor.acceleration
        accel_total = x * x + y * y  # x=tilt, y=rotate
#         print (accel_total)
        if accel_total > ROCKSTAR_TILT_THRESHOLD:
            MODE = 3
            print("Tilted: ", accel_total)
        if MODE == 1:
            VOLUME = magnitude / (VOLUME_CALIBRATOR * 100000)
            if VOLUME > MAX_BRIGHTNESS:
                VOLUME = MAX_BRIGHTNESS
#             print(VOLUME)
            pixels.brightness = VOLUME
#             time.sleep(2)
            animations.animate()
        elif MODE == 2:
            pixels.brightness = NORMAL_BRIGHTNESS
            animations.animate()
        elif MODE == 3:
            rockstar_tilt(ROCKSTAR_TILT_DURATION)
            MODE = LASTMODE

User avatar
eeeeeepic
 
Posts: 20
Joined: Mon May 14, 2018 10:36 am

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by eeeeeepic »

One more update: I've tried testing the NeoPixels themselves with the following code:

Code: Select all

import time
import board
import neopixel


#  On CircuitPlayground Express, and boards with built in status NeoPixel
#  -> board.NEOPIXEL
#  Otherwise choose an open pin connected to the Data In of the NeoPixel
#  strip, i.e. board.D1
pixel_pin = board.NEOPIXEL

#  On a Raspberry pi, use this instead, not all pins are supported
#  pixel_pin = board.D18

#  The number of NeoPixels
num_pixels = 90

#  The order of the pixel colors - RGB or GRB. Some NeoPixels have red and
#  green reversed!
#  For RGBW NeoPixels, simply change the ORDER to RGBW or GRBW.
ORDER = neopixel.GRB

pixels = neopixel.NeoPixel(
    pixel_pin, num_pixels, brightness=0.2, auto_write=False,
    pixel_order=ORDER
    )


def wheel(pos):
        # Input a value 0 to 255 to get a color value.
        # The colours are a transition r - g - b - back to r.
        if pos < 0 or pos > 255:
            r = g = b = 0
        elif pos < 85:
            r = int(pos * 3)
            g = int(255 - pos * 3)
            b = 0
        elif pos < 170:
            pos -= 85
            r = int(255 - pos * 3)
            g = 0
            b = int(pos * 3)
        else:
            pos -= 170
            r = 0
            g = int(pos * 3)
            b = int(255 - pos * 3)
        return (r, g, b) if ORDER in (neopixel.RGB, neopixel.GRB) else (r, g,
                                                                        b, 0)


def rainbow_cycle(wait):
        for j in range(255):
            for i in range(num_pixels):
                pixel_index = (i * 256 // num_pixels) + j
                pixels[i] = wheel(pixel_index & 255)
            pixels.show()
            time.sleep(wait)


while True:
        # Comment this line out if you have RGBW/GRBW NeoPixels
        pixels.fill((255, 0, 0))
        # Uncomment this line if you have RGBW/GRBW NeoPixels
        # pixels.fill((255, 0, 0, 0))
        pixels.show()
        time.sleep(1)

        # Comment this line out if you have RGBW/GRBW NeoPixels
        pixels.fill((0, 255, 0))
        # Uncomment this line if you have RGBW/GRBW NeoPixels
        # pixels.fill((0, 255, 0, 0))
        pixels.show()
        time.sleep(1)

        # Comment this line out if you have RGBW/GRBW NeoPixels
        pixels.fill((0, 0, 255))
        # Uncomment this line if you have RGBW/GRBW NeoPixels
        # pixels.fill((0, 0, 255, 0))
        pixels.show()
        time.sleep(1)

        rainbow_cycle(0.001)  # rainbow cycle with 1ms delay per step
No luck - none of the pixels on the strand are lighting up. There are no error codes flashing on the board - it's doing the rainbow pattern. I've also tried soldering my other connector onto the other end of the NeoPixel strand, and had no luck using that either.

Does it seem like there might be a flaw with the board or the light strand, maybe? Is there something I seem to noticeably be doing wrong, or should I just reorder the parts and see if that'll help? The solder links seem strong, so I don't think that's the flaw...

EDIT: SUCCESS! I got the lights to actually work with the following code:

Code: Select all

"""Simple rainbow example for 30-pixel NeoPixel strip"""
import digitalio
import board
import neopixel

NUM_PIXELS = 90  # NeoPixel strip length (in pixels)

enable = digitalio.DigitalInOut(board.D10)
enable.direction = digitalio.Direction.OUTPUT
enable.value = True

strip = neopixel.NeoPixel(board.D5, NUM_PIXELS, brightness=1)


def wheel(pos):
    # Input a value 0 to 255 to get a color value.
    # The colours are a transition r - g - b - back to r.
    if pos < 0 or pos > 255:
        return (0, 0, 0)
    if pos < 85:
        return (255 - pos * 3, pos * 3, 0)
    if pos < 170:
        pos -= 85
        return (0, 255 - pos * 3, pos * 3)
    pos -= 170
    return (pos * 3, 0, 255 - pos * 3)


while True:
    for i in range(255):
        strip.fill((wheel(i)))
This leaves the issue with the original ukulele code though - I'm still having issues at the ulab line. Anyone have any thoughts? (And thanks to anyone who has followed this neverending journey so far, haha.)

User avatar
mikeysklar
 
Posts: 13824
Joined: Mon Aug 01, 2016 8:10 pm

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by mikeysklar »

Good job getting the NeoPixels going. It looks like they are working on the same pin (D5) as the Ukulele example. I assume you went back to the 'original' Ukulele code we supply and updated your NUM_PIXELS as the guide suggests?

It sounds like the conflict is elsewhere. I would start adding print statements and watch the REPL console to see which functions are getting called. The power_on() method has some timing logic which you will want to make sure you getting through to the powerup.animate() call.

User avatar
James1234
 
Posts: 1
Joined: Sat Jul 24, 2021 12:46 pm

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by James1234 »

eeeeeepic wrote:Which indicates an error at Line 24... which is importing ulab.extras as extras. I cannot even guess what the problem might be there, and a Google hasn't helped either. The code seems to clear mu's check process without issue. Any suggestions?
I am trying to do the same and I'm having exactly the same problem. Did you ever find a solution?

"ImportError: no module named 'ulab.extras'"

It seems to work without the error message with CircuitPython 5.3.1 (but the LEDs so far don't work), but not with 6 or 7 for which the guides seems to have been made. Maybe something else changed by now and this build-in library "ulab" doesn't exist any more or has been renamed? I also noticed that the libraries mentioned in the guide are not 100 identical to those put into the project file.

It's a bit of a shame that those guides are all half broken and are not being updated any longer. People who try to learn with those guides are then left to their own devices and cannot finish a project.

User avatar
mikeysklar
 
Posts: 13824
Joined: Mon Aug 01, 2016 8:10 pm

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by mikeysklar »

@James1234,

ulab is a built-in so I'm guessing what has changed from CP 5.x going to newer CP 6.x/7.x is how the core module has renamed the extensions. There is no more ulab.extras, but you should be able to use:
  • ulab.numpy
  • ulab.scipy
  • ulab.user
https://circuitpython.readthedocs.io/en ... index.html

User avatar
jepler1
 
Posts: 50
Joined: Mon Oct 28, 2013 4:16 pm

Re: Light-Up Reactive Ukulele Problems (Feather Sense)

Post by jepler1 »

Hi! I think I helped Erin with this code when the guide was first written.

ulab has been revised several times through various Python versions. There's currently a pull request open that is intended to make it compatible with CircuitPython 7.0.0-alpha.5. If you're able to test it out and give us feedback that would be great! You can find the Pull Request here: https://github.com/adafruit/Adafruit_Le ... /pull/1675

Locked
Please be positive and constructive with your questions and comments.

Return to “Microcontrollers”