Sharing 1 interrupt pin between 3 push buttons?

So in my project I need to have 3 buttons trigger an interrupt, yet the ATmega328p only has 2 interrupt pins. So I had the idea of connecting each of the 3 push buttons connect to their own digital pin, then share a interrupt pin. When the interrupt pin is triggered, the ISR will see which of the 3 digital pins was triggered, and subsequently run the appropriate code (using a basic if statement in the ISR). Will this approach work reliably?

Here is my void setup() code:

void setup() {
  pinMode(pin_alarm_switch, INPUT_PULLUP);
  pinMode(pin_pot_1_switch, INPUT_PULLUP);
  pinMode(pin_pot_2_switch, INPUT_PULLUP);
  pinMode(pin_interrupt_1, INPUT_PULLUP);
  attachInterrupt(0, isr, FALLING);
}

And here is my ISR code:

static void isr() {
  if (digitalRead(pin_alarm_switch) == LOW) {
  	alarm_enabled_var = !alarm_enabled_var;
  } else if (digitalRead(pin_pot_1_switch) == LOW) {
  	pot_1_enabled_var = !pot_1_enabled_var;
  } else if (digitalRead(pin_pot_2_switch) == LOW) {
  	pot_2_enabled_var = !pot_2_enabled_var;
  }
}

My main loop then checks if any of the *enabled_var variables are 0 or not 0. (Should I use alarm_enabled var = ~alarm_enabled_var, or leave it how it is? (are they practically the same?))

Cheers.

First question has to be, "are you sure you need interrupts?".

I had the idea of connecting each of the 3 push buttons connect to their own digital pin, then share a interrupt pin

I can't visualise what you are trying to describe. A circuit diagram would help

Ajmar:
So in my project I need to have 3 buttons trigger an interrupt, yet the ATmega328p only has 2 interrupt pins. So I had the idea of connecting each of the 3 push buttons connect to their own digital pin, then share a interrupt pin. When the interrupt pin is triggered, the ISR will see which of the 3 digital pins was triggered, and subsequently run the appropriate code (using a basic if statement in the ISR). Will this approach work reliably?

It should, but I'd use Direct Port Manipulation instead of digitialread(). Much faster -- very important in an ISR.

My main loop then checks if any of the *enabled_var variables are 0 or not 0. (Should I use alarm_enabled var = ~alarm_enabled_var, or leave it how it is? (are they practically the same?))

Hard to say. Since you didn't post a complete code, we don't know how alarm_enabled_var is defined.

EDIT:
Post a schematic as previously requested so we can understand how pressing any one button of three will activate the single interrupt-capable input pin.

Pin change interrupt?
https://playground.arduino.cc/Main/PinChangeInterrupt

PCINTs are the way to go for sure, especially if you want to wake from sleep with them.

Ok here's a circuit diagram: https://i.imgur.com/1RCDQnP.png

And here's the code: Alarm328/alarm_main.cpp at master · etylermoss/Alarm328 · GitHub

Any criticisms welcome (it's my first C/C++ program), though it's not finished yet (have yet to add the main time handling code). Also cheers for the DPM link gfvalvo, though how beneficial is it likely to be? Surely digitalRead() etc. can't add that much overhead, with compiler optimizations, right?

Edit: (Obviously it's supposed to be code for an alarm clock), the 3 switches are to enable / disable potentiometers which can be used to set the time / alarm time, and to enable/disable the alarm. (Haven't commented the code yet).

Ajmar:
Also cheers for the DPM link gfvalvo, though how beneficial is it likely to be? Surely digitalRead() etc. can't add that much overhead, with compiler optimizations, right?

I'm not one to waste my own time. Therefor, I wouldn't have taken the time to look up the link and tell you about it if I didn't think it was worthwhile:

#include "Arduino.h"

void setup() {
  uint32_t startTime, stopTime;
  const uint32_t numIterations = 1000000;
  volatile uint8_t inputPinValue;

  Serial.begin(115200);
  delay(1000);
  Serial.println("Starting");
  Serial.println();

  pinMode(3, INPUT_PULLUP);

  startTime = micros();
  for (uint32_t i = 0; i < numIterations; i++) {
    inputPinValue = digitalRead(3);
  }
  stopTime = micros();
  Serial.print("Using Digital Read: ");
  Serial.print((stopTime - startTime) / (float) numIterations, 3);
  Serial.println(" us per Reading");
  Serial.println();

  startTime = micros();
  for (uint32_t i = 0; i < numIterations; i++) {
    inputPinValue = (PORTD & (1 << PD3)) >> PD3;
  }
  stopTime = micros();
  Serial.print("Using Direct Port Manipulation: ");
  Serial.print((stopTime - startTime) / (float) numIterations, 3);
  Serial.println(" us per Reading");
}

void loop() {
}
Starting

Using Digital Read: 3.773 us per Reading

Using Direct Port Manipulation: 0.755 us per Reading

This suggests that using direct port access is almost 5 times faster.

It would be even faster without the final (usually unnecessary) shift into bit position 0. But, that provides an exact equivalent to the result from digitalRead(0).

Thinking about it some more, and taking into account loop overhead, I think Direct Port Access might be closer to 9 times faster.

Unless the interrupt is triggered at high frequency (above 500Hz) then this kind of optimization is premature.

You could use diodes to connect all 3 pins to the interrupt pin but I would look at Pin Change INTerrupts first.

MorganS why would diodes be needed? Surely the diagram I posted would work as is?

Ajmar:
MorganS why would diodes be needed? Surely the diagram I posted would work as is?

No it won't work. All the buttons are shorted together.

Circuit in post #6

it is not going to work.

According to schematic, it is not definite when the button "stops" been pressed . So, "handling" ISR first time, the interrupt vector is re-activated .

The result may be many times running ISR with one button press.

I’ve done something similar with 3 buttons on 2 pins with interrupt.
CPU sleeps until a pin is fired, then diodes across the buttons give binary 1,2,4 for which one’s pressed.
Do stuff then go back to sleep