Switch Accessible Board Game
by devincej in Circuits > Assistive Tech
378 Views, 2 Favorites, 0 Comments
Switch Accessible Board Game
This is a way to make a one player board game controlled by an adaptive switch. As the player toggles the switch LEDs along the path will light up and play messages along the way. I used CandyLand but you could use any board game with spaces on it. The whole project is built using CircuitPython on a CircuitPlayground Bluefruit.
Supplies
- CircuitPlayground Bluefruit
- A battery pack
- LED strands (I used 3 strands of 20)
- A wire to connect them to the CPB
- An adaptive switch that connects to a mono jack
- Mono jack female to bare wire cables
- A board game
- Velcro tape
- A speaker (optional)
- A casing for the game (optional)
- Tools:
- Hot glue gun
- Screwdriver (or drill; anything to punch holes in the board)
- A soldering iron (also optional, I used to cut holes in the acrylic)
Attach Wires to CPB
The first step is to wire up the microcontroller. You can connect it differently and change the code but here's the connections I used:
- Speaker Mono Jack:
- Black to GND
- Red to AUDIO
- Adaptive Switch Mono Jack:
- Black to GND
- Red to A4
- LED Strand (You'll need to figure out which of the three wires are which, the middle should be signal)
- Red to VOUT
- Black to GND
- Signal to A6
Cut Pieces for the Housing
I chose to make an acrylic housing for the board game and the electronics. I used MakerCase to design my box then used a laser cutter to cut the pieces out. I used 1/8" thick acrylic material: pink on the sides and bottom and clear for the top.
Glue Together the Box
Next, using the hot glue gun glue together the bottom piece and the sides. Leave the clear top piece aside for now.
Cut Holes in the Box
To allow the speaker and adaptive switch to be easily swapped out I cut 2 holes at the bottom of the box. I also cut a third hole in the side so the battery pack could stay on the outside. I attempted using a drill press to cut the holes, but it kept shattering the acrylic. I ended up using the soldering iron (850°F) to puncture holes in the side. I used my college's makerspace which had hoods available, but if you're trying this at home you should make sure you either wear a mask or have some form of ventilation (or both). If your iron isn't wide enough just keep drawing circular motions around the hole to remove more acrylic until it's wide enough (it might take a couple minutes).
Cut Holes in the Board Game
Next, poke holes through the spaces of your board game that you want the lights to be in. CandyLand has 134 spaces so I opted to just go every 5 spaces or so (I avoided the fold of the board). I used a screwdriver to poke a primary hole then a drill, which wasn't the best method as I had to cut a lot of cardboard out to make it look more presentable. A drill press might've worked better, but anything capable of poking a hole through the board would work. I poked a couple of holes around the castle at the end as well.
Glue LED Strand to Board
Now, flip the board over and start gluing the individual LEDs to the back of the board. Make sure the light will be facing out and that you're going in the right order and direction so the code will be easier to use.
Write/Test Code
If you're copying these instructions directly you can just use the code in the next step, but otherwise you could modify it to fit your needs or even write your own. Make sure to test the code a couple times to ensure that it works before you close up the box.
Code
import board, neopixel, time, digitalio, random
from adafruit_debouncer import Debouncer
from audiopwmio import PWMAudioOut as AudioOut
from audiocore import WaveFile
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.animation.pulse import Pulse
from adafruit_led_animation.animation.SparklePulse import SparklePulse
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.color import (
AMBER, #(255, 100, 0)
AQUA, # (50, 255, 255)
BLACK, #OFF (0, 0, 0)
BLUE, # (0, 0, 255)
CYAN, # (0, 255, 255)
GOLD, # (255, 222, 30)
GREEN, # (0, 255, 0)
JADE, # (0, 255, 40)
MAGENTA, #(255, 0, 20)
OLD_LACE, # (253, 245, 230)
ORANGE, # (255, 40, 0)
PINK, # (242, 90, 255)
PURPLE, # (180, 0, 255)
RED, # (255, 0, 0)
TEAL, # (0, 255, 120)
WHITE, # (255, 255, 255)
YELLOW, # (255, 150, 0)
RAINBOW # a list of colors to cycle through
# RAINBOW is RED, ORANGE, YELLOW, GREEN, BLUE, and PURPLE ((255, 0, 0), (255, 40, 0), (255, 150, 0), (0, 255, 0), (0, 0, 255), (180, 0, 255))
)
INDIGO = (63, 0, 255)
VIOLET = (127, 0, 255)
atcolors = [ORANGE, RED, TEAL, JADE, YELLOW, GREEN, INDIGO, VIOLET, AQUA, BLUE, CYAN, PINK, GOLD, PURPLE]
colors = [RED, MAGENTA, ORANGE, YELLOW, GREEN, JADE, BLUE, INDIGO, VIOLET, PURPLE]
strand_pin = board.A6
strand_n_of_lights = 60
strand = neopixel.NeoPixel(strand_pin, strand_n_of_lights, brightness = 1.0, auto_write = True)
strand.fill(BLACK)
button_input = digitalio.DigitalInOut(board.A4)
button_input.switch_to_input(pull=digitalio.Pull.UP)
button = Debouncer(button_input)
speaker = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker.direction = digitalio.Direction.OUTPUT
speaker.value = True
audio = AudioOut(board.SPEAKER)
def play_sound(filename):
with open(filename, "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
pass
#animation, maybe make so there are different functions for different animations
def rand_colors():
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
color = (r, g, b)
strand_loca = random.randint(0, strand_n_of_lights-1)
strand[strand_loca] = color
time.sleep(0.01)
def outer_rand_colors():
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
crandom = (r, g, b)
strand_loca = random.randint(33, strand_n_of_lights-1)
strand[strand_loca] = crandom
time.sleep(0.01)
def q1_func(): #Plays sound and plays lights
with open("1.wav", "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
outer_rand_colors()
strand[32:strand_n_of_lights] = BLACK * (strand_n_of_lights - 32)
def half_func():
with open("2.wav", "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
outer_rand_colors()
strand[32:strand_n_of_lights] = BLACK * (strand_n_of_lights - 32)
def q3_func():
with open("3.wav", "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
outer_rand_colors()
strand[32:strand_n_of_lights] = BLACK * (strand_n_of_lights - 32)
def full_rainbow(): #Lights the full board up the colors of the rainbow in order
x = 0
strand.fill(BLACK)
while x <= 32:
for l in range(len(colors)-1):
strand[x] = colors[l]
time.sleep(0.05)
x += 1
def castle_lights():
x = 27
while x <= 32: #Optional, lights up the castle at the end on my board
for l in range(32-27):
strand[x] = colors[l]
time.sleep(0.05)
x += 1
def castle():
with open("4.wav", "rb") as wave_file:
wave = WaveFile(wave_file)
audio.play(wave)
while audio.playing:
castle_lights()
strand[27:strand_n_of_lights] = BLACK * (strand_n_of_lights-27)
def celebration(): #The celebration function which plays at the end of the game
castle()
play_sound("5.wav")
full_rainbow()
full_rainbow()
full_rainbow()
end = time.time() + 10 #How many seconds you want the random colors to go off for
while time.time() <= end:
rand_colors()
strand.fill(BLACK) #Turns off all the lights; "resets" board so you can start over
i = -1 #A counter for LED index
j = 0 #A counter for color list index
num_of_spaces = 27 #The number of lights in spaces
q1 = num_of_spaces * .25 #1/4 of the way
q2 = num_of_spaces * .5 #Halfway
q3 = num_of_spaces * .75 #3/4 of the way
mess1_dummy = False #Dummies to make sure the mid game celebrations only go off once
mess2_dummy = False
mess3_dummy = False
while True: #The main loop, will restart unless disconnected from power or halted
if i >= 0:
strand[i] = atcolors[color]
button.update()
if button.fell:
i += 1 #Moves to the next LED
color = random.randint(0, len(atcolors) - 1)
if i >= q1 and mess1_dummy == False:
q1_func() #Sound and lights when you're 1/4 done
mess1_dummy = True #Makes sure it only goes off once per game
if i >= q2 and mess2_dummy == False:
half_func()
mess2_dummy = True
if i >= q3 and mess3_dummy == False:
q3_func()
mess3_dummy = True
if i == num_of_spaces:
#play victory noise
celebration() #The celebration function (sound and lights)
strand.fill((BLACK))
i = -1 #Reset the counter and dummy variables
mess1_dummy = False
mess2_dummy = False
mess3_dummy = False
Glue LEDs to Side of Box (optional)
I glued one of the strands to the side of the acrylic board so the lights would be more visible from the outside. This isn't necessary, but if you're going to do this as well then it's easier to unclip one of the strands first, glue it to the side, then reattach it to the strands behind the game.
Glue the Board Game to the Top of the Box
Now, glue the board game FACE DOWN to the clear acrylic panel. I placed it down first and traced around it with dry erase marker to make it easier. Once again, make sure it's face down so the board game will be inside the box but visible through the clear panel.
Attach Electronics
Next, glue the female mono jacks into the holes you cut earlier so they're secure and you can access them from outside the box. Next glue the CPB down so the battery pack can reach it through the hole from outside. Then, connect the board game lights to the CPB. Once everything is secure and wired together test it one more time.
Glue the Top Onto the Box
By this point there should be 2 female mono jack connections sticking outside the box and a battery pack running from outside the box into the CPB. Every other component besides the battery pack, adaptive switch, and speaker should be inside of the box. I secured the battery pack and speaker to the box using the velcro tape. Once you're sure everything is working and you won't need to do anything else inside, glue the top panel onto the rest of the box. Once everything is dry the game is complete, to play just switch the battery pack on and connect the speaker and switch. Enjoy!