Introduction
I created this project a long time ago based on one of the original Rapsberry Pi Model B boards (2011.12). It uses some cheap arcade-style switches mounted on a wooden board - it’s not pretty but the idea was to have something that could be used for a number of different applications. The first application was a Whack-a-mole game that I built with my son Jack.
After building the original application, the buttonboard laid idle for a few years. I revived it to use at a STEM event at a local school.
The hardware
- Raspberry Pi
- This uses an original 2011.12 version so any variant will do.
- A MCP23017-based breakout board. There are 7 switches (each with a light) so I needed 14 I/O pins to control the buttonboard.
- I used the “Slice of Pi/O” board that fitted on top of the Pi.
- A relay board to drive the button lamps. The lamps in the buttons need a 12V supply and a reasonable current so can’t be driven directly from the Pi. I used 7 output pins on the MCP23017 to switch these relays to power the lamps.
- I used the KS0059 keyestudio Eight-channel Relay Module
- A mini portable speaker with a 3.5mm jack input
- This is used for the sound output. Alternatively you could add a speaker and a small amplifier module to the project.
- A 12V power supply
- This powers the relay board itself and the lamps. It could also power the amplifier if you want to go down that route.
The switches are mounted into some scrap wood - see the photos. I mounted some hardboard underneath and put the circuitry on there.
The build
The software in github makes some assumptions about the way the buttonboard is wired up. If you choose a different configuration, you’ll need to adjust the code accordingly.
The MCP23017 has two banks of 8 GPIO pins, A and B. I have configured bank A as outputs to drive the button lights. Bank B is configured as inputs to receive the button presses.
There are 8 inputs/outputs in each bank. As I have 7 buttons on the board I am only using \(A_0\) to \(A_6\) and \(B_0\) to \(B_6\). \(A_n\) and \(B_n\) are the light and switch for the same button.
To use the software as-is, wire the inputs and outputs in the following configuration.
Output pins (bank A)
Each output pin controls a relay on the relay board. One side of each relay is wired to 12V (the side that connects when the relay is energised) and the common goes to one side of the corresponding lamp. The other lamp connectors are wired together and connected to ground. When the pin is set to 1 (5V), the relay energises and 12V is connected across the lamp.
Input pins (bank B)
One side of each switch is connected to a common ground. The other side is connected to the corresponding pin (bank B) on the MCP23017.
The MCP23017 has the option of using pull-up resistors on input pins, which is the mode I’m using here. In the software, this is controlled using the GPPUB (GPIO pull-up resistor) register.
When the switch is not being pressed, the input goes to 1 (because of the internal pull-up resistor). When the switch is pressed, the input is pulled down to 0.
Hopefully that’s enough information to get you going. If you need more detail or anything doesn’t make sense, please ask.
OS and System Software
As I was coming back to this project after a long break, I reinstalled the OS (RaspOS) from scratch (there are lots of guides on-line explaining how to do that).
With the OS installed, I also:
With the OS installed, I used raspi-config
from the command line to:
- Enable I2C
- (Optional) Setup Wi-Fi (I added a USB Wi-Fi dongle)
- (Optional) Enable ssh
I enabled ssh and and installed an ssh key from my PC. This lets me log on to the system remotely without any further authentication.
Packages for this project
sudo apt-get python-smbus
(to control the I/O pins from Python)sudo apt-get festival
(text to speech utility)sudo apt-get espeak
(another text to speech utility)sudo apt-get git
(source control)
There is no display on the buttonboard (maybe a future project…) so I used text-to-speech to tell people their score etc. Both festival
and espeak
work OK - I installed them both and have the option to switch between them.
I use git for version control.
Applications
All the code is available in this repo: https://github.com/paulstallard/buttonboard.
I put most of the common code into a ButtonBoard
class. This handles the basics of turning on or off a specific light, collecting button inputs, waiting for a specific button, etc. It also includes some simple switch debouncing.
The applications (games) are then written using the main class. They are all relatively simple so looking through the code is the best way to understand them.
Dice
Uses the lights to display a standard dice. Press the centre button to “throw” a new value.
Whack-a-mole
A very simple, but very addictive game! Hit the button that is lit, then another one will illuminate. After 20 hits, you’ll be given your time. Can you go faster than the lowest time so far?
Simon
A “follow-me” game, similar to the old “Simon” (but without the colours and without sounds). Watch the sequence of lights and try to copy it. When you make a mistake (oh, you will!) it tells you how long the streak was. Can you go longer than the longest streak so far?
Other ideas?
I’m sure there are plenty of other games/applications I could build on this platform. I’d love to hear your ideas…
Use in STEM sessions
It seems like everyone loves playing these games - children and adults alike. I’ve used the buttonboard to talk about algorithms and computational thinking - eg asking children to imagine the steps the computer is going through to implement the game. I also used it alongside an image recognition demo (built using PyTorch) to discuss the differences between traditional algorithms and machine learning.
Children are invariably creative and surprising. Every group I’ve shown this too has tried to break it or cheat in one way or another.
- “What if we hold down all the buttons at the same time?” (I fixed that bug!)
- “Let’s do one button each and get an unbeatable score”
I’ve also witnessed some truly incredible streaks in the Simon game 🙂.