Setup Circuit Playground Express with CircuitPython

We'll need to get our board setup so we can run CircuitPython code. Let's walk through these steps to get the latest version of CircuitPython onto your board. 

Quick Start

  • Download the CircuitPython UF2 for Circuit Playground Express
  • Connect Circuit Playground Express to your computer over USB and press the Reset button
  • Drag-n-drop the CircuitPython UF2 onto the CPLAYBOOT drive - the drive will vanish and a new CIRCUITPY drive should appear.
  • Copy code and library files to the CIRCUITPY drive

Download Adafruit CircuitPython Library Bundle

In order to run the code, we'll need to download a library. The download linked below will contain all the libraries available for CircuitPython. To run the code for this project, we only need the Adafruit Circuit Playground library. Unzip the library bundle and search for the library. Drag and drop it onto a folder named lib on the CIRCUITPY drive (create the folder if it is not already on the Circuit Playground Express).

Required Library 

  • Adafruit Circuit Playground – adafruit_circuitplayground

Upload Code

Click on the download link below to grab the main code directly from GitHub. Rename the file to code.py and drop it onto the CIRCUITPY main (root) directory. Create a new folder on the CIRCUITPY drive and name it sounds. Upload the audio files to that folder. The code will run properly when all of the files have been uploaded.

Use any text editor or favorite IDE to modify the code. We suggest using the Mu Python Editor. See below for more on Mu.

Audio Files

The sounds used in this project were sampled from the LEGO movie. This pack contains sounds that are already in the supported audio format.

Adafruit CircuitPython supports 16-bit, Mono, 22.050kHz .wav audio format. See this guide to help format any audio files you might want to use in this project besides the files provided.

Mu Python Editor

Mu is a simple Python editor that works with Adafruit CircuitPython hardware. It's written in Python and works on Windows, MacOS, Linux and Raspberry Pi. The serial console is built right in so you get immediate feedback from your board's serial output!

# Shake Audio Lamp
# for Adafruit Circuit Playground express
# with CircuitPython
import time
import audioio
import board

from adafruit_circuitplayground.express import cpx

# External Audio Stuff
audio = audioio.AudioOut(board.A0)  # Speaker
wave_file = None

def play_wav(name, loop=False):
    """
    Play a WAV file in the 'sounds' directory.
    :param name: partial file name string, complete name will be built around
                 this, e.g. passing 'foo' will play file 'sounds/foo.wav'.
    :param loop: if True, sound will repeat indefinitely (until interrupted
                 by another sound).
    """
    global wave_file  # pylint: disable=global-statement
    print("playing", name)
    if wave_file:
        wave_file.close()
    try:
        wave_file = open('sounds/' + name + '.wav', 'rb') # using wave files from sounds folder
        wave = audioio.WaveFile(wave_file)
        audio.play(wave, loop=loop)
    except OSError:
        pass # we'll just skip playing then

# flash neopixel effects
def party_flash(duration):
    cpx.pixels.fill((255, 255, 255))
    cpx.pixels.show()
    time.sleep(duration)
    cpx.pixels.fill((255, 0, 0))
    cpx.pixels.show()
    time.sleep(duration)

def led_flash(duration):
    cpx.pixels.fill((255, 255, 255))
    cpx.pixels.show()
    time.sleep(duration)
    cpx.pixels.fill((0, 0, 0))
    cpx.pixels.show()
    time.sleep(duration)

# make a counter variable
counter = 0

while True:
    # Listen for shakes
    if cpx.shake(shake_threshold=15): # adjust sensitivity - low number is more sensitive
        print("Shake detected!") # Let us know there was a shake
        counter = counter + 1 # Start a counter
        if counter == 2: # On second shake
            play_wav("awe-a") # play audio
            for _ in range(3): # loop x times
                party_flash(0.4) # neopixel flash
        elif counter == 3: # On third shake
            play_wav("awe-b")
            for _ in range(3): # loop x times
                party_flash(0.4) # neopixel flash
        elif counter == 4: # On fourth shake
            play_wav("awe-c")
            for _ in range(3): # loop x times
                party_flash(0.4) # neopixel flash
        elif counter == 5: # on fifth shake
            counter = 0 # Reset the counter back to zero
            play_wav("untz") #play audio
            for _ in range(3): # loop x times
                led_flash(.18) # faster pixel flash
            cpx.pixels.fill((255,255,255)) # solid pixel
            time.sleep(1) # light it for one second
        else: # On first shake
            play_wav("haha") # play audio
            cpx.pixels.fill((255,255,255)) # white color
            time.sleep(1) # for one second
    else: # When there's no shakyness to be had
        cpx.pixels.fill((0, 0, 0)) # keep pixels off when not shaking

Loop and Play

The play_wav function handles the location of the wav files. In this project, the audio wav files reside in a folder named sounds. The party_flash and led_flash animations use cpx.pixels.fill to quickly flash between two colors.

In the loop, we set the shake sensitivity and print a statement to let us know when a shake is detected. A variable is setup and starts a counter which increments each time a shake has been detected. This way we can play different audio files each time we shake it. In this project, we'll play up to five different wave files.

  • On the first shake, we play haha.wav and turn all NeoPixels white for one second. 
  • One second shake, we play awe-a.wav and run party_flash 3 times, 0.4 seconds each flash.
  • On third shake, we play awe-b.wav and run part_flash 3 times, 0.4 seconds each flash.
  • On fourth sake, we play awe-c.wav and run the part_flash 3 times, 0.4 seconds each flash.
  • On fifth sake, we set the counter to 0, play untz.wav and run led_flash 3 times, 0.18 seconds each flash.

Customization Options

Minor adjustments can be made to customize the functionality. Change the colors of the NeoPixels by adding your own values, just look for the RGB numbers in the code. If you want the lights to always stay on, look for the last line that uses cpx.pixels.fill and adjust the RGB values. Rearrange the animations and adjust the timing to match your audio files.

This guide was first published on Sep 25, 2019. It was last updated on Sep 25, 2019. This page (Code) was last updated on Oct 14, 2019.