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