Thank you everyone for your replies, I really appreciate them.
I'm using Mega 2560 Pro MINI for its high pin count and ease of programming.
The device switches 5 guitar amplifiers and 2 speaker cabinets. There is one input socket for a guitar, 5 output (send) sockets to distribute that guitar input to one of the 5 guitar amps. Then there are 5 input (return) sockets from the guitar amplifiers' speaker outputs which route to a final relay that sends that amp's signal to either speaker cab A or B.
There are 7 buttons on the front panel: amps 1-5, cab A/B and random. Tube/valve guitar amps can be damaged if there is signal on their input and they are not connected to a load so a short pause is required between each switching (hence using Arduino instead of simple mechanical switch). That is also why I am checking if the sockets are occupied (using the switch contacts of the jack sockets) before switching to them.
It's not life-or-death stuff, but I really don't want to blow up guitar amps, hence these precautions.
This is the basic pseudocode I've started. Please forgive me for the inconsistent naming conventions used in it (but see at the bottom if you are curious to actual I/O pin names).
[MAIN FUNCTION LOOP:]
If amp button #X is pressed:
If amp socket #X contact == high (socket occupied)
Set channel state variable to #X,
extinguish all 5 amp button LEDs,
mute all GTR send relays,
wait 50ms,
mute all amp return relays,
wait 50ms,
engage amp return relay #X,
wait 50ms,
engage GTR send relay #X,
illuminate button LED #X.
else
flash button LED #X three times (to indicate channel can't be selected),
illuminate original button LED. (original needs to be saved as a variable)
When cab button is pressed:
If cab state variable == A (red LED)
If cab socket B contact == high (socket occupied)
mute all GTR send relays,
wait 50ms,
mute all amp return relays,
wait 50ms,
set cab relay to B (high)
wait 50ms,
engage amp return relay #X,
wait 50ms,
engage GTR send relay #X,
illuminate GREEN cab button LED,
set cab state variable to B,
return to MAIN FUNCTION.
else
flash cab B LED (GREEN) three times,
illuminate cab A LED (RED).
If cab state variable == B (green LED)
If cab socket A contact == high (socket occupied)
mute all GTR send relays,
wait 50ms,
mute all amp return relays,
wait 50ms,
set cab relay to A (low)
wait 50ms,
engage amp return relay #X,
wait 50ms,
engage GTR send relay #X,
illuminate RED cab button LED,
set cab state variable to A,
return to MAIN FUNCTION.
else
flash cab A LED (RED) three times,
illuminate cab B LED (GREEN).
If Random button is pressed:
Check which amp return sockets are occupied (high), then randomly choose one of them (with the standard Mute, Wait, Mute, Wait, Engage amp return, Wait, Engage GTR send, but don't illuminate the corresponding amp button LED)
If random button is pressed again,
Illuminate the corresponding amp button LED.
[END OF MAIN LOOP]
[INTERRUPTS]
If, at any time, any socket switch contacts go low:
mute all GTR send relays,
wait 50ms,
mute all amp return relays,
then flash the corresponding button LED for the amp channel (or cab button LED red or green for SKT_A or SKT_B)
And the setup section:
const IP_SPK_SKT_1 = A14; //interrupt
const IP_SPK_SKT_2 = A12; //interrupt
const IP_SPK_SKT_3 = A10; //interrupt
const IP_SPK_SKT_4 = A13; //interrupt
const IP_SPK_SKT_5 = A8; //interrupt
const IP_SPK_SKT_A = A9; //interrupt
const IP_SPK_SKT_B = A11; //interrupt
const int IP_AMP_SW_1 = 35;
const int IP_AMP_SW_2 = 37;
const int IP_AMP_SW_3 = 39;
const int IP_AMP_SW_4 = 41;
const int IP_AMP_SW_5 = 43;
const int IP_RAND_SW = 45;
const int IP_CAB_SW = 47;
const int OP_AMP_SW_LED_1 = 2; //pwm
const int OP_AMP_SW_LED_2 = 4; //pwm
const int OP_AMP_SW_LED_3 = 6; //pwm
const int OP_AMP_SW_LED_4 = 8; //pwm
const int OP_AMP_SW_LED_5 = 10; //pwm
const int OP_RAND_SW_LED = 12; //pwm
const int OP_CAB_SW_LED_R = 14; //cab button has RGB LED
const int OP_CAB_SW_LED_G = 16;
const int OP_CAB_SW_LED_B = 18;
const int OP_GTR_RLY_1 = 22;
const int OP_GTR_RLY_2 = 24;
const int OP_GTR_RLY_3 = 26;
const int OP_GTR_RLY_4 = 28;
const int OP_GTR_RLY_5 = 30;
const int OP_SPK_RLY_1 = 33;
const OP_SPK_RLY_2 = A15;
const OP_SPK_RLY_3 = A5;
const OP_SPK_RLY_4 = A3;
const OP_SPK_RLY_5 = A1;
const int OP_CAB_RLY = 20;
void setup() {
pinMode(IP_SPK_SKT_1, INPUT):
pinMode(IP_SPK_SKT_2, INPUT):
pinMode(IP_SPK_SKT_3, INPUT):
pinMode(IP_SPK_SKT_4, INPUT):
pinMode(IP_SPK_SKT_5, INPUT):
pinMode(IP_SPK_SKT_A, INPUT):
pinMode(IP_SPK_SKT_B, INPUT):
pinMode(IP_AMP_SW_1, INPUT):
pinMode(IP_AMP_SW_2, INPUT):
pinMode(IP_AMP_SW_3, INPUT):
pinMode(IP_AMP_SW_4, INPUT):
pinMode(IP_AMP_SW_5, INPUT):
pinMode(IP_RAND_SW, INPUT):
pinMode(IP_CAB_SW, INPUT):
pinMode(OP_GTR_RLY_1, OUTPUT):
pinMode(OP_GTR_RLY_2, OUTPUT):
pinMode(OP_GTR_RLY_3, OUTPUT):
pinMode(OP_GTR_RLY_4, OUTPUT):
pinMode(OP_GTR_RLY_5, OUTPUT):
pinMode(OP_SPK_RLY_1, OUTPUT):
pinMode(OP_SPK_RLY_2, OUTPUT):
pinMode(OP_SPK_RLY_3, OUTPUT):
pinMode(OP_SPK_RLY_4, OUTPUT):
pinMode(OP_SPK_RLY_5, OUTPUT):
pinMode(OP_CAB_RLY, OUTPUT):
pinMode(OP_AMP_SW_LED_1, OUTPUT):
pinMode(OP_AMP_SW_LED_2, OUTPUT):
pinMode(OP_AMP_SW_LED_3, OUTPUT):
pinMode(OP_AMP_SW_LED_4, OUTPUT):
pinMode(OP_AMP_SW_LED_5, OUTPUT):
pinMode(OP_RAND_SW_LED, OUTPUT):
pinMode(OP_CAB_SW_LED_R, OUTPUT):
pinMode(OP_CAB_SW_LED_G, OUTPUT):
pinMode(OP_CAB_SW_LED_B, OUTPUT):
//set all outputs to off
digitalWrite(OP_GTR_RLY_1, LOW);
digitalWrite(OP_GTR_RLY_2, LOW);
digitalWrite(OP_GTR_RLY_3, LOW);
digitalWrite(OP_GTR_RLY_4, LOW);
digitalWrite(OP_GTR_RLY_5, LOW);
digitalWrite(OP_SPK_RLY_1, LOW);
digitalWrite(OP_SPK_RLY_2, LOW);
digitalWrite(OP_SPK_RLY_3, LOW);
digitalWrite(OP_SPK_RLY_4, LOW);
digitalWrite(OP_SPK_RLY_5, LOW);
digitalWrite(OP_CAB_RLY, LOW);
analogWrite(OP_AMP_SW_LED_1, 0); // analogWrite(pin, dutyCycle)
analogWrite(OP_AMP_SW_LED_2, 0);
analogWrite(OP_AMP_SW_LED_3, 0);
analogWrite(OP_AMP_SW_LED_4, 0);
analogWrite(OP_AMP_SW_LED_5, 0);
analogWrite(OP_RAND_SW_LED, 0);
digitalWrite(OP_CAB_SW_LED_R, HIGH);
digitalWrite(OP_CAB_SW_LED_G, LOW);
digitalWrite(OP_CAB_SW_LED_B, LOW);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_1), unplugged_1, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_2), function_name, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_3), function_name, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_4), function_name, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_5), function_name, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_A), function_name, FALLING);
attachInterrupt(digitalPinToInterrupt(IP_SPK_SKT_B), function_name, FALLING);
Check if IP_SPK_SKT_A is high, if not, check if IP_SPK_SKT_B is high, if not STOP - flash cab button LEDs red,green,red,green.. until one of them is high.
//If no guitar speaker cabinet is connected, DO NOT PROCEED.
Once a cab is connected, set the cab button LED accordingly (red for SKT A, green for SKT B), then set cab state variable to A or B accordingly.
}