user23610: I need an answer fast.I want to make a keyboard class to handle a few buttons attached to my arduino. I want to use interrupts.The problem is I have to use the same interrupt function for all my buttons(it would beimpractical to create a routine for each button).So inside the routine I must know at least what pin fired the interrupt. How can I solve this?(I belive it can be solved by changing some registers but that would be too complicated).PS:there are only two buttons(pins 2 and 3 are enough)
Edit:
   Isn't possible to create/call an interrupt routine inside a class? (I know that the routine actually doesn't exist initially because the object of the class type wasn't created). Can this be done?
class Keyboard{
  private:
    struct btn{
      boolean pressed;
      uint32_t pressTime;
    };
    btn button1;

  public:
    void int_handler(){

    }
    Keyboard(){
      attachInterrupt(digitalPinToInterrupt(2),this->int_handler,RISING);
      attachInterrupt(digitalPinToInterrupt(3),this->int_handler,RISING);
    }
};


user23610: I solved this in a more..compressed way.
I already store the state of the buttons(pushed down or up-that is if they set their connected pin to 0 or 1).So I can have a single routine called by the microcontroller and then inside it decide what pin changed states(clever):
#define btn1Pin 2
#define btn2Pin 3

class Timer{
  //....
};
uint32_t Timer::start_time;
class KeyboardBtn{
  private:
    const static byte clicksDelay=255;
    struct btn{
      byte state=1;   //(0-keyDown / 1-keyUp) 2-Click 
      byte pin;
      Timer clickLapse;
    };
    volatile static btn buttons[2];

  public:  
    KeyboardBtn(){
      buttons[0].pin=btn1Pin;
      buttons[1].pin=btn2Pin;
      attachInterrupt(digitalPinToInterrupt(btn1Pin),keyPress,CHANGE );
      attachInterrupt(digitalPinToInterrupt(btn2Pin),keyPress,CHANGE );
    }
    static void keyPress(){
      //digitalRead ==1 then button up
      for(int i=0;i<2;i++){
        if(bitRead(buttons[i].state,0)==digitalRead(buttons[i].pin)) continue;
        //i is the switched button
      }
    }
    byte stateChanged(byte key){
      //code
    }
};
volatile KeyboardBtn::btn KeyboardBtn::buttons[2];

KeyboardBtn btn;
void setup() {
  pinMode(btn1Pin,INPUT_PULLUP);
  pinMode(btn2Pin,INPUT_PULLUP);
}

void loop(){
}


user10794: You only have two external interrupts on the Uno, so a simple solution would be to call an "intermediate" routine, which remembers the button number. eg.
  attachInterrupt(digitalPinToInterrupt(2),this->int_handler2,RISING);
  attachInterrupt(digitalPinToInterrupt(3),this->int_handler3,RISING);

Those two functions could then call your main function passing down 2 or 3 depending on which one was called.
eg.
void int_handler2 ()
  {
  int_handler (2);
  }

void int_handler3 ()
  {
  int_handler (3);
  }

If you have more switches than that you can use pin-change interrupts. The typical way of detecting which one fired is to see which bits are different this time, compared to last time.
See my page about interrupts.

23610: <p>I need an answer fast.I want to make a keyboard class to handle a few buttons attached to my arduino. I want to use interrupts.The problem is I have to use the same interrupt function for all my buttons(it would beimpractical to create a routine for each button).So inside the routine I must know at least what pin fired the interrupt. How can I solve this?(I belive it can be solved by changing some registers but that would be too complicated).PS:there are only two buttons(pins 2 and 3 are enough)</p>

<p>Edit:
   Isn't possible to create/call an interrupt routine inside a class? (I know that the routine actually doesn't exist initially because the object of the class type wasn't created). Can this be done?</p>

<pre><code>class Keyboard{
  private:
    struct btn{
      boolean pressed;
      uint32_t pressTime;
    };
    btn button1;

  public:
    void int_handler(){

    }
    Keyboard(){
      attachInterrupt(digitalPinToInterrupt(2),this-&gt;int_handler,RISING);
      attachInterrupt(digitalPinToInterrupt(3),this-&gt;int_handler,RISING);
    }
};
</code></pre>
 23610: <p>I solved this in a more..compressed way.
I already store the state of the buttons(pushed down or up-that is if they set their connected pin to 0 or 1).So I can have a single routine called by the microcontroller and then inside it decide what pin changed states(clever):</p>

<pre><code>#define btn1Pin 2
#define btn2Pin 3

class Timer{
  //....
};
uint32_t Timer::start_time;
class KeyboardBtn{
  private:
    const static byte clicksDelay=255;
    struct btn{
      byte state=1;   //(0-keyDown / 1-keyUp) 2-Click 
      byte pin;
      Timer clickLapse;
    };
    volatile static btn buttons[2];

  public:  
    KeyboardBtn(){
      buttons[0].pin=btn1Pin;
      buttons[1].pin=btn2Pin;
      attachInterrupt(digitalPinToInterrupt(btn1Pin),keyPress,CHANGE );
      attachInterrupt(digitalPinToInterrupt(btn2Pin),keyPress,CHANGE );
    }
    static void keyPress(){
      //digitalRead ==1 then button up
      for(int i=0;i&lt;2;i++){
        if(bitRead(buttons[i].state,0)==digitalRead(buttons[i].pin)) continue;
        //i is the switched button
      }
    }
    byte stateChanged(byte key){
      //code
    }
};
volatile KeyboardBtn::btn KeyboardBtn::buttons[2];

KeyboardBtn btn;
void setup() {
  pinMode(btn1Pin,INPUT_PULLUP);
  pinMode(btn2Pin,INPUT_PULLUP);
}

void loop(){
}
</code></pre>
 10794: <p>You only have two external interrupts on the Uno, so a simple solution would be to call an "intermediate" routine, which remembers the button number. eg.</p>

<pre><code>  attachInterrupt(digitalPinToInterrupt(2),this-&gt;int_handler2,RISING);
  attachInterrupt(digitalPinToInterrupt(3),this-&gt;int_handler3,RISING);
</code></pre>

<p>Those two functions could then call your main function passing down 2 or 3 depending on which one was called.</p>

<p>eg.</p>

<pre><code>void int_handler2 ()
  {
  int_handler (2);
  }

void int_handler3 ()
  {
  int_handler (3);
  }
</code></pre>

<p>If you have more switches than that you can use pin-change interrupts. The typical way of detecting which one fired is to see which bits are different this time, compared to last time.</p>

<p>See <a href="http://www.gammon.com.au/interrupts" rel="nofollow noreferrer">my page about interrupts</a>.</p>
