I've created a class BAPhysicalControls to make it easier to manage physical controls in audio projects including pots, rotary encoders, switches and outputs (LEDs/relays).

By having controls managed by a class object, it allows code that needs to interact with the controls do so with that single object, rather than using globals or functions with lots of paramters. Switches usually work best with momentary (rather than latching switches) because they are more flexible. A latching switch can be emulated in software from a momentary hardware switch but the reverse is not true.

The class also uses some wrappers around each type to add a little more functionality. Typical use is create an instance of the PhysicalControls, then add() controls to it by registering them to a handle. Use the handle to query the inputs or control the outputs.
// Examples
BAPhysicalControls controls(NUM_SWITCHES, NUM_POTS, NUM_ENCODERS, NUM_LEDS); // This will create the object with enough memory for all the controls you will be adding. Use zero for unused control types.

// Register the controls. For example, 2 switches, 1 pot, 1 encoder, 1 output LEDs
unsigned sw1Handle = controls.addSwitch(SW1_PIN); // SW1_PIN here is the logical pin on the Teensy
unsigned sw2Handle = controls.addSwitch(SW2_PIN);

// Pots require the pin as well as the min and max calibration values. swapDirection depends on pot orientation. E.g. make sure clockwise means increase, not decrease.
// Calibration ensures the range goes all the way from 0.0 to 1.0.
unsigned pot1Handle = controls.addPot(POT1_PIN, min, max, swapDirection); // The logical analog pin number on the Teensy. E.g. A16, A17,etc.
unsigned encoderHandle = controls.addEncoder(PIN_A, PIN_B, swapDirection); // The encoder needs two input pins.
unsigned outputLed = controls.addOutput(LED_PIN);

// Check for switch toggling (pressed and released) or held down (pressed).
// Outputs can be set with setOutput(value) or simply toggled. In this example, turn the LED on whenever the switch is pressed (held down)
if (controls.isSwitchHeld(sw1Handle)) { controls.setOutput(outputLed, 1); }
else { controls.setOutput(outputLed, 0); }

if (controls.isSwitchToggled(sw2Handle)) { // returns true if switch has been pressed and released since last check }

// Pots will return true if changed, and put the new value in the provided float.
float potValue;
if (controls.checkPotValue(pot1Handle, potValue)) { //returns true if new reading is available. potValue is passed by reference so it will be overwritten with the new value }

// Rotary encoders will provide the net change in position since the last call. E.g. -5 means 5 points counterclockwise, +3 is 3 units clockwise, etc. 0 means no change.
if ( controls.getRotaryAdjustUnit(encoderHandle) != 0) { // rotary encoder has moved }
You can find the code in the BALibrary here https://github.com/Blackaddr/BALibrary

The code was written to make it super easy to work with Expansion Control Board for the TGA Pro audio shield. It has controls for 2 switches, 3 pots and 2 LEDs. An example of controlling my Analog Delay effect with this class can be found here.
Click image for larger version. 

Name:	BAPhysicalControls.jpg 
Views:	2 
Size:	57.0 KB 
ID:	14902