I should probably just have used a self-centering switch and omitted the feature of it staying in top/bottom.
Lots of options to get what you want. Many types of SPDT or even SPST switches could do the job. Lots of options in code too ... logic, state-change, debouncing, or using 1 or 2 inputs.
Since you already have many unused inputs, the 2-input option is a good choice. Take a look at this for a simple RS latch solution (no debouncing required). Just need to add state-change detection in your code.
Here's a crude example to show the 5 possible states of your switch (tested) ...
// toggle switch
bool up;
bool dn;
bool previousUp;
bool previousDn;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(15, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
}
void loop() {
// update previous status
previousUp = up;
previousDn = dn;
// get current status
up = digitalRead(15);
dn = digitalRead(14);
// now test for the logic conditions
// switch is down
if (up && !dn) {
// code here runs continuously while switch is up
// LED is bright
digitalWrite(LED_BUILTIN, HIGH);
}
// switch is up
if (dn && !up) {
// code here runs continuously while switch is down
// LED is dim
digitalWrite(LED_BUILTIN, HIGH);
delay(1);
digitalWrite(LED_BUILTIN, LOW);
delay(20);
}
// switch is transferring either way
if (up && dn) {
// code here runs while switch is transferring from state to state
// LED blinks quickly 3 times
digitalWrite(LED_BUILTIN, HIGH);
delay(5);
digitalWrite(LED_BUILTIN, LOW);
delay(50);
digitalWrite(LED_BUILTIN, HIGH);
delay(5);
digitalWrite(LED_BUILTIN, LOW);
delay(50);
digitalWrite(LED_BUILTIN, HIGH);
delay(5);
digitalWrite(LED_BUILTIN, LOW);
}
// switch just went up
if (dn && !up && previousUp) {
// code here runs only once
// LED blinks slowly once
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
// switch just went down
if (up && !dn && previousDn) {
// code here runs only once
// LED blinks slowly twice
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
}