Connect 3 independent Switches to the Arduino using a single analog input pin

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