Once you've finished setting up your Feather RP2040 with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: 2017 John Park for Adafruit Industries # Modified 2023 by Erin St Blaine # # SPDX-License-Identifier: MIT import board import pulseio import neopixel import adafruit_irremote from rainbowio import colorwheel from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.animation.solid import Solid from adafruit_led_animation.animation.rainbow import Rainbow from adafruit_led_animation.animation.sparkle import Sparkle 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.animation.pulse import Pulse from adafruit_led_animation.animation.SparklePulse import SparklePulse import adafruit_led_animation.color as color NUMBER_OF_PIXELS = 85 pixels = neopixel.NeoPixel(board.D13, NUMBER_OF_PIXELS) # Define the brightness levels and their corresponding values # Start at a non-blinding brightness. BRIGHTNESS_LEVELS = (0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.7, 0.8, 1.0) brightness_index = 2 pixels.brightness = BRIGHTNESS_LEVELS[brightness_index] pulsein = pulseio.PulseIn(board.A0, maxlen=120, idle_state=True) decoder = adafruit_irremote.GenericDecode() SPEEDS = (0.25, 0.125, 0.1, 0.08, 0.05, 0.02, 0.01) # Customize speed levels here speed_index = 4 def setup_animations(): """Set up all the available animations.""" # Animation Setup rainbow = Rainbow(pixels, speed=SPEEDS[speed_index], period=2, name="rainbow", step=3) sparkle = Sparkle(pixels, speed=SPEEDS[speed_index], color=color.WHITE, name="sparkle") solid = Solid(pixels, color=colorwheel(0), name="solid") # Make the Solid animation changeable quickly. solid.speed = 0.01 off = Solid(pixels, color=color.BLACK, name="off") rainbow = Rainbow(pixels, speed=SPEEDS[speed_index], period=6, name="rainbow", step=2.4) rainbow_carousel = RainbowChase(pixels, speed=SPEEDS[speed_index], size=4, spacing=1, step=20) party_chase = RainbowChase(pixels, speed=SPEEDS[speed_index], size=1, spacing=5, step=6) rainbow_chase2 = RainbowChase(pixels, speed=SPEEDS[speed_index], size=10, spacing=1, step=18) chase = Chase(pixels, speed=SPEEDS[speed_index], color=color.RED, size=1, spacing=6) rainbow_comet2 = RainbowComet( pixels, speed=0.02, tail_length=104, colorwheel_offset=80, bounce=False) rainbow_comet3 = RainbowComet( pixels, speed=SPEEDS[speed_index], tail_length=25, colorwheel_offset=128, step=4, bounce=False) lava = Comet(pixels, speed=SPEEDS[speed_index], color=color.ORANGE, tail_length=40, bounce=False) sparkle1 = Sparkle(pixels, speed=SPEEDS[speed_index], color=color.BLUE, num_sparkles=10) pulse = Pulse(pixels, speed=0.1, color=color.AMBER, period=3) sparkle_pulse = SparklePulse(pixels, speed=0.05, period=2, color=color.JADE, max_intensity=3) # Animation Sequence Playlist -- rearrange to change the order of animations # advance_interval is None, so the animations change only under user control. all_animations = AnimationSequence( rainbow, rainbow_chase2, rainbow_carousel, party_chase, rainbow_comet2, rainbow_comet3, sparkle_pulse, pulse, chase, rainbow, solid, sparkle, lava, sparkle1, off, auto_clear=True, auto_reset=True, advance_interval=None, ) return all_animations # IR Remote Mapping for the Adafruit mini IR remote # https://www.adafruit.com/product/389 CMD_1 = 247 # 1: [255, 2, 247, 8] CMD_2 = 119 # 2: [255, 2, 119, 136] CMD_3 = 183 # 3: [255, 2, 183, 72] CMD_4 = 215 # 4: [255, 2, 215, 40] CMD_5 = 87 # 5: [255, 2, 87, 168] CMD_6 = 151 # 6: [255, 2, 151, 104] CMD_7 = 231 # 7: [255, 2, 231, 24] CMD_8 = 103 # 8: [255, 2, 103, 152] CMD_9 = 167 # 9: [255, 2, 167, 88] CMD_0 = 207 # 0: [255, 2, 207, 48] CMD_UP = 95 # ^ : [255, 2, 95, 160] CMD_DOWN = 79 # v : [255, 2, 79, 176] CMD_RIGHT = 175 # > : [255, 2, 175, 80] CMD_LEFT = 239 # < : [255, 2, 239, 16] CMD_ENTER_SAVE = 111 # Enter/Save: [255, 2, 111, 144] CMD_SETUP = 223 # Setup: [255, 2, 223, 32] CMD_STOP_MODE = 159 # Stop/Mode: [255, 2, 159, 96] CMD_BACK = 143 # Back: [255, 2, 143, 112] CMD_VOL_DOWN = 255 # Vol - : [255, 2, 255, 0] CMD_VOL_UP = 191 # Vol + : [255, 2, 191, 64] CMD_PLAY_PAUSE = 127 # Play/Pause: [255, 2, 127, 128] CMD_REPEAT = True # short code: repeat of previous command def read_command(): """Try to read an IR command. If none seen or if error, return None.""" try: pulses = decoder.read_pulses(pulsein, blocking=False) if pulses: code = decoder.decode_bits(pulses) if len(code) > 3: print("Decoded:", code) return code[2] # if code is less than or equal to 3 characters long or no pulses received return None except adafruit_irremote.IRNECRepeatException: # unusual short code! print("NEC repeat!") return CMD_REPEAT except adafruit_irremote.IRDecodeException as e: # failed to decode print("Failed to decode:", e) return None except MemoryError as e: print("Memory error: ", e) return None SOLID_COLORS = { CMD_0 : color.BLACK, CMD_1 : color.RED, CMD_2 : color.GREEN, CMD_3 : color.WHITE, CMD_4 : color.BLUE, CMD_5 : color.PINK, CMD_6 : color.YELLOW, CMD_7 : color.PURPLE, CMD_8 : color.TEAL, CMD_9 : color.ORANGE, } # main program animations = setup_animations() last_command = None while True: command = read_command() if command is None: # Nothing read, just keep animating. animations.animate() # Run one animation cycle. continue if command == CMD_REPEAT: command = last_command last_command = command print("Command", command) # See if the command was a number button. Fetch the animation color if it is. solid_color = SOLID_COLORS.get(command, None) if solid_color: # Jump to the "solid" animation. Set its color to # the chosen color. animations.activate("solid") animations.current_animation.color = solid_color elif command == CMD_LEFT: animations.previous() elif command == CMD_RIGHT: animations.next() elif command == CMD_DOWN: # Slow down current animation if speed_index > 0: speed_index -= 1 animations.current_animation.speed = SPEEDS[speed_index] print("speed of current animation is now:", animations.current_animation.speed) elif command == CMD_UP: if speed_index < len(SPEEDS) - 1: speed_index += 1 animations.current_animation.speed = SPEEDS[speed_index] print("speed of current animation is now:", animations.current_animation.speed) elif command == CMD_VOL_DOWN: if brightness_index > 0: brightness_index -= 1 pixels.brightness = BRIGHTNESS_LEVELS[brightness_index] print("brightness:", pixels.brightness) elif command == CMD_VOL_UP: if brightness_index < len(BRIGHTNESS_LEVELS) - 1: brightness_index += 1 pixels.brightness = BRIGHTNESS_LEVELS[brightness_index] print("brightness:", pixels.brightness)
Upload the Code and Libraries to the Feather RP2040
After downloading the Project Bundle, plug your Feather RP2040 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather RP2040's CIRCUITPY drive.
- lib folder
- code.py
Your Feather RP2040 CIRCUITPY drive should look like this after copying the lib folder and the code.py file.

