There’ll be no quarrel on who got in first with this game show button system.
BUILD TIME: 2 Hours + 3D Printing time
DIFFICULTY RATING: Intermediate
This is quite a fun little project that can easily allow you to increase the tempo and fun factor of any trivia game, rapidly turning a commonly sedate game into a high energy competitive battle among friends.
There are countless other potential uses also, from drinking games (yes, we all have that one friend) to ninja warrior style obstacle courses. The reality is the device can be used and or adapted to be used in countless different ways for countless different things.
THE BROAD OVERVIEW
The concept is fairly simple and can be adapted to suit many different games which require people to be the first to hit a button. We built it with the quiz-style button system in mind where four players are asked a question and the first to hit their button gets to answer. A fifth button allows the host to reset the system for the next question.
HOW IT WORKS
The electronics for this project are very simple. We use a microcontroller to read the state of five switches. These switches consist of four player buttons and a fifth button to allow the game host to reset before asking the next question.
When any of the four player buttons are depressed the microcontroller will halt, illuminate the LED on the player’s button and also illuminate the game hosts unit the colour of the winning player. The game stays in this halted state until the game host depresses the reset in which all LEDs extinguish, and the program again awaits a player to press their button.
For the prototype we used an Arduino Nano development board. Largely due to its convenient ability to be used in a breadboard. We used five tactile switches to simulate the player and game host inputs, A red, green, blue and yellow LED simulate the LEDs built into the arcade-style buttons we will use in the final design. We also used a single NeoPixel style WS2182 addressable LED to identify to the game host which button was pressed first.
The Fundamental Build:
Game Show Prototype
Parts Required: | Jaycar | ||
---|---|---|---|
1 × Arduino Compatible Nano | XC4414 | ||
1 × Mixed Jumper Wires | WC6027 | ||
5 × Tactile Switches | SP0608 | ||
4 × 330Ω 1/4W Resistors* | RR0560 | ||
5 × 10KΩ 1/4W Resistors* | RR0596 | ||
1 × Red 5mm LED | ZD0150 | ||
1 × Green 5mm LED | ZD0170 | ||
1 × Blue 5mm LED | ZD0185 | ||
1 × Yellow 5mm LED | ZD0160 | ||
1 × NeoPixel RGB LED | ZD0272 |
* Quantity shown, may only be sold in packs. Prototyping breadboard and accessories are also required.
THE CODE
The code can be downloaded from the resources section on the website.
The code is quite simple in theory. All we need to do is constantly check the button inputs to see if they have changed states. If a change of state is detected, we have the program halt, illuminate an LED to indicate which button was depressed first and change an addressable LED to the winning players colour.
The code waits for the game host to press their button, signifying a new round. All LEDs are extinguished and we once again return to polling the switch inputs, waiting for a changing state.
DIRECT PORT MANIPULATION
One significant difference from our usual programming is the use of direct port addressing. Usually, we control the I/O pins of the microcontroller using the Arduino nomenclature/syntax.
This is usually:
digitalRead(pin)
digitalWrite(pin)
Where pin is the pin we want to read. This code exists outside of the normal C++ programming language and was created by the Arduino foundation as a way for the users to easily manipulate the GPIO (General Purpose Input & Output) pins of a microcontroller.
For this project, we have opted to directly address the pins and not use the Arduino syntax. We did this to speed the program up significantly.
The Arduino development platform offers users an exponentially simpler microcontroller experience largely due to the ease of their custom C++ based programing language, however, this ease of use does not come without a significant cost to the speed of the program.
To explain this better, let’s use the simple blink program. We will blink an LED without using any delays, then watch the waveform on our oscilloscope and see how quickly the program can run.
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
//delay(1000);
digitalWrite(13, LOW);
//delay(1000);
}
Doing this we learned that the Arduino Nano running the above code can run that code 144000 times a second despite having a 16MHz crystal. Let’s repeat the same experiment but without using the Arduino language.
void setup()
{
DDRB = 0xFF;
}
void loop()
{
while(1){
PORTB = B110010;
//delay(1000);
PORTB = B00000000;
//delay(1000);
}
}
When running this code, we get the following output.
As you can clearly see doing despite the code doing precisely the same thing using direct pin manipulation is many magnitudes quicker than using the Arduino language, allowing us to cycle the pin on and off 4 million times a second compared to only 145 thousand times a second.
For the most part, this is never really an issue for our programs as we don’t often need this level of speed, however, for this project we want to essentially use a polling technique to identify if one of the five buttons have been pressed.
This means in one cycle of the program we need to read the state of five inputs, if we were to use the Arduino nomenclature this would slow down the program fairly significantly and increase the chances of an incorrect triggering when two people attempt to press their buttons at the same time.
We could use hardware interrupts however, that would mean we would need to upgrade the microcontroller to an ATmega which has four hardware interrupts.
We could use software interrupts but then we would need to include many more lines of code to account for debouncing etc. Thus, we concluded the easiest and most efficient and effective approach would be to use this direct port manipulation.
The first step to understanding this process is to take a look at the actual pinout of the Microcontroller hidden under the Arduino naming convention.
After you ascertain the actual name and address of each of the required pins you then need to calculate the value to write to the address to control it by using the datasheet for the ATmega328P, as shown here.
We find it easiest to work in binary here as a 1 in a location represents that bit. So, when we write:
if ((PINB & B00000001) == 0)
We are telling the microcontroller to multiply the bit in each of the addresses inside PINB by the binary value “00000001”.
This effectively takes the value of the entire PINB address and multiplies each bit by 00000001.
i.e. the value in register PIN B7 x 0 = 0
Anything multiplied by 0 is a zero therefore, for this to be true PINB0 has to be 0. i.e. pulled low.
This whilst sounding complex is quite simple once you get your head around it and really allows you to open up the potential of the microcontroller.
It’s worth mentioning that the same process can be used to set the pins as inputs and outputs, we didn’t do this as we define the inputs and outputs outside of the main loop and thus it had no benefit to the speed of the code. However, if you’re keen to have a try, look into the data direction register from the ATmega328P datasheet and give it a crack.
The Main Build:
Game Show Button System
Additional Parts Required: | Jaycar | ||
---|---|---|---|
1 × Arduino Compatible UNO | XC4410 | ||
1 × UNO Prototyping Shield | XC4482 | ||
1 × Yellow Arcade Button | SP0664 | ||
1 × Blue Arcade Button | SP0666 | ||
1 × Green Arcade Button | SP0665 | ||
1 × Red Arcade Button | SP0662 | ||
1 × Clear Arcade Button | SP0669 | ||
20 × M3x15mm Screws | HP0406 | ||
Cat5 Cable (Length depends on your application) | WB2022 |
WIRING THE CIRCUIT
Wiring the circuit is fairly straightforward. The first step you need to take is to identify the four required connections on the switches. We used the arcade switches from Jaycar and whilst they look very similar we can’t guarantee the switches sold by Altronics and core electronics are identical.
Therefore, it’s best to suggest that you follow the datasheet or use a multimeter to identify which pins are which on your switch.
If your datasheet does not have a pin out for the switch it should have markings for COM, N/O and N/C. These connections should be identical to our circuit.
To identify the LED connections, you can use your multimeter in Diode mode. Select the diode mode and use the probes in the common and + inputs. Attach the probe to either side of the LED connections, in one direction you will get a reading as the diode only allows current to flow from anode to cathode.
- COM = Arduino ground connection.
- N/O = the normally open pin and is connected to the Arduino input for that colour switch.
- N/C = Normally Closed unconnected.
- GND = Arduino ground connection.
- LED+ = Arduino digital pin for that colour LED.
If your switch isn’t labeled with COM, N/C or N/O you can use your multimeter in continuity mode to detect which pins are connected when the switch is depressed. Simply push the button and apply the probe to tow of the switch pins, if it beeps release the button and makes sure the circuit is now open in which case the beeping should stop.
When you depress the button the switch contact moves from the N/C or normally closed pin and COM to the Normally open pin and COM, in this configuration, it will connect the digital pin input to ground producing a voltage potential at the digital pin of 0V.
We used 10KΩ pull-up resistors to keep the pin high when the button isn’t depressed, however you can very easily use the internal pullups built into the ATmega328P microcontroller, if desired.
Now we know the pinout of the button we realise that each of the four button units will require three wires for control. We can use the same ground wire for COM and GND, we need a wire to sense the button press and we need a wire to control the inbuilt LED.
Since the current demands are a tiny 20mA we don’t need to be too concerned about the thickness of the cable despite needing about 1 – 2 metres per unit. This is because the voltage drop along a cable is proportional to the current. The individual wires inside a cat5 cable have a resistivity of around 100Ω per km, therefore our 2m length of wire at 20mA will experience a voltage drop of a few millivolts.
Voltage drop = ((2(length of cable in metres × resistance per metre)) × current)
= ((2*(2*0.1))*0.02) = .4Ω * 0.02A
= 8mV voltage drop
It’s now just a matter of assembling the device and making all of the required connections. We suggest wiring each bottom one at a time as this will significantly reduce the chances of confusion.
3D PRINTED ENCLOSURE
When designing the enclosures for this project we had to keep in mind the environment it would be used in. These buttons are likely to see some significant abuse as excited players attempt to be the first to answer. As such we designed the cases with a thicker than usual shell of 2mm compared to our usual standard of 1.2mm. We also added ribbing around the button that disperses the impacts over a larger surface area. We have also added TPU rubber feet that will again absorb some of the impact.
We have also added some strain relief tabs to the bottom section of the button and controller unit, these tabs allow us to secure the cable input to the case preventing the cables and connections being damaged if the cable is accidentally pulled.
The bottoms of the button and controller enclosures are secured to the top sections via M3 15mm screws and the rubber feet are secured to the bottoms using hot glue or any other suitable adhesive.
QUIZ BUTTON ENCLOSURE
The top part of the button unit was printed on out Flashforge Creator pro at 200-micron layer height using Flashforge branded translucent PLA. At this layer height and in this orientation, it took us about 7 hours to print each piece. Note this time is a result of our settings and the speeds we print at. Your print time may vary. If you’re wanting a faster print time you can instantly reduce the required time by increasing the layer height from 200–300 microns, this will reduce your print time by around 50% meaning you can print this same part in 3.5 hours.
To assemble this section all you need to do is remove the switch section from the button section by gently twisting the two apart. Be careful here as all that aligns and secures the two pieces together is 2 small pieces of plastic which can easily be broken and if broken could render your button inoperative. Once you have the switch removed unscrew the retaining nut from the main button body. You then simply insert the button into the enclosure and tighten the retaining nut back up securing the button to the enclosure and once again very carefully reattach the switch component.
The bottom part of the button enclosure was also printed on our Flashforge at 200-micron in the same Flashforge translucent PLA. It printed without support and takes about 2 hours to print in this orientation.
FEET
The feet for the button unit were printed using unbranded TPU rubber on our Flashforge at about 25mm/s, taking about 20 minutes each to print at 200-micron. This part is quite literally just a small ring of rubber which is designed to both reduce the parts ability to slide on a surface but also absorb some of the impact of high velocity button pushing that one would expect in this type of situation. These rings can simply be attached to the base using adhesive or simply hot glue.
HOST BUTTON ENCLOSURE
The top part of the host controller unit was also printed using Flashforge clear PLA at 200-micron layer height. It takes about 7 hours to print at these settings.
Note that this enclosure is not built to be as tough as the other sections since it is designed to be used by the host who we expect wouldn’t be likely to be quite as excited as the players. This also want this enclosure to light up the colour of the winning player, which means we needed to diffuse the light through the walls of the enclosures. Thin walls enable us to make the light appear brighter.
The bottom part of the enclosure was printed in clear Flashforge PLA on our Flashforge creator pro at 200-micron layer height. The part prints perfectly fine without any supports and takes about 2 hours to print in this orientation and layer height.
Overall printing time
As you can no doubt tell the printing time for this device is actually quite momentous requiring a total of 12 parts. Five parts, which take 7 hours to print, five parts that take 2 hours and two parts that take about 20 mins. This makes the total print time for this project to around 45 hours. However, once you have everything printed, the construction only takes a few hours.
TESTING
The good news is that there is only one way to test this device and that is to play it. We dusted off our old trivial pursuit board game and modified the rules so that the person to hit their button first got to answer the question. We can confidently say that the buttons are capable of surviving some severe rough play with excited adults. The project needs 5V to operate. You can connect your own 5V regulated power supply or power from an available USB power source.
For our build, we soldered a USB cable (with its plug cut off) directly onto the UNO board. If you do the same, we recommend you secure the USB cable inside the case using a cable tie. This strain relief will prevent damage to the UNO if somebody accidentally pulls on the USB cable.
Testing the project is straightforward. Once power is applied, you can hit any of the player buttons. The button should illuminate and the same colour should be shown on the host controller. You press the host controller button to reset, ready for another game button to be pressed.
WHERE TO FROM HERE?
There are a few modifications one can easily make to this project to make it substantially more convenient. One awesome idea would be to add a display to each of the button units and a correct or incorrect button to the controller unit. This way the host can press a button to indicate a correct or incorrect answer in which the score is tallied and displayed on each players button. This functionality would be pretty simple to implement however the cost would be substantially more and may put it outside the scope of many people, thus we opted to keep it nice and simple.
Another possible modification would be to add randomisation to the button polling process. As it stands currently the buttons are polled in the same pattern each time. Ie check button 1, check button 2, check button 3, check button 4 and repeat. It’s unlikely due to the speed of the program but still possible that this rotation could favor the first button in the case that two people answer at the same time (due to the time it takes the microcontroller / Arduino to operate a while loop). A solution to this would be to add a level of randomisation to the polling rotation. This way no one player is given any advantage no matter how slight ie microseconds.
To do this we could store the four button addresses in an array and shift the array one address left or right on each loop of the program. This would mean each button had the chance to be read first and each button equally had the chance to be read last, thus, negating any potential inequality in the polling process. Of course, this added code will also slow down the process which isn’t ideal.
Finally, another modification would be to add some audible indication to the buttons giving them a buzzer feel. This could be done using a MP3 shield for the Arduino UNO in conjunction with a speaker, this would give you the ability to add very unique buzzer sounds to each individual button.