Interfacing a tristate switch with one µC pin

This is just a little trick I have not seen anywhere before, so I thought I might as well share it with the world.

If you have a switch with three states, such as an on-off-on switch and you only want to use one microcontroller pin, this is how you can do it:

tristate switch

The image shows the basic setup. Resistor values are given for Atmel controllers, but this should also work for PICs and other µCs.

If the switch is connected to Vcc the input reads high, if it is connected to GND, it reads low. But if the switch is in its open setting, the reading is depending on the pullup resistor beeing switch on or not. This can be used to recognize all three states: high, low and open.

Here is a pseudo c example:

uint8_t getPin(uint8_t num)
{
    setPullup(num, OFF);
    if(readPin(num) == HIGH)
        return 0;                //input is connected to Vcc
    setPullup(num, ON);
    if(readPin(num) == HIGH)
        return 1;                //input is open
    return 2;                    //input is connected to GND
}
symbols are from this site

 

Update 2019:

Just found this old blog post, though I’d update it a bit:
if you are using a µC which has both, pullup and pulldown (STM32 for example), you can of neglect the external resistor.