Interrupt pin in Key pad

Please tell me is there any way to define interrupt keys in key pad. I cannot use pin 2 and 3 as interrupts because I had to use rotary encoder to my UNO. But i use a key pad to my project. So please tell me is any way to define interrupt pin in key pad.
Thankyou

Pin change interrupt

I don't think I'm fully understanding what you're asking.

Are you saying that you'd like any press of a key on a keypad to generate an interrupt so that the key press can be detected and handled?

And if so, what key pad are you using?

Why do you (think that you) need an interrupt?

Here is a demo that Nick Gammon wrote 9 years ago. I kept it because I thought it would come in handy some day.

SleepyKeypad.ino

// Wake from deep sleep with a keypress demonstration

// Author: Nick Gammon
// Date: 18th November 2012

#include <Keypad.h>
#include <avr/sleep.h>

const byte ROWS = 4;
const byte COLS = 4; 

char keys[] = {
  "123A"
  "456B"
  "789C"
  "*0#D"
};

byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

// number of items in an array
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

const byte ledPin = 13;

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

/*

 Pin change interrupts.
 
 Pin                  Mask / Flag / Enable
 
 D0	  PCINT16 (PCMSK2 / PCIF2 / PCIE2)
 D1	  PCINT17 (PCMSK2 / PCIF2 / PCIE2)
 D2	  PCINT18 (PCMSK2 / PCIF2 / PCIE2)
 D3	  PCINT19 (PCMSK2 / PCIF2 / PCIE2)
 D4	  PCINT20 (PCMSK2 / PCIF2 / PCIE2)
 D5	  PCINT21 (PCMSK2 / PCIF2 / PCIE2)
 D6	  PCINT22 (PCMSK2 / PCIF2 / PCIE2)
 D7	  PCINT23 (PCMSK2 / PCIF2 / PCIE2)
 D8	  PCINT0 (PCMSK0 / PCIF0 / PCIE0)
 D9	  PCINT1 (PCMSK0 / PCIF0 / PCIE0)
 D10	  PCINT2 (PCMSK0 / PCIF0 / PCIE0)
 D11	  PCINT3 (PCMSK0 / PCIF0 / PCIE0)
 D12	  PCINT4 (PCMSK0 / PCIF0 / PCIE0)
 D13	  PCINT5 (PCMSK0 / PCIF0 / PCIE0)
 A0	  PCINT8 (PCMSK1 / PCIF1 / PCIE1)
 A1	  PCINT9 (PCMSK1 / PCIF1 / PCIE1)
 A2	  PCINT10 (PCMSK1 / PCIF1 / PCIE1)
 A3	  PCINT11 (PCMSK1 / PCIF1 / PCIE1)
 A4	  PCINT12 (PCMSK1 / PCIF1 / PCIE1)
 A5	  PCINT13 (PCMSK1 / PCIF1 / PCIE1)
 
 */

// we don't want to do anything except wake
EMPTY_INTERRUPT (PCINT0_vect)
EMPTY_INTERRUPT (PCINT1_vect)
EMPTY_INTERRUPT (PCINT2_vect)

void setup ()
{
  pinMode (ledPin, OUTPUT);

  // pin change interrupt masks (see above list)
  PCMSK2 |= _BV (PCINT22);   // pin 6
  PCMSK2 |= _BV (PCINT23);   // pin 7
  PCMSK0 |= _BV (PCINT0);    // pin 8
  PCMSK0 |= _BV (PCINT1);    // pin 9

}  // end of setup

// set pins as keypad library expects them
// or call: kpd.initializePins ();
//    however in the library I have that is a private method

void reconfigurePins ()
{
  byte i;

  // go back to all pins as per the keypad library

  for (i = 0; i < NUMITEMS (colPins); i++)
  {
    pinMode (colPins [i], OUTPUT);
    digitalWrite (colPins [i], HIGH); 
  }  // end of for each column 

  for (i = 0; i < NUMITEMS (rowPins); i++)
  {
    pinMode (rowPins [i], INPUT);
    digitalWrite (rowPins [i], HIGH); 
  }   // end of for each row

}  // end of reconfigurePins

void goToSleep ()
{
  byte i;

  // set up to detect a keypress
  for (i = 0; i < NUMITEMS (colPins); i++)
  {
    pinMode (colPins [i], OUTPUT);
    digitalWrite (colPins [i], LOW);   // columns low
  }  // end of for each column

  for (i = 0; i < NUMITEMS (rowPins); i++)
  {
    pinMode (rowPins [i], INPUT);
    digitalWrite (rowPins [i], HIGH);  // rows high (pull-up)
  }  // end of for each row

  // now check no pins pressed (otherwise we wake on a key release)
  for (i = 0; i < NUMITEMS (rowPins); i++)
  {
    if (digitalRead (rowPins [i]) == LOW)
    {
      reconfigurePins ();
      return; 
    } // end of a pin pressed
  }  // end of for each row

  // overcome any debounce delays built into the keypad library
  delay (50);

  // at this point, pressing a key should connect the high in the row to the 
  // to the low in the column and trigger a pin change

  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();

  byte old_ADCSRA = ADCSRA;
  // disable ADC to save power
  ADCSRA = 0;  

  PRR = 0xFF;  // turn off various modules

  PCIFR  |= _BV (PCIF0) | _BV (PCIF1) | _BV (PCIF2);   // clear any outstanding interrupts
  PCICR  |= _BV (PCIE0) | _BV (PCIE1) | _BV (PCIE2);   // enable pin change interrupts

  // turn off brown-out enable in software
  MCUCR = _BV (BODS) | _BV (BODSE);
  MCUCR = _BV (BODS); 
  sleep_cpu ();  

  // cancel sleep as a precaution
  sleep_disable();
  PCICR = 0;  // cancel pin change interrupts
  PRR = 0;    // enable modules again
  ADCSRA = old_ADCSRA; // re-enable ADC conversion

  // put keypad pins back how they are expected to be
  reconfigurePins ();

}  // end of goToSleep

void loop () 
{

  byte key =  kpd.getKey();
  if (!key)
  {
    // no key pressed? go to sleep
    goToSleep ();
    return;
  }

  // confirmation we woke - flash LED number of times
  // for the appropriate pin (eg. pin 1: one time) 
  for (byte i = 0; i < (key - '0'); i++)
  {
    digitalWrite (ledPin, HIGH);
    delay (500); 
    digitalWrite (ledPin, LOW);
    delay (500); 
  }  // end of for loop

} // end of loop

That was before INPUT_PULLUP so to modernize it you would replace:

    pinMode (rowPins [i], INPUT);
    digitalWrite (rowPins [i], HIGH);  // rows high (pull-up)

with
pinMode (rowPins [i], INPUT_PULLUP);

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.