Need interrupt help - can't get out of sleep mode

Hi gang,
I’ve got this code running for an RF remote control - -0019, Duemilanove, data to RF TX module from pin 12, 4x4 Matrix keypad with rows on D3,4,5,6, columns on 7,8,9,10 - only I can’t get any interrupts to work once it goes into sleep mode.
I have the Row lines connected via DiodeOr like in Simon Bell’s example
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283692181
and I copied placement of interrupt code, with a do-nothing interrupt handler - I just want to wakeup.

The references to Plan B imply a Plan A - that was to make PCInt work on the Row pins, as I have remote built up that I wanted to add this power reduction feature into.
Gave up, now have this other attempt with diodes to pull down the interrupt on Pin2 on a protoboard, thinking simpler s/w, still no go.

Nothing seems to work - once in sleep mode, all the pins seem to be good & high so that the keypad cannot pull anything low. I tried adding pulldown resistors to the column pins, no help. Not even shorting interrupt pin D2 directly to ground will let this thing wake up.

Please help! Many thanks in advance!

// transmitter_mine_updated_Simon_Bell_DiodeOr.pde

// Processor: Duemilanove running on PC USB power
// (ran on 3 AA batteries fed into VCC line prior to this Interrupt attempt)
// Keypad: Velleman 4x4 Matrix
// RF Link Transmitter - Sparkfun MO-SAWR-A, 434MHz, WRL-08946

// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with TX module. 

// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

// uses default pin 12 for transmit data
// uses default pin 11 for receive data

// added Keypad example from playground
// modified to send character in a buffer to the receiver from 4x4 matrix

// Velleman column keypad 1 (Col1) to D10
// keypad 2 (Col2) to D9
// keypad 3 (Col3) to D8
// keypad 4 (Col4) to D7
// keypad 5 (Row1) to D6
// keypad 6 (Row2) to D5
// keypad 7 (Row3) to D4
// keypad 8 (Row4) to D3

// Rows have 22K external pullups currently, discovered Internal Pullups after prototype was wired
// started with the code from this example
// http://www.arduino.cc/playground/Learning/arduinoSleepCode

// with sleep function called -> 0.357mA! should be 175 days on 1500mAH batteries
// down from 8.95 mA in normal idle mode  -> just 7 days
// with bursts of ~14-15mA when a keypress is transmitted

// Plan B: Row 1, 2, 3, 4 Diode OR'd to D2 (INT0) to pull it low on a keypress

// Interrupt on D2 "wakePin" LOW - set up as Input with Internal pullup

// D0, D1, D14, D15, D16, D17, D18, D19 set as inputs with internal pullups enabled

// end of notes
// ********************************************************

// bring in the library(s)
#include <VirtualWire.h> // Wireless transmitter/receiver library
#include <Keypad.h>      // Matrix Keypad library
#include <avr/sleep.h>   // powerdown library

// ********************************************************

// define unused pins
int dpin0 = 0;   // apparently redefined by Serial as Serial Monitor works
int dpin1 = 1;   // apparently redefined by Serial as Serial Monitor works
int wakePin = 2;  // redefine as the interrupt pin (wakePin) for Plan B
int dpin14 = 14;
int dpin15 = 15;
int dpin16 = 16;
int dpin17 = 17;
int dpin18 = 18;
int dpin19 = 19;

// ********************************************************
// define the used pins

#define ledPin 13      // activity indicator, use for brief flash when transmit

// don't need to define pin12, handled by VirtualWire as default data_out pin to the transmitter

int sleepStatus = 0;   // variable to store a request for sleep - I don't call out, maybe in the library?
int count = 0;         // counter for telling when to sleep
int sleep_flag = 0;    // flag to tell us to go sleep

// ********************************************************
// create an array to store data to be sent out
char msg[1];

// set up the Keypad
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns

// Define the Keymap
char keys[ROWS][COLS] = 
{
  {  '1','2','3','A'   } ,  // row 1
  {  '4','5','6','B'   } ,  // row 2
  {  '7','8','9','C'   } ,  // row 3
  {  '*','0','#','D'  } ,  // row 4
};
// Connect keypad ROW1, ROW2, ROW3 and ROW4 to these Arduino pins.
byte rowPins[ROWS] = {  6, 5, 4, 3  };  //

