I have found a way to connect 3 independent switches on a single analog input.
By "independent" I mean that you can open/close any combination of switches and the code will return their individual state.
- We use a ladder of 3 resistors R1, R2, R3 having power-of-two values
- Each resistor has a switch connected in parallel
- The resulting variable resistance forms a bridge with R4
- We measure the voltage of the bridge with an analog input
- The readSwitches() function returns a byte corresponding to the combination of closed switches

Parts list: R1=1K R2=2.2K R3=4.7K R4=6.8K
Code:
// The state of each switch corresponds to a bit in the return value of readSwitches()
const byte SW1 = 0x01;
const byte SW2 = 0x02;
const byte SW3 = 0x04;
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
}
void loop() {
static byte Last_switches_byt = 0xFF;
byte switches_byt = readSwitches(A0);
if (switches_byt != Last_switches_byt) {
// the state of one or more switches has changed
Last_switches_byt = switches_byt;
// display the state of the switches
Serial.print("Sw1="); Serial.print(SW1 & switches_byt ? 1:0);
Serial.print(" Sw2="); Serial.print(SW2 & switches_byt ? 1:0);
Serial.print(" Sw3="); Serial.println(SW3 & switches_byt ? 1:0);
}
delay(10);
}
/* Read the state of the switches connected to given analog input
** Call this function repeatedly in loop()
** there sould be some delay (at least 1Oms) between calls to allow for proper debouncing
** Return value: the state of each switch corresponds to a bit in the return value:
**
Sw1 Sw2 Sw3 Retval Analog reading
x x x 0 552
- x x 1 518
x - x 2 468
- - x 3 420
x x - 4 328
- x - 5 250
x - - 6 128
- - - 7 0
x=open -:closed
*/
byte readSwitches(byte input_byt) {
static byte Retval_byt = 0xFF;
const int Samples_int[] = {552, 518, 468, 420, 328, 250, 128, 0};
// Read the current state of the switches
byte state_byt = 0;
unsigned int sample_int = analogRead(input_byt) & 0xFFFE; // filter noise: ignore least significant bit
while (state_byt < 7) {
int limit_int = Samples_int[state_byt + 1] + ((Samples_int[state_byt] - Samples_int[state_byt + 1]) >> 1);
if (limit_int < sample_int)
break;
else
++state_byt;
}
// Debounce: return the state if it did not change for COUNT calls
const byte COUNT = 4;
static byte Count_byt = 0;
static byte Last_state_byt = 0;
if (Retval_byt == 0xFF)
Retval_byt = state_byt; // first returned value is not debounced, but it is better than returning 0xFF anyway
if (state_byt == Last_state_byt) {
if (++Count_byt == COUNT) {
Retval_byt = state_byt;
Count_byt = 0;
}
}
else
Count_byt = 0;
Last_state_byt = state_byt;
return Retval_byt;
}
Page last modified on October 13, 2014, at 07:01 am
Powered by
PmWiki