Saturday, April 20, 2013

First Project: Arduino Spede

Here's my take on a reaction time tester entitled Arduino Spede. The device is similar to the one seen in Speden Spelit TV show that ran in Finnish television in the 90s. The idea is to push buttons that lit up in a random sequence. The sequence gets faster and faster until eventually you are too slow or push the wrong button and it's game over. Each LED also plays a different note (C#, D#, F# and G#), so if you are really hardcore you can play with your eyes closed! My musically talented girlfriend Saara gets a score of about 30 with her eyes closed, where I can do only about 4 or 5 if I'm very lucky :)

If you're interested in knowing how it works or even building one yourself, read on!


Parts list

  • 1 Arduino UNO R3 (or equivalent)
  • 1 CC56-21SRWA common cathode four digit 7-segment display (or similar)
  • 1 74HC595 shift register chip
  • 4 push buttons
  • 4 LEDs
  • 4 BC548B transistors (almost any NPN transistor with similar specs should work)
  • 1 1uF capacitor
  • 4 1 kohm resistors
  • 4 390 ohm resistors
  • 1 470 ohm resistor
  • 7 560 ohm resistors
  • 1 small speaker
  • 14-pin ribbon cable
  • 2 14-pin ribbon cable connectors (female)
  • 2 14-pin PCB connectors (male)
  • Pin headers and Harwin connectors for LEDs, buttons and speaker
  • Wires, etc.

How does it work?

Buttons: The buttons are connected to digital pins 14-17, which are set up to use the internal pull up resistors inside Arduino. When no buttons are pressed the internal resistors pull up the pins to high state. When a button is pressed the corresponding pin does low. Without the pull up resistors the state of the input pins would be undetermined.

LEDs: The four LEDs are connected to digital pins 3-6 in series with 390 ohm current limiting resistors. Without the resistors the LEDs or digital pins of the Arduino could burn out.

Speaker: The speaker is connected to digital pin 2 via a resistor. In hindsight I should have also used a capacitor in series to filter out the DC and pass only the audible AC frequencies. I'm using the Arduino tone library to generate the tones. I've chosen frequencies 277, 311, 370 and 415 Hz which produce exotic Asian sounding notes C#, D#, F# and G#.

The score display: This is by far the most complicated part of the schematic. I've chosen a 4 digit seven segment display so you shouldn't run out of digits no matter how good you are! The display is a so called common cathode display, meaning that the cathodes (negative terminals of the LEDs) of a digit are tied together. The display has a pin for each segment A-G but the pins are shared for all digits. So, for example, if the anode (positive terminal of a LED) for segments B and C are set high and the common cathode of digit 1 is pulled to ground, number 1 would be displayed in the first digit.

Because a single anode pin is connected to all digits, it's impossible to display different numbers in different digit positions at the same time. Instead, we can turn on a digit one by one very rapidly in succession. So, for example, to display the number 1234, first we would set the anodes to display number 1 and enable only the first digit by pulling the cathode of digit 1 to ground. Then we would turn off the digit, set the anodes to display number 2 and turn on digit 2. And so on for 3 and 4. If this is done fast enough, the eye cannot see the LEDs blinking on and off and it appears as if the digits are all lit.

The job of NPN transistors T1-T4 is precisely to pull the digits to ground. Normally the transistors are off, meaning there is no current flowing through them. Digital pins 10-13 are connected to the base of the transistors, so setting a pin high turns on the corresponding transistor and enables a digit.

In order to cut down the number of Arduino pins I've used a 74HC595 shift register between the Arduino and the display. The shift register is a serial in, parallel out device and also acts as a 8 bit buffer. It has eight outputs which "latch" to a state, meaning that the outputs remember their state until the state changes again. The Arduino sends the state of eight outputs one bit at a time (serial transmission). For seven segments we need only seven bits so the eighth bit is unused. There is a great tutorial about using the 74HC595 chip with Arduino here.

This may sound a little tricky. Check out the datasheets of parts CC56-21SRWA and 74HC595 for more details. You should be able to substitute the display with another part but it has to have common cathodes. The pin ordering is also likely different from the one I used.

Putting it together

The final version consists of three circuit boards which I made myself (I could write about the process in a separate blog post). One of the boards contains only the display and it is connected using a 14 pin ribbon cable to the main board. The main board contains the 74HC595 chip, transistors, resistors and the capacitor.

After building these and making sure everything worked, I realized that I didn't want to allocate my Arduino permanently to the project. So I made a third circuit board, a standalone Arduino board following the instructions here.

You can use normal pushbuttons and LEDs, or you can order some fancy arcade buttons with built-in LEDs from Ebay like I did. I soldered wires to the terminals of buttons and LEDs and connected them using Harwin connectors and headers to the main board.

Source code

Download source code

The code itself should be self explanatory so just a few comments. The game can be in one of three states each of which is implemented in a separate function: startMenu(), playGame() and gameOver().

Start menu flicks between previous score and high score. High score is stored in EPPROM which retains its value even when the device is turned off. When a button is pressed, a new game begins. Holding all four buttons while in start menu causes the high score to be cleared.

Playing the game is handled by playGame() function. Here one of the four LEDs is turned on randomly and a timer starts counting down. If the player presses a wrong button or the timer reaches zero, the game is over. If the player pressed the correct button, the procedure starts again with a new randomly selected LED. This time the timer starts from a little bit smaller value. This repeats until the game is over.

In game over state, the score is blinked a few times and a tone is played. The game enters the menu state automatically after a short delay.

Display and main circuit boards, hand drawn, before dipping into acid bath
The wiring for LEDs. Buttons not connected yet.

Harwin connectors for connecting LEDs and buttons to circuit board
Standalone Arduino board (left) and main board (right)

Testing the outputs