Using IRremote library, millis() and PIR to awake from sleep

Promini 16MHz 5v board.
I can read IRremote input using generic 17 button Keyes transmitter.
I can implement a delay of around 10 seconds using millis(), then enter sleep mode.
I can wake from sleep using PIR detector.

When I try to combine these elements into one sketch, this is what happens—
The sketch runs and indicates a ‘6’ button on the remote as been pressed.
The board only enters sleep mode after 10 seconds, and when the button is being pressed.
The board wakes from sleep on PIR detection.

The Keyes remote, and another recent ebay generic the same type, use different codes (‘Unknown’) when operated at the working distance of 2 metres or more. At less than a few inches the decoding is given as NEC with different HEX values, those as shown in tutorials.
This IRremote library and ‘switch’ ‘case’ is the only way I have been able to read the button presses.
So, I was hoping not to have to find a solution that involved going to an interrupt based decoding method.

[code]
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <IRremote.h>

const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long previousMillis = 0;
unsigned long interval = 10000;

void motorcw(void)
{

  digitalWrite(6, LOW); //activate motor
  for (int x = 1; x <= 2; x++) //slow flash diagnostic indicator
  { //digitalWrite(13,HIGH);
    delay(250);
    //digitalWrite(13,LOW);
    delay(250);
  }
  digitalWrite(6, HIGH); //de-activate motor
}

void motorccw(void)
{
  digitalWrite(8, LOW); //activate motor
  for (int x = 1; x <= 4; x++) //fast flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
  digitalWrite(8, HIGH); //de-activate motor
}
void motorstop(void)
{
  //no code here yet!
}

void sleepNow(void)
{
  digitalWrite(13, LOW);
  // Set pin 2 as interrupt and attach handler:
  attachInterrupt(0, pinInterrupt, LOW);
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  // Set sleep enable (SE) bit:
  sleep_enable();
  sleep_mode();
  // Upon waking up, sketch continues from this point.
  sleep_disable();

}

void pinInterrupt(void)
{
  detachInterrupt(0);
}

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  irrecv.enableIRIn();
  //    irrecv.blink13(true);
  //    Serial.begin(9600);
}

void loop()
{
  digitalWrite(13, HIGH);//to indicate awake from sleep
  if (irrecv.decode(&results))
  {

    switch (results.value)
    {
      case 0x52A3D41F: //Keypad button "4"
        //    Serial.print(" decode: ");
        //    Serial.println(results.value, HEX);
        motorcw();
    }

    switch (results.value)
    {
      case 0x20FE4DBB: //Keypad button "6"
        //      Serial.print(" decode: ");
        //      Serial.println(results.value, HEX);
        motorccw();
    }
    switch (results.value)
    {
      case 0xD7E84B1B:
        motorstop();
    }
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis > interval)
    {
      previousMillis = currentMillis;
      sleepNow();
    }
    irrecv.resume();
  }
}

[/code]

As my understanding of IRremote library, calling this function resets the receiver -

irrecv.resume();

which means the sketch is stuck in a loop because no signal of any kind is reaching the sensor (no button pressed)?

There are no 'results' to do a switch/case with, so the sketch just hangs at this point. What I can't find is a way around this.

from Ken Sherriff’s blog -
The IRrecv class performs the decoding, and is initialized with enableIRIn(). The decode() method is called to see if a code has been received; if so, it returns a nonzero value and puts the results into the decode_results structure. (For details of this structure, see the examples/IRrecvDump sketch.) Once a code has been decoded, the resume() method must be called to resume receiving codes. Note that decode() does not block; the sketch can perform other operations while waiting for a code because the codes are received by an interrupt routine.

If millis() uses Timer0, the Timer1 based (50uS ticks) interrupt decoding in IRremote library shouldn’t interfere?

Something like this has been asked on the forums before, but although AWOL and others did their best to help, the OP’s never followed up with any outcome.
By trial and error then, I have modified this sketch and it is now working. Hope it might help others, the short distance to the sensor giving different decode protocols could be saturation of sensor with IR signal?, so hopefully that may be useful to know too.

What I did was create a function for the irrecv section and added an 'if (results.value == 0x00) {return}
Sorry, not very elegant solution.

[code]
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <IRremote.h>

const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long previousMillis = 0;
unsigned long interval = 10000;

void motorcw(void) {
  digitalWrite(6, LOW); //activate motor
  for (int x = 1; x <= 2; x++) //slow flash diagnostic indicator
  { //digitalWrite(13,HIGH);
    delay(250);
    //digitalWrite(13,LOW);
    delay(250);
  }
  digitalWrite(6, HIGH);
} //de-activate motor

void motorccw(void) {
  digitalWrite(8, LOW); //activate motor
  for (int x = 1; x <= 4; x++) //fast flash diagnostic indicator
  { digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
  digitalWrite(8, HIGH);
} //de-activate motor

void motorstop(void) {
}//no code here yet!

void sleepNow(void) {
  digitalWrite(13, LOW);
  // Set pin 2 as interrupt and attach handler:
  attachInterrupt(0, pinInterrupt, LOW);
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  // Set sleep enable (SE) bit:
  sleep_enable();
  sleep_mode();
  // Upon waking up, sketch continues from this point.
  sleep_disable();
}

void pinInterrupt(void) {
  detachInterrupt(0);
}

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  irrecv.enableIRIn();
  //    irrecv.blink13(true);
  //    Serial.begin(9600);
}

void loop()
{
  digitalWrite(13, HIGH);//to indicate awake from sleep
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sleepNow();
  }
  checkirforkey();
}

void checkirforkey (void)
{
  if (irrecv.decode(&results)) {
    if (results.value == 0x52A3D41F) {
      //Keypad button "4"
      //    Serial.print(" decode: ");
      //    Serial.println(results.value, HEX);
      motorcw();
    }

    if (results.value == 0x20FE4DBB) {
      //Keypad button "6"
      //      Serial.print(" decode: ");
      //      Serial.println(results.value, HEX);
      motorccw();
    }
    if (results.value == 0xD7E84B1B) {
      motorstop();
    }
    if (results.value == 0x00) {
      return;
    }
    irrecv.resume();
  }
}

[/code]