This instructable focuses on using one analog input line for multiple buttons which can be detected independent of each other.
And to highlight the use of these buttons included is software to play four different 4-Button games. All the games (8 in total) herein use an Led ladder display (refer to earlier project: instructables: Single-Line-LED-Display-Games).
You can use your own 4-button assembly with other display outputs, simply utilize the 'scanButtons()' function from one of the included sketches. And use those sketches for example use thereof.
The games are a skill game: Whack-a-Mole, a memory game: Simon Says, logic games Sea Hunt and Flip'd a two player game similar to Reveri. Later, in this instructable, I'll also later introduce four two-person games of head to head competition.
Step 1: Determining Optimal Button Configuration
Simply using some resistors in series with buttons tapped off between each will work if you never have to worry about one button press occluding another. In such a configuration each button, when pressed, blocks out any and all below it. Even when you only need two buttons and you only care about one at a time, like in an implementation of ping-pong; it would be a problem, if a player fails (just being too slow, or maliciously) to remove his finger from his button before the other has to hit his.
Multiple buttons have often been connected to a single analog line each with there own different resistor values going to the input. You can, easily enough, differentiate which button or pair is pressed when there is only 2 or 3 buttons. But not reliably with more buttons or more than two pressed, as the worst case combination of readings become ambiguously too close together.
Here with what I call a Double-Y configuration of four buttons & resistors, you can reliably discern any single, double, even triple or all four buttons being pressed. The software driver to do so is covered in the next section and the code listing.
With a desire to have four buttons attached to one analog input where each button's press could be detected regardless of the state of the other buttons, I modeled several configurations in a spreadsheet. I found that a double-Y (consisting of 2 sets of three resistors) configuration gave the best possibilities. See the wiring schematic diagram below. I was evaluating them based on the most separation of the total resistance between any two combinations of buttons pressed. I further modeled calculated analogue values. Refer to the spreadsheet file below.
To determine the best values to use in the above configurations I wrote a simulation, which exhaustively tried all possible permutations of potential resistor values, finding the set which produced the maximum least difference between possible reading inputs. I have provided the code I used. This was a brute force tool I threw together, got what I wanted and put it aside, so it was in no way optimized. It is totally as is, for historical reference only (Solve_4R.html below).
Here is its output for review:
R1: 10 R2: 12 R3: 10 R4: 12 R5: 10 R6: 15 minR delta: 3.3658818125 R1: 10 R2: 12 R3: 10 R4: 12 R5: 10 R6: 18 minR delta: 4.9490620031 R1: 10 R2: 12 R3: 10 R4: 12 R5: 18 R6: 10 minR delta: 4.9490620031 R1: 10 R2: 12 R3: 10 R4: 15 R5: 10 R6: 33 minR delta: 5.0576510475 R1: 10 R2: 12 R3: 10 R4: 15 R5: 12 R6: 10 minR delta: 7.104826870 R1: 10 R2: 12 R3: 10 R4: 18 R5: 10 R6: 18 minR delta: 8.1673424912 R1: 10 R2: 12 R3: 10 R4: 18 R5: 15 R6: 22 minR delta: 8.6504939648 R1: 10 R2: 12 R3: 10 R4: 22 R5: 10 R6: 18 minR delta: 10.1721492515 R1: 10 R2: 12 R3: 10 R4: 22 R5: 10 R6: 22 minR delta: 10.5040000560 R1: 10 R2: 12 R3: 10 R4: 27 R5: 12 R6: 27 minR delta: 10.7814361579 R1: 10 R2: 12 R3: 12 R4: 33 R5: 15 R6: 36 minR delta: 10.8827552754 R1: 10 R2: 12 R3: 12 R4: 68 R5: 10 R6: 22 minR delta: 11.4499029683 R1: 10 R2: 12 R3: 12 R4: 68 R5: 10 R6: 27 minR delta: 12.0961591599 R1: 10 R2: 12 R3: 15 R4: 68 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 15 R4: 75 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 15 R4: 82 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 15 R4: 91 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 27 R4: 82 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 27 R4: 91 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 27 R4: 100 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 68 R4: 15 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 75 R4: 15 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 82 R4: 15 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 82 R4: 27 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 91 R4: 15 R5: 10 R6: 27 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 91 R4: 27 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 12 R3: 100 R4: 27 R5: 10 R6: 15 minR delta: 12.7992171382 R1: 10 R2: 15 R3: 10 R4: 18 R5: 18 R6: 12 minR delta: 13.2909379968 R1: 10 R2: 15 R3: 10 R4: 22 R5: 12 R6: 10 minR delta: 14.245362837 R1: 10 R2: 15 R3: 10 R4: 39 R5: 18 R6: 27 minR delta: 14.5126340326 R1: 10 R2: 15 R3: 10 R4: 56 R5: 12 R6: 15 minR delta: 15.220571553 R1: 10 R2: 15 R3: 12 R4: 27 R5: 12 R6: 12 minR delta: 18.8228671943 R1: 10 R2: 15 R3: 12 R4: 39 R5: 18 R6: 27 minR delta: 19.236186493 R1: 10 R2: 15 R3: 15 R4: 47 R5: 22 R6: 33 minR delta: 19.5685736556 R1: 10 R2: 15 R3: 22 R4: 56 R5: 22 R6: 27 minR delta: 19.7887024012 R1: 10 R2: 15 R3: 27 R4: 220 R5: 12 R6: 10 minR delta: 21.2533513149 R1: 10 R2: 15 R3: 220 R4: 27 R5: 12 R6: 10 minR delta: 21.2533513149 R1: 10 R2: 18 R3: 22 R4: 68 R5: 33 R6: 39 minR delta: 21.58566448 R1: 10 R2: 18 R3: 27 R4: 75 R5: 33 R6: 36 minR delta: 22.158443806 R1: 10 R2: 18 R3: 27 R4: 82 R5: 33 R6: 36 minR delta: 22.158443806 R1: 10 R2: 18 R3: 27 R4: 82 R5: 33 R6: 39 minR delta: 22.158443806 R1: 10 R2: 18 R3: 33 R4: 75 R5: 27 R6: 18 minR delta: 24.2578084248 R1: 10 R2: 18 R3: 75 R4: 33 R5: 27 R6: 18 minR delta: 24.2578084248 R1: 10 R2: 36 R3: 36 R4: 68 R5: 12 R6: 18 minR delta: 24.380952380 R1: 10 R2: 36 R3: 36 R4: 75 R5: 12 R6: 18 minR delta: 24.380952380 R1: 10 R2: 36 R3: 39 R4: 75 R5: 12 R6: 15 minR delta: 24.380952380 R1: 10 R2: 36 R3: 68 R4: 36 R5: 12 R6: 18 minR delta: 24.380952380 R1: 10 R2: 36 R3: 75 R4: 36 R5: 12 R6: 18 minR delta: 24.380952380 R1: 10 R2: 36 R3: 75 R4: 39 R5: 12 R6: 15 minR delta: 24.380952380 R1: 10 R2: 39 R3: 15 R4: 39 R5: 10 R6: 27 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 22 R4: 47 R5: 10 R6: 22 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 22 R4: 56 R5: 10 R6: 22 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 27 R4: 56 R5: 10 R6: 15 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 39 R4: 15 R5: 10 R6: 27 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 47 R4: 22 R5: 10 R6: 22 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 56 R4: 22 R5: 10 R6: 22 minR delta: 24.4674161824 R1: 10 R2: 39 R3: 56 R4: 27 R5: 10 R6: 15 minR delta: 24.4674161824 R1: 12 R2: 39 R3: 33 R4: 75 R5: 15 R6: 39 minR delta: 24.5467795136 R1: 12 R2: 39 R3: 33 R4: 82 R5: 18 R6: 47 minR delta: 24.789976640 R1: 12 R2: 39 R3: 47 R4: 100 R5: 18 R6: 33 minR delta: 24.789976640 R1: 12 R2: 39 R3: 56 R4: 100 R5: 15 R6: 12 minR delta: 25.3564579616 R1: 12 R2: 39 R3: 100 R4: 56 R5: 15 R6: 12 minR delta: 25.3564579616 R1: 12 R2: 47 R3: 18 R4: 47 R5: 10 R6: 27 minR delta: 27.4996466431 R1: 12 R2: 47 R3: 22 R4: 56 R5: 10 R6: 22 minR delta: 27.4996466431 R1: 12 R2: 47 R3: 27 R4: 56 R5: 10 R6: 18 minR delta: 27.4996466431 R1: 12 R2: 47 R3: 47 R4: 18 R5: 10 R6: 27 minR delta: 27.4996466431 R1: 12 R2: 47 R3: 56 R4: 22 R5: 10 R6: 22 minR delta: 27.4996466431 R1: 12 R2: 47 R3: 56 R4: 27 R5: 10 R6: 18 minR delta: 27.4996466431 R1: 15 R2: 56 R3: 22 R4: 56 R5: 10 R6: 27 minR delta: 29.1605253709 R1: 15 R2: 56 R3: 22 R4: 56 R5: 12 R6: 33 minR delta: 29.811354701 R1: 15 R2: 56 R3: 33 R4: 68 R5: 12 R6: 22 minR delta: 29.811354701 R1: 15 R2: 56 R3: 56 R4: 22 R5: 12 R6: 33 minR delta: 29.811354701 R1: 15 R2: 56 R3: 68 R4: 33 R5: 12 R6: 22 minR delta: 29.811354701 R1: 18 R2: 68 R3: 27 R4: 68 R5: 12 R6: 33 minR delta: 30.7487559507 R1: 18 R2: 68 R3: 33 R4: 68 R5: 12 R6: 27 minR delta: 30.8965517241 R1: 18 R2: 68 R3: 68 R4: 33 R5: 12 R6: 27 minR delta: 30.8965517241 R1: 18 R2: 75 R3: 27 R4: 68 R5: 12 R6: 36 minR delta: 30.9007058823 R1: 18 R2: 75 R3: 47 R4: 91 R5: 12 R6: 10 minR delta: 30.9007058823 R1: 18 R2: 75 R3: 68 R4: 27 R5: 12 R6: 36 minR delta: 30.9007058823 R1: 18 R2: 75 R3: 91 R4: 47 R5: 12 R6: 10 minR delta: 30.9007058823 R1: 22 R2: 82 R3: 36 R4: 82 R5: 15 R6: 39 minR delta: 33.2525545171 R1: 22 R2: 82 R3: 82 R4: 36 R5: 15 R6: 39 minR delta: 33.2525545171 R1: 36 R2: 82 R3: 22 R4: 82 R5: 39 R6: 15 minR delta: 33.2525545171 R1: 36 R2: 82 R3: 82 R4: 22 R5: 39 R6: 15 minR delta: 33.2525545171 R1: 82 R2: 22 R3: 36 R4: 82 R5: 15 R6: 39 minR delta: 33.2525545171 R1: 82 R2: 22 R3: 82 R4: 36 R5: 15 R6: 39 minR delta: 33.2525545171 R1: 82 R2: 36 R3: 22 R4: 82 R5: 39 R6: 15 minR delta: 33.2525545171 R1: 82 R2: 36 R3: 82 R4: 22 R5: 39 R6: 15 minR delta: 33.2525545171 R1: 36 R2: 82 R3: 82 R4: 22 R5: 39 R6: 15 minR delta: 33.2525545171
Step 2: My 4-Button Assembly
For my four buttons I used these buttons and a perforated PCB and resistors as indicated in the diagram above. How you physically implement your four buttons is wide open and up to you and your projects needs. So long as it is electrically what's in the diagram above. Be sure that your construction-mounting is such that you won't make any contact with the wiring to the buttons as that will throw off the readings resulting in erroneous button behavior.
I have an added little button on my board which I use like a 'Function' key. It is in series with a 2 megohm resistor, which does not significantly throw off my other input readings; though I can only detect it when it alone is pressed. You can ignore it or check the code to further understand how I utilize it.
Test sketch 'Test_12Leds_6Btns' can be used to test the detection of button(s) presses by your MCU and actual button assembly. Its output is set to be viewed either with an LED Ladder or the serial monitor. It could easily be modified to output via whatever type of display you may have.
You may need to adjust the code's set of reference readings it compares the input to, due to potential differences in your MCU's internal pull-up resistor or to tolerances of the resistors you use. You could, if you rather, use precision resistors, hopefully to not have to make calibration adjustments. By the way, I did not use an external pull-up as it would interfere with other uses I plan for one of my projects.
One of the key software actions taken, to ensure the determination of which button(s) are pressed is uneffected by the supply voltage level (&/or MCU variance), is to the scale the analog input based on its maximum reading which in turn is affected by the supply voltage.
The software 'driver' which services these buttons is the routine 'scanButtons()'. It waits for the analog input value to settle then maps the reading into a series of the predetermined values; and translates that into the corresponding states for the collection of buttons. This routine, and the public variables it shares with the application software, is all that is needed to make similar use of this set in independent buttons.
Note! The current version of 'scanButtons()' does not try to uniquely identify all of the possible three button combinations as that was, for me, not realistically needed and would further complicate the code and calibration accuracy required.
Step 3: Game Play
Either sketch, 'LadderGames4' or 'Head2head' can be loaded into and run by most any Arduino MCU, but LadderGames4 must have 'SimonSays' or any of the other two games commented out in order to fit in the 8K Bytes of program space in an Attiny-85. Audio is also an issue with an ATtiny-85, see previous project mentioned above. The code is setup with conditional compilation, and is known to work with a Nano, Uno and an ATtiny-85.
With each of these sketches after initialization you are presented with the Menu, with one color at a time lighting all the Red...Yellow...Green...Blue Leds, corresponding to the four possible game choices. You either press Btn1 when the desire option is lit or at any time you press Btn2-4 for games 2-4. The redundant way to select is so as to be compatible with both two and four button implementations & games. If there are multiple versions to the game you will have to select flashing red for ver-1, flashing yellow for ver-2, and so on.
4 Button Games
A game of memory, an eye-hand coordination game, and two strategy games.
This is a re-implementation of the game from the form I had it in, in these earlier projects:
It plays like most any other 'Simon Says' game.
Here though, I did add the two person version (when you select option 2, flashing yellow), where each player, in turn, adds a new light-note to the series. The first one not to correctly repeat all that came before loses the game.
Whack a Mole
For 30 seconds different moles pop up (red, yel, grn, blu) 1,2 or 3 at a time. You must 'whack' them by pressing the corresponding buttons Btn1-4. Only single button presses will be accepted, no simultaneous multiple button presses. How long a set of moles stays up gets shorter as the game goes on. If you whack all the moles showing, then a new set will appear; such that faster you are the more moles you'll have a chance to whack.
Once a game is done the display will reflect the score, lighting one led for each 10 moles that were whacked. As the game scores 10 points for each mole whack, 5 lit leds would represent a standard Whac-a-Mole point score of 500+. To play another round you'll have to re-select the game.
I use a finger on each button for fast action and high scores. For a more proper challenge one should only use one finger on one hand, responding to the use of one mallet.
My typical score using one finger is in the 500s, using 4 fingers (one per button) it is 600+. My highest score is 700+. Using multiple fingers is especially tricky in that if there is an overlap in pressing one and another the second one will not be accepted by the software, requiring you to release all buttons before another will be accepted. If anyone get's all 12 leds to light, for a 1200+ score, please let us know.
There is an unseen submarine moving through the depths. It's initial location and direction is random. It makes a move along its course after each turn you take. You must predict his whereabouts via sonar reports and sink it with a depth-charge. A sonar sounding waves out (in both directions) from its starting location as a dim light and brightens (along with a ping) at the distance of the sub. However note that the sub could be either way of you and is moving in an unknown direction. A depth-charge explodes deep below where it is launched. You hear a muffled explosion if nothing, or is there, else you hear the large explosion of the sub and a bright flash.
To move the cursor led to where you want to drop a sonar buoy or depth-charge is done with Btn2 & Btn3 for left & right. Button-1 is used to launch them.
In version 1, each attempt is a combination depth-charge and sonar report; and you can use an unlimited number of them.
In version 2, Head to head, taking turns, to see who manages to sink the sub. Player 1 uses Btn1 and the second player uses Btn4 to launch their depth-charges.
In version 3, depth-charges and sonar reports are launched independently by Btn1 and Btn4 respectively. You only have three depth-charges available to you. You can get all the sonar reports you want. You lose if you fail to get him with those charges.
In version 4 the sub could be moving at a rate of 1-3 spaces per volley, and otherwise plays like version 3, but you do get 6 depth-charges.
History: I first created the 'Sea Hunt' game in the 1970's. Then the input & output device was a teletype. However, then the sea was a 2 dimensional grid, as opposed to 1 dimensional as it is here.
NOTE: I commented out the depth-charge limiting in the code, with the idea that it was already hard enough to play for most people.
This two player game is a little like Reveri, in that you are trying to turn all the cells to your color, but this is accomplished by differently.
In this two player game, one player's goal is to turn all the lights out, and the other to turn them all on. One player uses Btn1 to either turn a group of the other player's lights off or relinquishes a single one of his “Off lights” (turning it on). The other player uses Btn4 to either turn a group of “Off lights” to On or a single one of his back Off.
The board starts with a random set of leds on. When it's the first player's turn there is a quick dimming or lighting on the led at the 'cursor', point of interest, to potentially be turned. During player #2's turn there is a long flash of an led as a cursor indicator. If the wrong player pushes his button, out of turn, there is a very short beep. The cursor is moved to the left by Btn2 and right by Btn3. The losing player starts the following game.
The strategy as to what to Flip can be significant.
Step 4: Head to Head Contests
Two Button / Two Player Games
In the first set of 4 button games only 'Whack-a-Mole' truly relies on complete independence of the button processing. I also have implemented four head to head games, all of which depend on independent button detection. These games are: Quick Draw, Tug a War, Chicken, and Hot Hands (Slapsies).
Quick Draw (Reaction test)
The contest is started with a 'Ready'/red, 'Set'/yellow, and a 'Draw!'/green; being fairly random as to when it gives you the green light. The first to hit their button wins. Hitting too soon and you are dishonored with a buzz.
Player 1 uses Btn1 (on the left) and player 2 uses Btn4 (on the right).
Tug of War
Starts with a 'Ready', 'Set' … 'GO!'. There appears an object in the middle, a 'bow' on a rope. Then the players hit their buttons as fast and often as they can. The bow will move towards the player with the most hits. Once the bow reaches one end that's the winner.
This contest is started similarly. After the sound & green flash of 'Go!' the players press and hold their buttons, blips of light (their chariots) start moving from them towards the other. The winner is the one who releases his button (jumps out of their chariot) last, just before the two blips would crash into each other. If someone release too late or doesn't at all, they crashed and lose. If both jump (release) too late no one wins.
At the beginning a pair of opposing leds sweep across the display, at this time if you hit Fnc-Btn2 the game speed will be increased. This can be repeated a few times.
A digital version of the hand slapping game (aka Red-Hands or Slapsies). To start the two players press down their buttons together, one side releases then tries to press his button twice before the other side can release his button. Next the other side tries to do similarly. The player whose turn it is is indicated at the start of a round by a lighting of the leds on his side. I found that a one button only push-slap was too fast and easy, So I made two required, which takes more action and time, like having to both flip one's hand over and above the others as well as then slapping down. TBD: In a second version, its a free for all, at anytime either player can try to get the best of the other.
Notice ! I advise you to print out the above games' rules of operation and reread them before you play a game that you have not recently played. Otherwise, you can frustrate yourself; thinking that the game is not operating properly when it fact it is, but you and the game have different ways and expectations. I, myself, have fallen prey to this more than a couple of times.
With the eight games here and the four in my earlier project Single-Line-LED-Display-Games , that makes software available to play 12 games with this four button + led ladder hardware combination.
I have at least four more recreation activities for this (button-display) hardware coming before the end of the year.
Step 5: Optional 2 Player Controllers
For the games which only required two buttons, I could have, of course, used the 4-button PCB with those games; however in playing these games one tends to get quite physical. So, I use separate plunger type button assemblies, made from a piece of plastic tubing covered with a bicycle handle grip and a large button.
Plunger type button parts:
- 1/2" drip line pipe, sprinkler stand-off, or PVC (Hardware store)
- Bicycle handle grip (Walmart)
- Large push buttons (eBay)
- 2 resistors
To maintain compatibility one button has a 75 ohm resistor in series with it and the other has a 36-39 ohm in series; such that the software will see them as Btn1 and Btn4 respectively.
You could use tubing from say a discarded broom or squeegee handle.
An adapter could even be made to which you could connect old game console joy sticks; have one's fire buttons be wired as Btn1 and Btn4 for the other, while sharing Btn1-4 going to the joy sticks' navigation buttons.
April 2018: Now prefer to use 5/8" Compression Couplers as the body for external plunger style buttons.The large buttons (with a little tape over their threads added) fit perfectly in them and they fit in the hand very nicely. As my kids like using a pair of these, I added a couple sets of header pins so as to easily connect one external hand held button across the Bnt1 contacts and one for Btn4.
Step 6: Update(s)
I have combined the 12 games that I created so far, for this 12 LED display, into one sketch 'Menu_12Games'. This software requires this project's hardware implemented with a 32KB flash MCU (e.g. Nano or Uno) and 5 buttons, 4 main + a FncKey.
The selection menu is now two tiered; first you select 1 of 4 groups of games then game 1-4 within that group, … as listed below. While awaiting the select displays scan R-Y-G-B periodically, you press Btn1-4 as your selection at anytime, it makes no difference what's being displayed when you press your selection. During 'group' selection all Leds are at least partially lite during the RYGB scan. To exit any game or back up from 'game' to 'group' selection hit FncKey-Btn1.
I am yet to code up the final 4. I have 3 written up (including 'LeMans'). I have not come up with what the last game would be. Message me with any ideas.
Update 25 Jan 17:
For those of you who enjoy access to a 3D printer, you may be interested in the game console case I made for my device: https://www.instructables.com/id/3D-Printed-Case-for-Inline-LED-Display-Console-and/
Update 17 Feb 17:
I added the finial 4 games, which are now available as "Menu_16Games.ino" under "Step 7: Update, more Games" of the Instructable: Single-Line-LED-Display-Games (Menu_12Games.ino is now defunct)
Group game: 1– Red 2- Yellow 3 – Green 4 – Blue 1 red PushIt PingPong ShootEmUp JumpMan 2 Yel QuickDraw Tug_a_War Chicken Hot_Hands 3 Grn Le_Mans Spray PIG BiFunc 4 Blu SimonSays Whack_Mole Sea_Hunt Flip_d