Whack-a-Pi

I have been looking for an excuse to use some large, light up arcade buttons for a while now. With a weekend pass for the Raspberry Pi party I decided this was the time to go all out and create my biggest Pi build yet!

Hardware

The frame is made of chip board and 25x38mm timber and is approximately 0.8m x 1.6m at full height.

Untitled Sketch 2_bbThe buttons were sourced from Arcade World UK and are 60mm with build in LED and micro switch.

The circuitry is fairly straightforward; the 13 buttons are wired directly to the GPIO (pull down) while the 13 LEDs are switched via 2 ULN2003 transistor arrays. The ULN2003s are needed as the LEDs are rated for 5v (i.e. they have a built in resistor).  The 5v feed is taken off of the Pis 5v supply.

The Fritzing diagram to the right shows how one button and LED is wired up to the Pi.  Adding all of them would have just been far too confusing, as you can see from the spaghetti wiring in the images below.

Let’s not forget the makers friend, gaffer tape!

The logo was scaled up and printed using the Block Posters site. This allowed me to split the image over multiple (16) sheets of A4 and then “tile” them on to the board.

A huge thanks to my teacher wife and her ninja paper strimming skills.  The trimming with a knife I did just didn’t cut it (pun intended)

Software

The software side is driven by GPIOZero for the button and LED interactions and PyGame for the front end and has been sized specifically for my HDMI Pi screen.

The LED Clock (or 7 segment style) font is called Digital 7 and is freeware available from styleseven.com

The core function of the game is fairly straightforward, and made even simpler with the GPIOZero library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from gpiozero import LEDBoard, Button
import time, random
 
lights = LEDBoard(2,3,4,14)    #there would be 13 in the game
buttons = [Button(25), Button(11), Button(8), Button(7)]   #there would be 13 in the game
 
elapsed = 0
last_idx = -1
current_idx = -1
score = 0
start_time = time.time()
while elapsed < 60:
	while last_idx == current_idx:    #select random index, that wasn’t the last one used
		current_idx = randint(0, len(lights) - 1)
	lights.leds[current_idx].on()	#light LED
	delay = max(0, 60 - (time.time() - start_time))
	buttons[current_idx].wait_for_press(delay)    #wait for corresponding button press
	if buttons[current_idx].is_pressed:    #if button was pressed in time increase score
		score += 1
	lights.leds[current_idx].off()
	last_idx = current_idx
	elapsed = time.time() - start_time

I also incorporated some sound effects which were gleaned from various sources, including YouTube!

The full source is available on my Github and has a lot more going on than the basic routine above, however the principle is exactly the same.  I also used the EzText library to bend PyGame to do my bidding and allow user input via some basic text boxes.

Post Birthday Update

It’s now the Monday morning and what a weekend!  This project held up really well (all things consided), and I received lots of nice comments about it.  It was pretty much in constant use for the two days and must have had hundreds of people playing it.

The highest scores over the weekend were 140 for adults, 136 for 13-17 and 126 for 12 and under. I’m not sure who derived the most pleasure out of it; the players or me watching friends and families fight it out for the top scores.

Below are some videos and pictures of the game from the weekend.

Leave a Reply