// Connect keypad COL1, COL2, COL3, COL4 to these Arduino pins.
byte colPins[COLS] = { 10, 9, 8, 7 }; 

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

// ******************************************************
// define stuff for Interrupt use
void wakeUpNow()  {     // here the interrupt is handled after wakeup. In this case, do nothing.
}

// ********************************************************
// set up the pins as Inputs, Outputs, etc.
void setup()
{

  // For Plan B:
  // define the interrut pin as input with internal pullup
  pinMode(wakePin, INPUT);       // redefine as the interrupt pin (wakePin)
  digitalWrite(wakePin, HIGH);

  // define all the unused pins as inputs with internal pullups for lower power state
  pinMode(dpin0, INPUT);       // apparently redefined by Serial as Serial Monitor works (receiving anyway)
  digitalWrite(dpin0, HIGH);   // apparently redefined by Serial as Serial Monitor works
  pinMode(dpin1, INPUT);       // apparently redefined by Serial as Serial Monitor works
  digitalWrite(dpin1, HIGH);   // apparently redefined by Serial as Serial Monitor works
 
  pinMode(dpin14, INPUT);
  digitalWrite(dpin14, HIGH);
  pinMode(dpin15, INPUT);
  digitalWrite(dpin15, HIGH);
  pinMode(dpin16, INPUT);
  digitalWrite(dpin16, HIGH);
  pinMode(dpin17, INPUT);
  digitalWrite(dpin17, HIGH);
  pinMode(dpin18, INPUT);
  digitalWrite(dpin18, HIGH);
  pinMode(dpin19, INPUT);
  digitalWrite(dpin19, HIGH);

  // default pin for data to be transmitted out
  // pinMode(dpin12, OUTPUT); // taken care of by VirtualWire

  digitalWrite(ledPin, LOW);  // pin 13
  Serial.begin(9600);            // need for debug monitoring only with FTDI connected via USB to PC
  Serial.println("TX setup"); // for debug only 

  // *******************************************************
  // Initialise the IO and ISR for VirtualWire
  vw_setup(2000);       // Bits per sec

} // end of void Setup()


// *********************************************************
// Finally, the loop for reading the keypad and sending the button pushed out
// (with a unique address to be added eventually by reading 0-F from currently unused pins)

void loop()
{
  if (sleep_flag==1){
    sleep_flag=0;                              // turn it off for when we wake up
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
    sleep_enable();                        // enables the sleep bit in the mcucr register so sleep is possible.
    sleep_mode();                          // here the device is actually put to sleep!!
  }  // end of checking sleep flag
  
    // THE PROGRAM SHOULD CONTINUE FROM HERE IF IT EVER WOKE UP
  
  char key = keypad.getKey();  // read the keypad
  if(key)  // same as if(key != NO_KEY)
  {
    //    Serial.println(key); // for debug only
    msg[0]=key;     // load the array with the key character
    // msg[1]=NULL; // Rx side seems to work without this

    digitalWrite(ledPin, true); // Flash a light to show transmitting
    Serial.println("sending"); // for debugging only
    Serial.println(key); // for debugging only    
    vw_send((uint8_t *)msg, strlen(msg)); // send the character out
    vw_wait_tx(); // Wait until the whole message is gone
    Serial.println("sent"); // for debugging only
    //    delay (1); // don't need at all - seem to get enough flash while sending
    digitalWrite(ledPin, false);  // turn off the flash of LED
    count = 0;  // reset count up to sleep if transmitted a key press

  }  // end of if(key) & transmitting a character
  count = count+1;  // start counting to go to sleep

  //  wait 2/10th of a second total with 2 LED flashes
  Serial.println("waiting"); // this whole section for debugging only
  digitalWrite(ledPin, true); // LED on
  delay(50);
  digitalWrite(ledPin, false);  // LED off
  delay(50);
  digitalWrite(ledPin, true); // LED on
  delay(50);
  digitalWrite(ledPin, false);  // LED off
  delay(50);

  // check if we should go to sleep because of time
  if (count >= 50) // update to 1000 after getting rid of flashes above
  {  // ~10 second delay to go to sleep after a key press
    Serial.println("going to sleep"); // for debugging only
    count = 0;  // reset sleep counter for when we come back
    // flash LED 3 times quick to show going to sleep - get rid of after debugged
    digitalWrite(ledPin, true); // LED on
    delay(100);
    digitalWrite(ledPin, false);  // LED off
    delay(100);
    digitalWrite(ledPin, true); // LED on
    delay(100);
    digitalWrite(ledPin, false);  // LED off
    delay(100);
    digitalWrite(ledPin, true); // LED on
    delay(100);
    digitalWrite(ledPin, false);  // LED off
    delay(100); 

    sleep_flag=1; // set the sleep flag, go to sleep at the top of the loop

    } // end of checking to go to sleep
    
} // end of void loop

