Friday, December 27, 2013

Speed Tester v2.0

Back in April I made an ATmega328P based speed and reaction time tester. Since then the game has been tested numerous times on our friends and relatives and it has also been a huge hit at a certain kindergarden! Last summer I was given orders to make a new device for a family of relatives. The game would be a christmas present for the whole family so utmost secrecy had to be maintained while building it. Also, the new device would have to be vandal proof because they have three kids :)

Instead of building an exact copy, which would have been boring, I decided to make a completely new revision. In this blog post I'll lay out the major changes and discuss some challenges I met.

But first a video!

From wall wart to battery powered

The old device was powered by a wall wart which was a little cumbersome to use and limited the usability somewhat. I decided early on that the new version would be battery powered. As this was my first real battery powered project, I had to do some research about battery efficiency. The old device uses a 7805 voltage regulator to convert a voltage between 7-15 volts down to 5 volts, a voltage more suitable for microcontrollers. The problem with 7805 is that it turns the extra voltage to heat and thus wastes a great amount of energy. Also the 7805 requires that the input voltage is about 2 volts higher than the output voltage. With batteries this would mean that once battery level would drop below the threshold voltage, the regulator would shut down, and thus even more battery capacity would be wasted.

I looked into another options like using low dropout regulators and even diodes to drop the voltage (the voltage drop of a typical diode is about 0.7 volts) but this was a dead end. Then I discovered the wonderful world of switching regulators. These tiny devices turn the voltage on and off very radiply and after suitable filtering this produces the desired output voltage. The amazing thing about switching regulators is that when the regulator switches off no current flows. This means that switching regulators are very efficient and only minimal amount of energy is lost. 

There are many kinds of switching regulators. Step Down voltage regulators work like the 7805, they take a higher voltage and drop it to desired output voltage. Step Up regulators work in the opposite direction. The issue with batteries is that battery voltage varies a lot during the lifetime of a battery as battery capacity is drained. Therefore a Step Down voltage regulator is not a good option for us; a Step Down regulator shuts down like the 7805 when input voltage drops below target voltage. Using a Step Up regulator to set up from 3 volts (two AA batteries) to 5 volts would probably be an acceptable solution, but I figured I would need the extra juice of 4x AA batteries.

Luckily I found a perfect match for my usecase: the Pololu S7V8F5. It is a combined Step Down/Step Up regulator. This little beast, about the size of a 7805, is capable of taking any voltage between 2.7 and 11.8 volts and turn it into steady 5 volts with typical efficiency over 90%. This is just what I needed to powered the device with four AA batteries.

Left: 7805 voltage regulator
Right: My new best friend, the S7V7F5 Step-up/step-down regulator

I also made some optimizations to reduce the power consumption of the hardware. First I lowered the MCU clock frequency from 16 Mhz to 2 Mhz by setting the 1/8 prescaler fuse bit. This reduced power consumption quite a bit (about 10mA less current drawn) and the clock rate is still fast enough to update the display hundreds of times per second and generate the necessary bleeps accurately in 300-600hz range. I also simplified the design by removing the 74HC595 shift register that was wired between the led display and the MCU. The MCU now drives the seven segment displays directly.

It is pretty easy to forget to turn off the game after playing, so I added an attract mode thingy which flashes the leds and makes some noise if the game sits too long in the main menu. As a last touch I added a reverse voltage protection circuit to protect the electonics in case the batteries are inserted the wrong way around. Typically reverse voltage protection is implemented using a diode in series with the battery, but diodes have a pretty big forward voltage drop, so this would have lowered battery efficiency. A better solution is to use a MOSFET or transistor. After some reach I decided to use a PNP transistor for this task. It was actually quite hard to find a suitable transistor: the required transistor needs to be PNP, have a high beta value, low saturation voltage and max collector emitter voltage of at least 6 volts. After a long search I found the ZXTP2012ASTZ which is just perfect for this task.

To protect the electronics I needed a sturdy enclosure. I have the privilege of knowing Antti Sirén, a master craftsman, who made the enclosure from wood and painted it bright christmasy red. Thanks Antti!

Yay! My first schematic done with Eagle

Inside the box are four AA batteries, main PCB and four arcade buttons with microswitches and LEDs. The 3x 7-segment display is on a separate PCB which is mounted on the lid.

New software revision

I also wanted to improve the software side to make the game more enjoyable. The old version is pretty harsh because the time window when the button needs to be pressed is very short. If you weren't fast enough to press the button before the next led lit up, it was game over. This resulted in unnecessary frustration and it was not sometimes clear what had happened. Sometimes the players felt it was the game's fault, not their own that the game had ended. To fix this, I changed the logic so that as long as you pressed the correct button in sequence, no matter when, it would be ok. So the player could be behind the led sequence as long as he kept pressing the buttons in the correct order. This improves the game a lot. Now the game can only end when the player presses the wrong button and there is no doubt whose fault it was.

Another aspect which has a big influence on gameplay is the speed up curve which makes the game gradually faster as you play. If this curve is wrong the game either speeds up too slow and feels boring, or too fast and it feels too difficult. Also abrupt changes to the speed are easily noticed and distrupt player's flow. Surprisingly a linear speed up curve does not feel natural at all. After many iterations I ended with a piecewise linear curve with 4 parts.

