Go Down

Topic: "Shift" function button using interrupt. (Read 3560 times) previous topic - next topic


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.
Code: [Select]

/* 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

#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);
  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");


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

Code: [Select]
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

Code: [Select]
if (digitalRead(button02pin) == LOW) {
      if (digitalRead(button01pin) == LOW) {
        // shift code
     } else {
       // no shift code

Rob Gray aka the GRAYnomad www.robgray.com

Go Up