Thought i'd share a little project i've been working on. As many may know there is a method for using a single analog pin to control multiple buttons. There is even a library for it. Problem is the way they connect the circuit doesn't allow for the use of button combinations.
So you couldn't press 2 buttons at the same time to perform a different action.
Rather then connecting the resistors in series like that i reorganized it in parallel.
Then i sorted the buttons into a directional pad configuration with 2 action buttons.
Trick was working out which resistors to use on the buttons. If the resistor values are not right then the values read by the analog pin could be too close or overlap on some combos. So here are the possible 2 button combos and values the analog pin will see when the buttons are pressed.
BUTTONS VALUES RESISTORS
btn 1 837-838 220
btn 2 737-738 390
btn 3 610-611 680
btn 4 318-319 2.2k
btn 5 178-179 4.7k
btn 6 91-92 10k
btn 1 + btn 2 896-897
btn 1 + btn 3 877-878
btn 1 + btn 4 851-852
btn 1 + btn 5 844-845
btn 1 + btn 6 840-841
btn 2 + btn 3 821-822
btn 2 + btn 4 769-770
btn 2 + btn 5 753-754
btn 2 + btn 6 745-746
btn 3 + btn 4 674-675
btn 3 + btn 5 643-644
btn 3 + btn 6 627
btn 4 + btn 5 408-409
btn 4 + btn 6 363-364
btn 5 + btn 6 243
Here is the code i put together for using the buttons in this controller configuration.
/*
AnalogButton_Combos
Version 0.1
Connection more then one button to a single analog pin. Utilizing
software debounce to prevent registering multiple button press
while allow for 2 button combos to be registered.
The Circuit:
Most other analog buttons circuits call for the resistors to be
lined up in series from ground. The analog pin and each button
connect off one of the resistors. My cuicuit requires that the
resistors tie in from +5 to the buttons. The buttons all connect
to the analog pin which is tied to ground threw a 1k resistor as
seen in the diagram below.
Analog pin 5
|
Ground--1K--|--------|--------|-------|-------|
| | | | |
btn1 btn2 btn3 btn4 btn5
| | | | |
220 Ohm 390 Ohm 680 Ohm 2.2K 4.7K
|--------|--------|-------|-------|-- +5V
Created By: Michael Pilcher
February 24, 2010
*/
int j = 1; // integer used in scanning the array designating column number
//2-dimensional array for asigning the buttons and there high and low values
int Button[21][3] = {{1, 837, 838}, // button 1
{2, 737, 738}, // button 2
{3, 610, 611}, // button 3
{4, 318, 319}, // button 4
{5, 178, 179}, // button 5
{6, 91, 92}, // button 6
{7, 896, 897}, // button 1 + button 2
{8, 877, 878}, // button 1 + button 3
{9, 851, 852}, // button 1 + button 4
{10, 844, 845}, // button 1 + button 5
{11, 840, 841}, // button 1 + button 6
{12, 821, 822}, // button 2 + button 3
{13, 769, 770}, // button 2 + button 4
{14, 753, 754}, // button 2 + button 5
{15, 745, 746}, // button 2 + button 6
{16, 674, 675}, // button 3 + button 4
{17, 643, 644}, // button 3 + button 5
{18, 627, 627}, // button 3 + button 6
{19, 408, 409}, // button 4 + button 5
{20, 363, 364}, // button 4 + button 6
{21, 243, 243}}; // button 5 + button 6
int analogpin = 5; // analog pin to read the buttons
int label = 0; // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0; // the last time the output pin was sampled
int debounce_count = 50; // number of millis/samples to consider before declaring a debounced input
int current_state = 0; // the debounced input value
int ButtonVal;
void setup()
{
Serial.begin(9600);
}
void loop()
{
// If we have gone on to the next millisecond
if (millis() != time)
{
// check analog pin for the button value and save it to ButtonVal
ButtonVal = analogRead(analogpin);
if(ButtonVal == current_state && counter >0)
{
counter--;
}
if(ButtonVal != current_state)
{
counter++;
}
// If ButtonVal has shown the same value for long enough let's switch it
if (counter >= debounce_count)
{
counter = 0;
current_state = ButtonVal;
//Checks which button or button combo has been pressed
if (ButtonVal > 0)
{
ButtonCheck();
}
}
time = millis();
}
}
void ButtonCheck()
{
// loop for scanning the button array.
for(int i = 0; i <= 21; i++)
{
// checks the ButtonVal against the high and low vales in the array
if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
{
// stores the button number to a variable
label = Button[i][0];
Action();
}
}
}
void Action()
{
if(label == 1)
{
Serial.println("Up Button");
}
if(label == 2)
{
Serial.println("Down Button");
}
if(label == 3)
{
Serial.println("Left Button");
}
if(label == 4)
{
Serial.println("Right Button");
}
if(label == 5)
{
Serial.println("Action Button #1");
}
if(label == 6)
{
Serial.println("Action Button #2");
}
if(label == 8)
{
Serial.println("Left and Up Buttons");
}
if(label == 9)
{
Serial.println("Right and Up Buttons");
}
if(label == 12)
{
Serial.println("Left and Down Buttons");
}
if(label == 13)
{
Serial.println("Right and Down Buttons");
}
if(label == 21)
{
Serial.println("Action Buttons #1 and #2");
}
//Serial.println("Button =:");
//Serial.println(label);
//delay(200);
}
Next i will be working on a nice 12 button keypad using this method. Sure you can get a 12 button keypad now but you'll be using row and column scanning to detect the buttons which takes up 7 digital I/O pins. With this analog button method i can have a 12 button keypad that only needs +5, Ground and a single analog pin. And this keypad will be able to accept button combinations. Hard part will be working out the best resistor values for it, the possible button combos and analog values. Not that a keypad would have much use for combos but it will be there. Besides the pad could always be used as a directional pad too.