As a result of these changes the game is now a tad easier and a game last a little longer. The game should now be more rewarding to the player. As icing on the cake I added a totally new game mode, the memory game. Check it out in the video below!


  1. great game!
    Is it possible to add more buttons?
    that could use a matrix

    1. Yes, it's possible. The microcontroller does not have enough free pins for new buttons and LEDs but it would be quite simple to extend the number of I/O pins with shift registers such as the 74HC595 for output pins -> more LEDs, and 74HC165 for input pins -> more buttons. A matrix would be a good idea if there are a lot of buttons & leds. E.g. a 4x4 button matrix would require 4 pins for the rows and 4 pins for the columns.

  2. Really great stuff. Love the retroness of Toorum's Quest. Reminds me of how proper games were made back in the 80's.

  3. Hi! Great project. I was considering to build and try if this would be great for my kids and ofcourse us parents :). Could you poste the sketch of this version of the improved game somewhere. Or is this version only for personal use.?

  4. Great idea! I added the code to github:

    The improved version is not only more fun but it has alternative memory game mode (press rightmost button to play the memory game). Be sure to use the new firmware :)

    Oh, remember to buy as big and as good quality buttons as possible. I got 5cm diameter arcade buttons from ebay and they rock.

    I'm sure this project is going to be a great success in your family. Please let me know how it goes!

    1. Ok. Thanks a lot. I will let you know how it worked out :)

    2. Hello Petri, thank you for sharing your coding. I am new to Arduino, and would not be able to write this like you have. I am planning a 6 button version, and change the display to something else to free up some pins. I hope to learn while attempting this! I will let you know how it goes, and hoping it goes well. :)

    3. Awesome! I'm interesting in hearing how it goes. Have fun!

  5. One more thing: make sure you set up the fuse bits to use internal 2MHz clock, otherwise timing and sounds will be way off. v2.0 uses lowered clock frequency for longer battery life.

    1. hello, I have uploaded the code is going very fast, how do I change the time, the beginner with Arduino. thank you

  6. Hi, did you use common cathode or common anode segment displays for this project?

    1. Turned out to be great project. Thanks!

  7. this is an awesome project to tinker with, also to have fun with friends q, in your previous project you mentioned using common catode display segment, and now i read your using anode...did i understand wrong from the first project or this is applies only to this v2.0? thanks..

    1. the transistors are sourcing current for the displays in emitter follower configuration. So the displays are common anode. If you have common cathode displays you need to swap the transistors to other side so that they pull the common cathodes to ground. You would also need to invert the segment signals in the firmware.

    2. Oh now I see what you meant. The old version used common cathode displays and the new one common anode. I guess no other reason than just having those parts around back then.

  8. Thank you!! the way, I liked the first version, the error-counting with led flash speed gets faster..... by any chance do you have the code for that one??

    1. The speed gets gradually faster as you play. You can easily tweak the initial speed if it feels too slow. Go to line 443 in speed.ino. Change "level = -1;" to e.g. "level = 15;".

      I don't recommend going back to the old version. The speed curve is much better in the new version, plus the old version does not have the memory game mode (you can play the memory game by pressing the 4th button in the menu).

  9. Hi Petri , would you do a commercial version of this circuit with 12 inputs ?

  10. I was thinking of building one of these, and having it act as a clock when otherwise not in use.

  11. Hi Petri.
    Thanks for sharing everything. I am planning to repeat but will use the LCD display and I2C. It is more simple to connect and I can display more information on the screen.
    One thing I would suggest as improvement to your design is to use 18605 rechargeable batteries from dead laptop batteries (check videos on youtube on this subject) together with TP4056 USB charge and a step-up booster. One 18605 cell will be more than enough to run this little device. The dead laptop batteries are lying around so it would be free, the cost of battery holder, booster and TP4056 in total is around $3 on Aliexpress including shipping. Boosters are LM2577 or MT3608.

  12. Hi Petri,
    Thank you for providing the schematic and sketch for this project.
    I have built it and it works perfectly (I used a 2MHz crystal as I couldn't figure out how to set the fuse bits).
    I am trying to make a slight adjustment to your code - which I thought would be quite easy, but your code is way above my level of expertise, I'm afraid - to allow pin 5 (DP3) to go HIGH (or LOW, so long as it changes state) when a certain score is reached. I'm not having much luck so far, even though I thought this would be relatively easy to do. Would you be able to advise at all?

    1. Hi! It could be a little bit tricky because digital pin 3 is connected to the timer 2 which generates the sound.

      You could try changing this line in mytone() function:
      TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);


      TCCR2A = _BV(COM2A0) | _BV(WGM20);

      This should disable timer output on DP3, but I haven't tested it, so it could also cause the sound to break down or some other issues.

      You could also try to comment out the entire mytone() function to see if your problem goes away.

      Unfortunately all the other pins are used. One idea to free up pins would be to use a 74HC595 shift register to control the LEDs but this would require rewriting the display code.

      Hope this helps!

    2. Petri, thank you for such a prompt reply.

      I'm pleased to say that your (first) suggestion worked perfectly. DP3 now remains LOW until a certain score is reached and then goes HIGH.
      And there is no discernible difference to the sound.
      Exactly what I wanted!
      Thank you very much.

  13. Meus parabéns
    Muito legal seu projeto.
    Gostaria muito de fazer um desse para jogar tiro ao alvo com airsoft, mas não consigo achar o esquema eletrônico
    Vc compartilharia?
    Desde já agradeço.