Sleeping issues

Hi guys, I'm running a sketch to test sleeping functionality on my Arduino Mega 2560. Right now I have it set to sleep for 10 seconds, wait for 5 seconds, sleep for another 5 seconds then display a done message. The initialization message is displayed fine, and the board goes to sleep for 10 seconds. However once the board wakes up from the first sleep, it fails to do anything else after that point. The ending message is not displayed, nor does it go back to sleep. Even if I comment out the second sleep command the end message still is not displayed. Getting serial comm working along with sleep functionality is quite important for the project I'm working on and I feel pretty much stuck on this. Maybe you guys could find a problem with my code I'm not getting.

At first I thought the problem was modifying the timer2 registers breaks serial comm. I thought reverting all register changes I made in the code would fix this but it didn't. Perhaps some other register is being modified that I don't know about. Does anyone know what Arduino functions rely on timer2 to work?

Maybe others will find this useful if I ever get it working.

Anyways here is my code:

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

volatile int flag = 1;

void setup(){
  Serial.begin(9600);
  Serial.println(F("Hi there how are you"));

  int sleeptime = 10;  

  delay(1000);
  Serial.print(F("Sleeping for "));
  Serial.print(sleeptime);
  Serial.println(F(" seconds."));
  Serial.end();
  delay(1000);
  sleep(sleeptime);
  delay(5000);
  sleep(5);
  Serial.begin(9600);
  Serial.println(F("done!"));
}

void loop(){
}

and here are my functions:

ISR(TIMER2_OVF_vect){
  if(flag == 0){
    flag = 1;
  }
}

void enterSleep(void){
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  
  power_adc_disable();
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer3_disable();
  power_timer4_disable();
  power_timer5_disable();
  power_twi_disable();
  power_usart0_disable();
  power_usart1_disable();
  power_usart2_disable();
  power_usart3_disable();  
    
  //enable global interrupts
  sei();

  //set timer2 to BOTTOM
  TCNT2 = 0x00;

  //go to sleep
  sleep_mode();

  //program continues from here after interrupt occurs
  sleep_disable();
  power_all_enable();

  //disable global interrupts
  cli();

  //clear timer2 overflow interrupt flag
  //actually this is done by hardware apparently  
}

void sleep(int time){
  int count = 0;
  int seconds = 0;

  //set up timing interrupts
  TCCR2B = 0x07;
  TCCR2A = 0x00;
  TIMSK2 = 0x01;

  while(1){
    if(flag == 1){
      flag = 0;
      enterSleep();
      if(count++ % 61 == 0){
        seconds++;
      }
      if(seconds % 1736 == 0){
        seconds++;
      }
      if(seconds >= time){
        //change back registers so serial comm works
        TCCR2B = 0x04;
        TCCR2A = 0x01;
        TIMSK2 = 0x00;
        break;
      }
    }  
  }
}

Furthermore, do you guys think my timing algorithm looks accurate? Hopefully this can be used to sleep for hours or days with good accuracy.

If you want people to help you, post the entire sketch as one piece that
compiles without error. Snippets are fine for talking about, but no use for
re-creating a problem.

okay here you go Mark, this should save you about 10 seconds! thanks so much for your helpful comment =D

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

volatile int flag = 1;

void setup(){
  Serial.begin(9600);
  Serial.println(F("Hi there how are you"));

  int sleeptime = 10;  

  delay(1000);
  Serial.print(F("Sleeping for "));
  Serial.print(sleeptime);
  Serial.println(F(" seconds."));
  Serial.end();
  delay(1000);
  sleep(sleeptime);
  delay(5000);
  sleep(5);
  Serial.begin(9600);
  Serial.println(F("done!"));
}

void loop(){
}

ISR(TIMER2_OVF_vect){
  if(flag == 0){
    flag = 1;
  }
}

void enterSleep(void){
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  
  power_adc_disable();
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer3_disable();
  power_timer4_disable();
  power_timer5_disable();
  power_twi_disable();
  power_usart0_disable();
  power_usart1_disable();
  power_usart2_disable();
  power_usart3_disable();  
    
  //enable global interrupts
  sei();

  //set timer2 to BOTTOM
  TCNT2 = 0x00;

  //go to sleep
  sleep_mode();

  //program continues from here after interrupt occurs
  sleep_disable();
  power_all_enable();

  //disable global interrupts
  cli();

  //clear timer2 overflow interrupt flag
  //actually this is done by hardware apparently  
}

void sleep(int time){
  int count = 0;
  int seconds = 0;

  //set up timing interrupts
  TCCR2B = 0x07;
  TCCR2A = 0x00;
  TIMSK2 = 0x01;

  while(1){
    if(flag == 1){
      flag = 0;
      enterSleep();
      if(count++ % 61 == 0){
        seconds++;
      }
      if(seconds % 1736 == 0){
        seconds++;
      }
      if(seconds >= time){
        //change back registers so serial comm works
        TCCR2B = 0x04;
        TCCR2A = 0x01;
        TIMSK2 = 0x00;
        break;
      }
    }  
  }
}

In case anyone cares, I found the problem... kind of obvious really

I didn't re-enable global interrupts after exiting my sleep function. Once I added in an sei(); to the code in the appropriate spot it worked fine.

So maybe this code would be useful to anyone looking to sleep for a set amount of seconds 8)