This code uses the Adafruit BlueFruit app's Control Pad and Color Picker features. The Color Picker will send a solid color to the lanyard, and the Control Pad will allow you to choose between four different customizable color gradient animations. You can also speed up and slow down the animations to get just the look you want.
We need to do a bit of setup to get the Feather working with CircuitPython. Here's what's on this page:
- Install the latest version of CircuitPython on the board
- Install the necessary CircuitPython libraries
- Copy and update the Python code
- Save the code to your Feather
Ready to start? Here we go!
Install CircuitPython
This guide tells you all you need to know about CircuitPython:
https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython
For now, I'll just cherry-pick the necessaries, but be sure to read through the guide to get all the nitty gritty details and troubleshooting tips.
Scroll down until you find the Feather nRF52840 board and click on it. Then click Download for the latest release. A file will download to your computer with a file extension of uf2.
Plug your Feather into your computer with a known good data+power USB cable.
Double-click the Reset button next to the USB connector on your board (green arrow), and you will see the NeoPixel RGB LED turn green (identified by the red arrow in the image). If the LED turns red, check the USB cable, try another USB port, etc. Note: The little red LED next to the USB connector will pulse red. That's ok!
If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!
When it happens correctly, you will see a new disk drive appear called FTHR840BOOT.
Drag the file you just downloaded onto this drive to install CircuitPython. The disk drive name FTHR840BOOT will magically change to read CIRCUITPY.
Note: if you don't see FTHR840BOOT, but instead see a drive called CIRCUITPY, that means CircuitPython is already installed. You probably want to follow the instructions to update CircuitPython to the latest version - this project requires at least version 5.0.0-beta.0 or higher.
Install Libraries
Now we need to install a few libraries onto our board as well. Here's a guide that tells you all you'll ever want to know about installing libraries:
https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries
I'll just hit the highlights again to get you up and running.
The above button takes you to a page where you can download the latest library release. Click the big purple button to do so.
Now go to your CIRCUITPY drive and create a new folder called lib. Unzip the Library bundle and find:
- adafruit_ble
- adafruit_bluefruit_connect
- adafruit_fancyled
- neopixel.mpy
Drag these three folders/files into your brand new lib folder.
Upload the Code
The last thing we need to add is a file called code.py on the CIRCUITPY drive. This is where the Feather will look for actual instructions on what to do. Copy the code below into a text or code editor -- we recommend the Mu editor which can be downloaded here.
# SPDX-FileCopyrightText: 2019 Phillip Burgess for Adafruit Industries # SPDX-FileCopyrightText: 2019 Dan Halbert for Adafruit Industries # SPDX-FileCopyrightText: 2019 Erin St Blaine for Adafruit Industries # # SPDX-License-Identifier: MIT """ FancyLED Palette and Color Picker Control with BlueFruit App Code by Phil Burgess, Dan Halbert & Erin St Blaine for Adafruit Industries """ import board import neopixel import adafruit_fancyled.adafruit_fancyled as fancy from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService from adafruit_bluefruit_connect.packet import Packet from adafruit_bluefruit_connect.button_packet import ButtonPacket from adafruit_bluefruit_connect.color_packet import ColorPacket NUM_LEDS = 60 # change to reflect your LED strip NEOPIXEL_PIN = board.D13 # change to reflect your wiring # Palettes can have any number of elements in various formats # check https://learn.adafruit.com/fancyled-library-for-circuitpython/colors # for more info # Declare a 6-element RGB rainbow palette PALETTE_RAINBOW = [fancy.CRGB(1.0, 0.0, 0.0), # Red fancy.CRGB(0.5, 0.5, 0.0), # Yellow fancy.CRGB(0.0, 1.0, 0.0), # Green fancy.CRGB(0.0, 0.5, 0.5), # Cyan fancy.CRGB(0.0, 0.0, 1.0), # Blue fancy.CRGB(0.5, 0.0, 0.5)] # Magenta # Declare a Purple Gradient palette PALETTE_GRADIENT = [fancy.CRGB(160, 0, 141), # Purples fancy.CRGB(77, 0, 160), fancy.CRGB(124, 0, 255), fancy.CRGB(0, 68, 214)] # Declare a FIRE palette PALETTE_FIRE = [fancy.CRGB(0, 0, 0), # Black fancy.CHSV(1.0), # Red fancy.CRGB(1.0, 1.0, 0.0), # Yellow 0xFFFFFF] # White # Declare a Water Colors palette PALETTE_WATER = [fancy.CRGB(0, 214, 214), # blues and cyans fancy.CRGB(0, 92, 160), fancy.CRGB(0, 123, 255), fancy.CRGB(0, 68, 214)] # Declare a NeoPixel object on NEOPIXEL_PIN with NUM_LEDS pixels, # no auto-write. # Set brightness to max because we'll be using FancyLED's brightness control. pixels = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_LEDS, brightness=1.0, auto_write=False) offset = 0 # Positional offset into color palette to get it to 'spin' offset_increment = 1 OFFSET_MAX = 1000000 ble = BLERadio() uart_service = UARTService() advertisement = ProvideServicesAdvertisement(uart_service) def set_palette(palette): for i in range(NUM_LEDS): # Load each pixel's color from the palette using an offset, run it # through the gamma function, pack RGB value and assign to pixel. color = fancy.palette_lookup(palette, (offset + i) / NUM_LEDS) color = fancy.gamma_adjust(color, brightness=0.25) pixels[i] = color.pack() pixels.show() # set initial palette to run on startup palette_choice = PALETTE_RAINBOW # True if cycling a palette cycling = True while True: # Advertise when not connected. ble.start_advertising(advertisement) while not ble.connected: if cycling: set_palette(palette_choice) offset = (offset + offset_increment) % OFFSET_MAX # Now we're connected while ble.connected: if uart_service.in_waiting: packet = Packet.from_stream(uart_service) if isinstance(packet, ColorPacket): cycling = False # Set all the pixels to one color and stay there. pixels.fill(packet.color) pixels.show() elif isinstance(packet, ButtonPacket): cycling = True if packet.pressed: if packet.button == ButtonPacket.BUTTON_1: palette_choice = PALETTE_RAINBOW elif packet.button == ButtonPacket.BUTTON_2: palette_choice = PALETTE_GRADIENT elif packet.button == ButtonPacket.BUTTON_3: palette_choice = PALETTE_FIRE elif packet.button == ButtonPacket.BUTTON_4: palette_choice = PALETTE_WATER # change the speed of the animation by incrementing offset elif packet.button == ButtonPacket.UP: offset_increment += 1 elif packet.button == ButtonPacket.DOWN: offset_increment -= 1 if cycling: offset = (offset + offset_increment) % OFFSET_MAX set_palette(palette_choice)
Once you've got the code in your editor, look near the top and find this line:
pixel = neopixel.NeoPixel(board.D13, 60)
If you soldered to a pin other than pin 13, change D13 to reflect the correct pin. The last number (60) tells the board how many NeoPixels we have. If you have more or less than 60, change this number to reflect your actual setup.
Customizing Palettes
I've added four different color palettes for the animations accessed from the Control Pad: a rainbow, a purple gradient, a "fire" and a "water" palette. You can customize these fairly easily in the code. The power of the FancyLED library allows you so much control when it comes to choosing custom colors and animating them smoothly.
Find the palette definitions in the code:
# Declare a 6-element RGB rainbow palette PALETTE_RAINBOW = [fancy.CRGB(1.0, 0.0, 0.0), # Red fancy.CRGB(0.5, 0.5, 0.0), # Yellow fancy.CRGB(0.0, 1.0, 0.0), # Green fancy.CRGB(0.0, 0.5, 0.5), # Cyan fancy.CRGB(0.0, 0.0, 1.0), # Blue fancy.CRGB(0.5, 0.0, 0.5)] # Magenta # Declare a Purple Gradient palette PALETTE_GRADIENT = [fancy.CRGB(160, 0, 141), # Purples fancy.CRGB(77, 0, 160), fancy.CRGB(124, 0, 255), fancy.CRGB(0, 68, 214)] # Declare a FIRE palette PALETTE_FIRE = [fancy.CRGB(0, 0, 0), # Black fancy.CHSV(1.0), # Red fancy.CRGB(1.0, 1.0, 0.0), # Yellow 0xFFFFFF] # White # Declare a Water Colors palette PALETTE_WATER = [fancy.CRGB(0, 214, 214), # blues and cyans fancy.CRGB(0, 92, 160), fancy.CRGB(0, 123, 255), fancy.CRGB(0, 68, 214)]
You can use CRGB values or CHSV values to choose colors, or use them both at the same time. There are also multiple ways to declare values and a lot of control over how spread out the gradients can be.
This is explained in detail in the FancyLED guide so take a look to find out all you need to know about creating your own custom color palettes.
Text editor powered by tinymce.