Skip to content

Instantly share code, notes, and snippets.

@todbot
Created January 29, 2024 23:59
Show Gist options
  • Save todbot/e31f46e5036fbab2709be3d603d49380 to your computer and use it in GitHub Desktop.
Save todbot/e31f46e5036fbab2709be3d603d49380 to your computer and use it in GitHub Desktop.
Neopixel LED animations + playing audio on Pico RP2040
# led animations + audio on RP2040 Pico
#
import os, time, random
import board, keypad
import audiomixer, audiocore
import audiopwmio
import neopixel
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.rainbowsparkle import RainbowSparkle
from adafruit_led_animation.sequence import AnimationSequence
leds = neopixel.NeoPixel(board.GP6, 64, brightness=0.1, auto_write=False)
keys = keypad.Keys( (board.GP12,), value_when_pressed=False, pull=True)
audio = audiopwmio.PWMAudioOut(board.GP21) # RP2040 Pico example
mixer = audiomixer.Mixer(voice_count=1, sample_rate=22050, channel_count=1,
bits_per_sample=16, samples_signed=True, buffer_size=4096)
audio.play(mixer) # attach mixer to audio playback
rainbow = Rainbow(leds, speed=0.1, period=4)
rainbow_chase = RainbowChase(leds, speed=0.1, size=4, spacing=3)
rainbow_comet = RainbowComet(leds, speed=0.1, tail_length=12, bounce=True)
rainbow_sparkle = RainbowSparkle(leds, speed=0.1, num_sparkles=15)
animations = AnimationSequence(
rainbow,
rainbow_chase,
rainbow_comet,
rainbow_sparkle,
advance_interval=3,
auto_clear=False,
random_order=True)
dir_path = "/wav"
wav_files = []
wavs = []
wav_index = 0
for path in os.listdir(dir_path):
if path.endswith('.wav'):
fullpath = dir_path + "/" + path
print('-', fullpath)
wav_files.append(fullpath)
wavs.append( audiocore.WaveFile(open(fullpath, "rb")) )
while True:
animations.animate()
key = keys.events.get()
if key:
print("key", key)
if key.pressed:
print("playing WAV:", wav_files[wav_index])
mixer.voice[0].play( wavs[ wav_index] )
wav_index = (wav_index + 1) % len(wav_files)
@todbot
Copy link
Author

todbot commented Jan 30, 2024

Video demo of the above, with two WAV files in the "/wav" directory.

led_animations_plus_audio.mp4

@todbot
Copy link
Author

todbot commented Jan 31, 2024

Version for Neotrellis M4:

import time, random, os
import board
import keypad
import audiocore, audiomixer, audiomp3
from audioio import AudioOut as AudioOut
import neopixel

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.rainbowsparkle import RainbowSparkle
from adafruit_led_animation.sequence import AnimationSequence

leds = neopixel.NeoPixel(board.NEOPIXEL, 32, brightness=0.01, auto_write=False)

keys = keypad.KeyMatrix( row_pins = [getattr(board, "ROW%d" % n) for n in range(4)],
                         column_pins = [getattr(board, "COL%d" % n) for n in range(8)],
                         columns_to_anodes=False,
                        )

audio = AudioOut(board.A0, right_channel=board.A1)
mixer = audiomixer.Mixer(voice_count=1, sample_rate=22050, channel_count=1,
                         bits_per_sample=16, samples_signed=True)
audio.play(mixer)


rainbow = Rainbow(leds, speed=0.1, period=4)
rainbow_chase = RainbowChase(leds, speed=0.1, size=4, spacing=3)
rainbow_comet = RainbowComet(leds, speed=0.1, tail_length=12, bounce=True)
rainbow_sparkle = RainbowSparkle(leds, speed=0.1, num_sparkles=15)

animations = AnimationSequence(
    rainbow,
    rainbow_chase,
    rainbow_comet,
    rainbow_sparkle,
    advance_interval=3,
    auto_clear=False,
    random_order=True,
)

dir_path = "/wav"
wav_files = []
wavs = []
wav_index = 0

for path in os.listdir(dir_path):
    if path.endswith('.wav'):
        fullpath = dir_path + "/" + path
        print('-', fullpath)
        wav_files.append(fullpath)
        wavs.append( audiocore.WaveFile(open(fullpath, "rb")) )

while True:
    animations.animate()
    if mixer.voice[0].playing == False:
        animations.freeze()
    key = keys.events.get()
    if key:
        print("key", key)
        if key.pressed:
            print("playing WAV:", wav_files[wav_index])
            animations.resume()  # start playing LED animation
            mixer.voice[0].play( wavs[ wav_index]  )
            wav_index = (wav_index + 1) % len(wav_files)

@todbot
Copy link
Author

todbot commented Feb 3, 2024

If you want the LEDs to turn on and animate only while audio is playing, make the while loop look something like this:

while True:
    # only animate LEDs while audio is playing, otherwise turn off LEDS
    if mixer.voice[0].playing == True:
        animations.animate()
    else:
        leds.fill(0x000000)
        leds.show()
    # check if a key has been pressed
    key = keys.events.get()
    if key:
        print("key", key)
        if key.pressed:
            print("playing WAV:", wav_files[wav_index])
            mixer.voice[0].play( wavs[ wav_index]  )
            wav_index = (wav_index + 1) % len(wav_files)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment