It’s natural to dwell on the visual elements of a costume. Consider for a moment though…the surprise of using other senses…sound, in this case…can provide a boost for a quickly-assembled outfit, or something that outwardly resembles conventional dress.

Here’s a mini-project that shows HalloWing being used like a Star Trek communicator badge, or to make video game sounds any time you jump (or both, if you really want to confuse people).

This small 8-Ohm speaker is included in Adabox 009 or is available separately. It features a tiny “PicoBlade” connector that plugs straight into Hallowing. You can use other small speakers but may need to solder wires directly to pads on the board.

 

There’s a tiny volume dial on HalloWing that can be adjusted with a screwdriver.

Our code uses CircuitPython because it’s super easy to customize for different sounds or graphics.

If you’ve overwritten CircuitPython on your HalloWing board with another project (such as the eye or Minotaur Maze), it’s easy to get it back. Follow the steps in this guide to get the standard CircuitPython firmware onto your board.

This project requires CircuitPython 4.0 or higher for loading BMP images (sound will work with 3.0 or higher) version of CircuitPython. Setup directions are the same as shown in that guide, only the .UF2 file is different:

Here’s the code we’ll be using. Click “Download Project Bundle” to download a ZIP file with this code and the project’s graphics and sound files and required libraries. After uncompressing, navigate to the folder matching your CircuitPython version, and copy all of the files (and the “lib” folder) to the root directory of the CIRCUITPY drive (i.e. not inside a folder…just straight to the drive).

# SPDX-FileCopyrightText: 2018 Phillip Burgess for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
Jump & touch sound example for Adafruit Hallowing. Plays different sounds
in response to jumping and capacitive touch pads.
"""

import time
import board
import digitalio
import displayio
import audioio
import audiocore
import touchio
import neopixel

def load_wav(name):
    """
    Load a WAV audio file into RAM.
    @param name: partial file name string, complete name will be built on
                 this, e.g. passing 'foo' will load file 'foo.wav'.
    @return WAV buffer that can be passed to play_wav() below.
    """
    return audiocore.WaveFile(open(name + '.wav', 'rb'))

def play_wav(wav):
    """
    Play a WAV file previously loaded with load_wav(). This function
    "blocks," i.e. does not return until the sound is finished playing.
    @param wav: WAV buffer previously returned by load_wav() function.
    """
    AUDIO.play(wav)      # Begin WAV playback
    while AUDIO.playing: # Keep idle here as long as it plays
        pass
    time.sleep(1)        # A small pause avoids repeated triggering

TOUCH_WAV = load_wav('touch') # WAV file to play when capacitive pads touched
JUMP_WAV = load_wav('jump')   # WAV file to play when jumping
JUMP_THRESHOLD = 4.0          # Higher number = triggers more easily
IMAGEFILE = 'mario.bmp'       # BMP image to display

IS_HALLOWING_M4 = False

# Perform a couple extra steps for the HalloWing M4
try:
    if getattr(board, "CAP_PIN"):
        IS_HALLOWING_M4 = True
        # Create digitalio objects and pull low for HalloWing M4
        cap_pin = digitalio.DigitalInOut(board.CAP_PIN)
        cap_pin.direction = digitalio.Direction.OUTPUT
        cap_pin.value = False
    if getattr(board, "SPEAKER_ENABLE"):
        # Enable the Speaker
        speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
        speaker_enable.direction = digitalio.Direction.OUTPUT
        speaker_enable.value = True
except AttributeError:
    pass

AUDIO = audioio.AudioOut(board.SPEAKER)  # Speaker

try:
    board.DISPLAY.auto_brightness = False
except AttributeError:
    pass
TOUCH1 = touchio.TouchIn(board.TOUCH1)  # Capacitive touch pads
TOUCH2 = touchio.TouchIn(board.TOUCH2)
TOUCH3 = touchio.TouchIn(board.TOUCH3)
TOUCH4 = touchio.TouchIn(board.TOUCH4)

# Set up accelerometer on I2C bus, 4G range:
i2c = board.I2C()  # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
if IS_HALLOWING_M4:
    import adafruit_msa301
    ACCEL = adafruit_msa301.MSA301(i2c)
else:
    import adafruit_lis3dh
    try:
        ACCEL = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x18) # Production board
    except ValueError:
        ACCEL = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19) # Beta hardware
    ACCEL.range = adafruit_lis3dh.RANGE_4_G

try:
    board.DISPLAY.brightness = 0
    SCREEN = displayio.Group()
    board.DISPLAY.show(SCREEN)

    # CircuitPython 6 & 7 compatible
    BITMAP = displayio.OnDiskBitmap(open(IMAGEFILE, 'rb'))
    TILEGRID = displayio.TileGrid(
        BITMAP,
        pixel_shader=getattr(BITMAP, 'pixel_shader', displayio.ColorConverter())
    )

    # # CircuitPython 7+ compatible
    # BITMAP = displayio.OnDiskBitmap(IMAGEFILE)
    # TILEGRID = displayio.TileGrid(BITMAP, pixel_shader=BITMAP.pixel_shader)

    SCREEN.append(TILEGRID)
    board.DISPLAY.brightness = 1.0   # Turn on display backlight
except (OSError, ValueError):
    pass

# If everything has initialized correctly, turn off the onboard NeoPixel:
PIXEL = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0)
PIXEL.show()

while True:
    # No freefall detect in LIS3DH library, but it's easily done manually...
    # poll the accelerometer and look for near-zero readings on all axes.
    X, Y, Z = ACCEL.acceleration
    A2 = X * X + Y * Y + Z * Z  # Acceleration^2 in 3space (no need for sqrt)
    if A2 < JUMP_THRESHOLD:
        # Freefall (or very close to it) detected, play a sound:
        play_wav(JUMP_WAV)
    elif TOUCH1.value or TOUCH2.value or TOUCH3.value or TOUCH4.value:
        # One of the capacitive pads was touched, play other sound:
        play_wav(TOUCH_WAV)

With the speaker, code and sound/graphics files all correctly installed, you’ll see it does two (or three) things:

  • When any of the capacitive pads (skull teeth) are touched, it emits a chirp sound like a Star Trek communicator. Add a magnet or pin back, don a red shirt and black slacks, and ask your host for tea, Earl Grey, hot.
  • If you jump while holding HalloWing (or hidden in a pocket or worn on a lanyard), it will make video game jumping sounds … perhaps you have some overalls and a hat? Telling everyone “IT’S A ME!” never gets tired.
  • If using a recent version of CircuitPython (4.0.0-alpha1 or later), the Hallowing display can show images … easily switched to other themes if you’d like.

This guide was first published on Oct 02, 2018. It was last updated on Oct 02, 2018.

This page (Making a Costume of Sound and Motion) was last updated on Mar 28, 2023.

Text editor powered by tinymce.