How the CircuitPython Code Works
First, we import all the necessary libraries and animations we'll be using.
Check out the CircuitPython LED Animations Library guide for more info on adding your own animations.
import board import pulseio import neopixel import adafruit_irremote from rainbowio import colorwheel from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.animation.solid import Solid from adafruit_led_animation.animation.rainbow import Rainbow from adafruit_led_animation.animation.sparkle import Sparkle 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.animation.pulse import Pulse from adafruit_led_animation.animation.SparklePulse import SparklePulse import adafruit_led_animation.color as color
NeoPixel Setup
Set your total number of pixels here. If you soldered to a different pin than 13, you can change the pin number here as well.
NUMBER_OF_PIXELS = 85 pixels = neopixel.NeoPixel(board.D13, NUMBER_OF_PIXELS)
Speed & Brightness Control
This code includes 8 brightness levels and 7 speed levels, which can be selected with buttons on the IR remote. You can edit them, add or subtract here.
# Define the brightness levels and their corresponding values # Start at a non-blinding brightness. BRIGHTNESS_LEVELS = (0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.7, 0.8, 1.0) brightness_index = 2 pixels.brightness = BRIGHTNESS_LEVELS[brightness_index] pulsein = pulseio.PulseIn(board.A0, maxlen=120, idle_state=True) decoder = adafruit_irremote.GenericDecode() SPEEDS = (0.25, 0.125, 0.1, 0.08, 0.05, 0.02, 0.01) # Customize speed levels here speed_index = 4
Animations
Here is where you set up and define your animations. You can edit colors, spacing, and lots of other variables until the animations do exactly what you want.
Pressing the left and right arrow keys will cycle through the animations in this list. You can add, subtract, or reorder them so the animations appear in the order you want.
def setup_animations(): """Set up all the available animations.""" # Animation Setup rainbow = Rainbow(pixels, speed=SPEEDS[speed_index], period=2, name="rainbow", step=3) sparkle = Sparkle(pixels, speed=SPEEDS[speed_index], color=color.WHITE, name="sparkle") solid = Solid(pixels, color=colorwheel(0), name="solid") # Make the Solid animation changeable quickly. solid.speed = 0.01 off = Solid(pixels, color=color.BLACK, name="off") rainbow = Rainbow(pixels, speed=SPEEDS[speed_index], period=6, name="rainbow", step=2.4) rainbow_carousel = RainbowChase(pixels, speed=SPEEDS[speed_index], size=4, spacing=1, step=20) party_chase = RainbowChase(pixels, speed=SPEEDS[speed_index], size=1, spacing=5, step=6) rainbow_chase2 = RainbowChase(pixels, speed=SPEEDS[speed_index], size=10, spacing=1, step=18) chase = Chase(pixels, speed=SPEEDS[speed_index], color=color.RED, size=1, spacing=6) rainbow_comet2 = RainbowComet( pixels, speed=0.02, tail_length=104, colorwheel_offset=80, bounce=False) rainbow_comet3 = RainbowComet( pixels, speed=SPEEDS[speed_index], tail_length=25, colorwheel_offset=128, step=4, bounce=False) lava = Comet(pixels, speed=SPEEDS[speed_index], color=color.ORANGE, tail_length=40, bounce=False) sparkle1 = Sparkle(pixels, speed=SPEEDS[speed_index], color=color.BLUE, num_sparkles=10) pulse = Pulse(pixels, speed=0.1, color=color.AMBER, period=3) sparkle_pulse = SparklePulse(pixels, speed=0.05, period=2, color=color.JADE, max_intensity=3) # Animation Sequence Playlist -- rearrange to change the order of animations # advance_interval is None, so the animations change only under user control. all_animations = AnimationSequence( rainbow, rainbow_chase2, rainbow_carousel, party_chase, rainbow_comet2, rainbow_comet3, sparkle_pulse, pulse, chase, rainbow, solid, sparkle, lava, sparkle1, off, auto_clear=True, auto_reset=True, advance_interval=None, ) return all_animations
IR Mapping
The next section deals with mapping the button keys using the Adafruit IR remote. If you want to use a different remote, change the codes to match your remote here.
CMD_1 = 247 # 1: [255, 2, 247, 8] CMD_2 = 119 # 2: [255, 2, 119, 136] CMD_3 = 183 # 3: [255, 2, 183, 72] CMD_4 = 215 # 4: [255, 2, 215, 40] CMD_5 = 87 # 5: [255, 2, 87, 168] CMD_6 = 151 # 6: [255, 2, 151, 104] CMD_7 = 231 # 7: [255, 2, 231, 24] CMD_8 = 103 # 8: [255, 2, 103, 152] CMD_9 = 167 # 9: [255, 2, 167, 88] CMD_0 = 207 # 0: [255, 2, 207, 48] CMD_UP = 95 # ^ : [255, 2, 95, 160] CMD_DOWN = 79 # v : [255, 2, 79, 176] CMD_RIGHT = 175 # > : [255, 2, 175, 80] CMD_LEFT = 239 # < : [255, 2, 239, 16] CMD_ENTER_SAVE = 111 # Enter/Save: [255, 2, 111, 144] CMD_SETUP = 223 # Setup: [255, 2, 223, 32] CMD_STOP_MODE = 159 # Stop/Mode: [255, 2, 159, 96] CMD_BACK = 143 # Back: [255, 2, 143, 112] CMD_VOL_DOWN = 255 # Vol - : [255, 2, 255, 0] CMD_VOL_UP = 191 # Vol + : [255, 2, 191, 64] CMD_PLAY_PAUSE = 127 # Play/Pause: [255, 2, 127, 128] CMD_REPEAT = True # short code: repeat of previous command
Solid Color Keys
The 0-9 buttons will select solid colors from the rainbow, with 0 as "black", which will turn the LEDs off. You can edit the colors, or assign different animations to the buttons by editing this code.
SOLID_COLORS = { CMD_0 : color.BLACK, CMD_1 : color.RED, CMD_2 : color.GREEN, CMD_3 : color.WHITE, CMD_4 : color.BLUE, CMD_5 : color.PINK, CMD_6 : color.YELLOW, CMD_7 : color.PURPLE, CMD_8 : color.TEAL, CMD_9 : color.ORANGE, }
Main Loop
The main loop starts with the while True:
line. First, the code checks to see if a button has been pressed. If you open the serial monitor and press some buttons on the remote, you'll see a readout of which code is being transmitted.
Finally, the code tells the NeoPixels how to behave when a button is pressed. This is the part you'll edit if you want to customize your button layout.
# if control mode is 0.. # control the volume of the white noise if ctrl_mode == 0: # encoder neopixel is blue pixel0.fill(BLUE) # if the encoder moves.. if pos0 != last_pos0: # if you increase the encoder # increase value by 0.1 # maxed out at 1 if pos0 > last_pos0: volume = volume + 0.1 if volume > 1: volume = 1 # if you decrease # decrease value by 0.1 # minimum value of 0 if pos0 < last_pos0: volume = volume - 0.1 if volume < 0: volume = 0 print(volume) # reset the position last_pos0 = pos0
Page last edited January 22, 2025
Text editor powered by tinymce.