Thanks for the reply! Here is the actual code I am using. Pressing different keys makes LED blink on every other keypress (On occasion, repeted keypress on the same key does make the led blink). Comment out line 136 (goToSleep), and the LED blinks on every key press...
#include <Keypad.h>
#include <avr/sleep.h>
const byte ROWS = 3;
const byte COLS = 2;
char keys[ROWS][COLS] = {
{'6','3'},
{'5','2'},
{'4','1'}
};
byte rowPins[ROWS] = { 5, 6, 7 };
byte colPins[COLS] = { 8, 9 };
// number of items in an array for pin re-configuration between sleep and keypad routines
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
const byte ledPin = 13;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// 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 (PCINT21); // pin 5
PCMSK2 |= _BV (PCINT22); // pin 6
PCMSK2 |= _BV (PCINT23); // pin 7
}
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 = keypad.getKey();
if (key)
{
// acknowledgeKeypress(key);
}
else // no key pressed? go to sleep
{
goToSleep ();
return;
}
acknowledgeKeypress(key);
}
void acknowledgeKeypress(byte key) {
for (byte i = 0; i < (key - '0'); i++) {
digitalWrite (ledPin, HIGH);
delay (500);
digitalWrite (ledPin, LOW);
delay (500);
}
}
For the record, I very much like this approach, as it reduces the power consumption of the Arduino Pro Mini 5V/16MHz right away by the factor of 5 - to some 4.5 mA with 9 V battery, with two leds ON, and JY-MCU HC-05 bluetooth client paired; without powerdown, the current form the battery is 19.5 mA (for the purpose of testing the above code, the bluetooth module was not connected).