"Shift" function button using interrupt.

I was needing a "shift" function button for a bank of buttons to double their functionality. I searched the forums for reading two buttons at the same time, but wasn't happy with the examples I found for what I wanted. So I wrote my own. (Not saying I'm the first to do it this way, just saying I couldn't find an example using this method)

This is just a simple example using two buttons for proof of concept.
Feel free to comment, improve, etc.
Thanks!
-J.R.

/* Demo of using interrupt for "shift" button type functions.
Needed: Arduino, 2 normally open push buttons.
Turn on serial monitor to see functionality.

This is written as an example for beginners - like me :)
This can be easily expanded for more buttons.
I don't have any debounce, but it could easily be added if needed.
*some code copy & pasted from the online tutorials
Jesse Rutherford
jr@bent-tronics.com
2011/01/29
*/

#define button01pin  3  // Button 1 ("shift" button) hooked up to pin 3
#define button02pin  5  // Button 2  hooked up to pin 5

int button02State = 0; 

volatile  int button01State = 0;    // volatile required for interrupt
volatile  int button02State02 = 0;  // volatile required for interrupt

void setup() { 

  pinMode(button01pin, INPUT);           
  digitalWrite(button01pin, HIGH);       // turn on pullup resistor
  pinMode(button02pin, INPUT); 
  digitalWrite(button02pin, HIGH);       // turn on pullup resistor
 

  attachInterrupt(1, doShift, LOW);  // Button 1 ("shift button") on interrupt 1  (pin 3)
  Serial.begin (9600);
  delay(200);
  Serial.println("start");           // just because
  } 
  
  void loop(){
    Serial.println ("stuff");   // simulated main loop code
    // scan button 2 here
    // read the state of the pushbutton value:
    button02State = digitalRead(button02pin);
  
    // check if the pushbutton is pressed.
    // if it is, the buttonState is LOW:
    if (button02State == LOW) {     
    // print function 1
    Serial.println ("function 1");
    }
    delay(1000);                  // wait for a second  
    }
  

  void doShift() {                // interrupt code
    button01State = digitalRead(button01pin);
    button02State02 = digitalRead(button02pin);  // because this is an interrupt,
    // button 2 needs a different variable name from the main loop to function properly
    
    // scan "shift" button and button 2
    if (button01State == LOW && button02State02 == LOW) {
   Serial.println ("shift function 1");
  }   
  }
  //end

The ISR seems a little complicated to me, all you need to know is that the SHIFT button is pressed or not so

volatile boolean shift = false;

void setup () {
 attachInterrupt(1, doShift, CHANGE);  
}

void (loop) {

   if (digitalRead(button02pin)) {
      if (shift) {
        // shift code
     } else {
       // no shift code
     }

}
void doShift() {
  delay (20); // debounce, yeah I know a delay in an ISR, but there's nothing else happening in this example 
  shift = (digitalRead(buttonShift) == LOW ) ? true : false;
}

of course you could just do

 if (digitalRead(button02pin) == LOW) {
      if (digitalRead(button01pin) == LOW) {
        // shift code
     } else {
       // no shift code
     }
}

Rob