Multiple switch inputs using single interrupt-capable digital IO

Hi everyone,

I’m new here so I hope I’m posting this in the right place.
I was working on a simple project and wanted to implement 3 switch button inputs using interrupt-capable inputs. I found out that the ATMEGA on the UNO only has two such inputs (2 and 3).
I was trying to figure a simple way to overcome this limitation under the assumption that only one button is pressed at any given time. I was trying to do this with components I had at hands from the Starter Kit.
The way I solved this is shown in the attached figure.
Follow the wires and components connected to inputs 3 and 4.
Input 3 is connected to a 10K pull-down and a switch, which, when pressed, connects input 3 to VCC.
Input 3 is also connected to the Emitter of a BC547, where the Collector is connected to VCC.
The Base of the BC547 is connected to Input 4, and to another switch, which, when pressed, connects the Base to VCC, thus turning the BC547 “on”.
How does this work:
Input 3 gets triggered when either switch S2 or swith S3 is pressed. In both case, an interrupt would be triggered. However, in the respective interrupt service routine (ISR), I check the status of inputs 3 and 4, and the one in a HIGH state I consider as the source of the interrupt. Of course I’m assuming that the inputs that triggered the interrupt is still in a high state in the ISR because a human press is relatively long…
Inside the ISR is it possible to decide how to handle in case both inputs are identified in a HIGH state. One way would be to handled this as another user input option - two switches pressed at the same time indicating something specific. Another way would be to prioritize - in case both are HIGH, only act on one of them, per your own choice.
I thought I’d share this since I didn’t find any such hint when I tried to “solve” my problem.
The following code extract is an example how to handle this:

const byte  modeSwitch = 2;
const byte  setSwitch = 3;
const byte  set2Switch = 4;

void setup() {

  pinMode (modeSwitch , INPUT);  // Input 2
  pinMode (setSwitch , INPUT);      // Input 3
  pinMode (set2Switch , INPUT);    // Input 4

  // Setup IRQ on switch press
  attachInterrupt(digitalPinToInterrupt(modeSwitch), modeSwitchISR, RISING);
  attachInterrupt(digitalPinToInterrupt(setSwitch), setSwitchISR, RISING);

}

// ISR for Mode switch and Fwd switch - S1
void modeSwitchISR () {
   // Do whatever is needed on the press of S1
}

// ISR for Secondary Set switch - S2 and S3
void setSwitchISR () {
  set2Input = digitalRead(set2Switch);
  if (set2Input) {   // Note: in this code S3 is given priority in case both 2 and 3 are pressed
    // Do whatever is needed on the press of S3
  } else {
    // Do whatever is needed on the press of S2
  }
}

I hope this may help some of you.
Questions are welcome.

Ilanmar

I don't understand. Switches rarely need to be handled at interrupt speed, sampling in the loop() function is usually sufficient. Furthermore, most inputs have pin change interrupts, not just 2 and 3.

With the switches between pin and ground, and internal pin pull up, you don't need resistors.

Your way (changing logic of two pins) can then be done with one diode (nothing else).
Leo..

Thanks guys for the feedback.
Right - I could use the internal pull-ups with opposite switch polarity.
vaj4088 - true...I should have looked into the datasheet rather than rely on what the web told me. There are indeed many interrupt-capable inputs. So I was indeed trying to solve a problem that doesn't exist.
Another comment I got which is true - connecting switch directly to interrup capable pins is risky due to bouncing. This should of course be taken into considertion if one does decide to do something like this.
For my simple circuit this works fine.
Thanks again.