Not even this simple example will get my Deumilanove to wake up - is it something with my hardware? Pins D2 & D3 seem to work - they can read & write okay otherwise:

// code to read in 2, write out on 3, swap #s to read in 3 & write out on 2
// set up the pin being read as input with internal pullup
// output goes to current limit resister to LED to ground
// drive output pin high/low to reflect input pin,
// manually shorted to ground to turn off LED

int pin2=2;
int pin3=3;
int in2=0;
int in3=0;

void setup(){
pinMode (pin3, INPUT);    // swap 2 & 3 to test both pins
digitalWrite (pin3, HIGH); // swap 2 & 3 to test both pins
pinMode (pin2, OUTPUT); // swap 2 & 3 to test both pins
}
void loop(){
  in3=digitalRead(pin3); // swap 2 & 3 to test both pins
  digitalWrite(pin2, in3); // swap 2 & 3 to test both pins  
}

And this simple program to put the Duemilanove into Power Down sleep mode after a few seconds, then recover on an interrupt.

/*
Copyright (c) 2010, Donal Morrissey
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright 
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the Author nor the names of its 
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

* Sketch for testing sleep mode with wake up on pin2 interrupt.

*/

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

int pin2 = 2;

/***************************************************
 *  Name:        pin2Interrupt
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Service routine for pin2 interrupt  
 *
 ***************************************************/
void pin2Interrupt(void)
{
  /* This will bring us back from sleep. */
  
  /* We detach the interrupt to stop it from 
   * continuously firing while the interrupt pin
   * is low.
   */
  detachInterrupt(0);
}

/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Enters the arduino into sleep mode.
 *
 ***************************************************/
void enterSleep(void)
{
  
  /* Setup pin2 as an interrupt and attach handler. */
  attachInterrupt(0, pin2Interrupt, LOW);
  delay(100);
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  
  sleep_enable();
  
  sleep_mode();
  
  /* The program will continue from here. */
  
  /* First thing to do is disable sleep. */
  sleep_disable(); 
}

/***************************************************
 *  Name:        setup
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Setup for the Arduino.           
 *
 ***************************************************/
void setup()
{
  Serial.begin(9600);
  
  /* Setup the pin direction. */
  pinMode(pin2, INPUT);
  
  Serial.println("Initialisation complete.");
}

/***************************************************
 *  Name:        loop
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Main application loop.
 *
 ***************************************************/
int seconds=0;
void loop()
{
  delay(1000);
  seconds++;
  
  Serial.print("Awake for ");
  Serial.print(seconds, DEC);
  Serial.println(" second");
  
  if(seconds >= 3)
  {
    Serial.println("Entering sleep");
    delay(200);
    seconds = 0;
    enterSleep();
  }
  
}

Finally managed to get out of sleep mode, manually anyway. Turns out all this time I didn’t have
#include <avr/interrupt.h>
in my sketch, saw something in the while browsing one of the cheatsheets led me do a different example where I noticed that in the sketch - stuck it in, and now I can interrupt out of sleep mode.

Gonna go ask in the hardware forum how to get a keypad response while in sleep mode now …