user46979: I am trying to use atmega88 timer2 with a 32.768KHz crystal. I'm using a slightly modified version of Nick Gammon's code. I am using Minicore. No bootloader, 1MHz clock from internal oscillator, BOD disabled. Sleep is interrupted every 8 seconds. I use a counter to count 12 minutes. Since it overshoots about 8 seconds every 6 hours, I am subtracting 8 sec every 6 hours. I hope to eventually make a weather logger with this.
The code is mostly working in it's bare stripped down version, after I add a delay(100) after the digitalWrite. However, I also need Serial. When I enable Serial, it does not sleep anymore. Also, the serial output has a lot of excess weird characters. This happens at all baud rates, even 1200 (serial monitor set to same baud rate as in program). I think some interrupts are being called during digitalWrite and when the usart is powered on and it is messing with the sleep. I am a beginner regarding uC programming, and am really struggling with the datasheet and the code. Any help will be appreciated.
Here is the test code:
#include <avr/sleep.h>
#include <avr/power.h>

const byte tickPin = 4;// (do not use 3 and 11)

//byte intCounter = 0;
//byte leapCounter = 0;

int intCounter = 0;
int leapCounter = 0;

unsigned long prevTime = 0;
unsigned long currTime = 0;

// interrupt on Timer 2 compare "A" completion - does nothing
EMPTY_INTERRUPT (TIMER2_COMPA_vect);

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


  Serial.begin(9600);
  prevTime = millis();
  Serial.print(" P: ");
  Serial.println(prevTime);


  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = bit (AS2);

  // set up timer 2 to count up to 256 * 1024  (8 seconds)
  TCCR2A = bit (WGM21);                             // CTC
  TCCR2B = bit (CS20) | bit (CS21) | bit (CS22);    // Prescaler of 1024
  OCR2A =  255;                                     // (zero-relative)

  // enable timer interrupts
  TIMSK2 |= bit (OCIE2A);

  // disable ADC
  ADCSRA = 0;

  // turn off everything we can
  power_twi_disable();
//  power_timer0_disable();
//  power_timer1_disable();
  power_spi_disable();
  power_usart0_disable();
  power_adc_disable ();

  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE);

  // get ready ...
  sleep_enable();

}  // end of setup

void loop(){
  sleep_cpu ();
  ++intCounter;

  power_usart0_enable();
  Serial.print("I: ");
  Serial.print(intCounter);
  Serial.print(" L: ");
  Serial.print(leapCounter);
  currTime = millis();
  Serial.print(" C: ");
  Serial.print(currTime);
  Serial.print(" E: ");
  Serial.print(currTime - prevTime);
  Serial.println();
  prevTime = currTime;
  power_usart0_disable();
  delay(1000);

  if ((leapCounter > 30) && (intCounter == 1)){
    leapCounter = 0;
    intCounter = 0;
  }
  if (intCounter > 89){
    ++leapCounter;
    intCounter = 0;
    digitalWrite (tickPin, ! digitalRead (tickPin));
    delay(100);
  }
//  digitalWrite (tickPin, ! digitalRead (tickPin));
//  delay(100);
}  // end of loop

The chip is an Atmega88 (not P). It is drawing the same 6.5uA during sleep, with or without timer0 and timer1. So, I probably don't care if I have to leave them enabled.
I am planning to use a DHT11 and a ds18B20 and write the data to a w25Q64 flash, every 12 minutes. I'd prefer reading it all out via serial port every few weeks, without having to stop the uC.
update
Calling timer2 ISR, instead of handling wake up directly in main loop. Possibly more stable (not affected by Serial and digitalWrite)... but I am not sure.
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

//const byte tickPin = 4;// (do not use 3 and 11)

volatile bool t2flag = LOW;
volatile byte t2counter = 0;

byte leapCounter = 0;

//preventing digitalWrite from causing interrupt (did not help much)
EMPTY_INTERRUPT(PCINT2_vect);

void setup(){
  pinMode (4, OUTPUT);
  pinMode (1, INPUT_PULLUP); //set TX pin default HIGH

  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = bit (AS2);
  // set up timer 2 to count up to 256 * 1024  (8 seconds)
  TCCR2A = bit (WGM21);                             // CTC
  TCCR2B = bit (CS20) | bit (CS21) | bit (CS22);    // Prescaler of 1024
  OCR2A =  255;                                     // (zero-relative)
  // enable timer interrupts
  TIMSK2 |= bit (OCIE2A);
  // disable ADC
  ADCSRA = 0;

  // turn off everything we can
  power_twi_disable();
//  power_timer0_disable();
//  power_timer1_disable();
  power_spi_disable();
  power_usart0_disable();
  power_adc_disable();
  wdt_disable();// reduces 6.5uA to 2.2uA @ 3.3V

  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE);
  sleep_enable();
}

//ISR to handle timer2
ISR (TIMER2_COMPA_vect){
  ++t2counter;
  if (t2counter > 89){t2flag = HIGH;}
}

void loop(){
  if (t2flag == LOW){

    power_usart0_enable();
    Serial.begin(9600);
    Serial.print("I: ");
    Serial.print(t2counter);
    Serial.println();
    Serial.flush();
    delay(10);
    Serial.end();
    power_usart0_disable();

    //blip the tickPin every 8 sec
    PORTD |= (1<<PD4);
    delay(10);
    PORTD &= ~(1<<PD4);

    delay(100);//helps a lot
    sleep_cpu();
    return;
  }

  ++leapCounter;  
  if (leapCounter == 30){
    t2flag = LOW;
    return; //delay another 8 sec every 6 hours
  }
  if (leapCounter > 30){leapCounter = 0;}

  t2flag = LOW;
  t2counter = 0;


  power_usart0_enable();
  Serial.begin(9600);
  Serial.print("L: ");
  Serial.print(leapCounter);
  Serial.println();
  Serial.flush();
  delay(10);
  Serial.end();
  power_usart0_disable();

  //long blip every 12 minutes
  PORTD |= (1<<PD4);
  delay(100);
  PORTD &= ~(1<<PD4);
}

The problem is not always present. But when it appears, it happens the same way. After pressing reset button, first led blink is always after 8 seconds. After that, one of three things seem to happen. 1. Second flash is after 8 seconds and everything works as expected. 2. Second flash is after 3 seconds and all flashes after that are also after every 3 seconds. 3. Second flash happens immediately after first flash (and any delay() in the code) and this keeps on happening. In all cases, the serial output also shows the same pattern.
Sometimes it seems that wires connected to the serial or miso, mosi, sck may be causing this, but that is not always the case. The problem may occur even if these wires are not connected. Also, the problem may or may not occur with the same code (e.g. pressing reset after 30 sec may not show any problem, but pressing reset within 5 or 10 seconds leads to problem cases 2 and 3 above. So there is some kind of race condition, or buffer or interrupt noise or something.
I have to program with Arduino as ISP, as the bootloader is unable to sync with the ftdi chip for some reason while uploading sketch. But data transfer from the sketch with serial.print is working fine. So pulling out the miso mosi sck pins everytime is a hassle. Everything is on breadboard. I transferred full circuit to new breadboard (from old loose breadboard) but there is no change. So maybe not a breadboard issue.

user7508: I see two issues in this code.
The first is that you are trying to send data through an UART that has
been powered off. Serial.print() doesn't wait for the data to get out,
it merely stores it into a memory buffer. You should wait until
everything gets out before switching the UART off. This can be done by
calling either Serial.flush() or Serial.end(). I would use the
latter, as it feels safer to stop the UART before switching if off. But
then you have to Serial.begin() again on wakeup.
To avoid the garbled characters in the serial stream, you could try to
either pinMode(1, INPUT_PULLUP); or digitalWrite(1, HIGH);. This way
you ensure that the TX line stays HIGH (which is its normal idle
state) when the UART goes off.
The second issue is your use of the Arduino timekeeping functions
millis() and delay(). These functions rely on an interrupt triggered
by Timer 0. If you power off that timer, millis() and delay()
won't work. If you don't, SLEEP_MODE_PWR_SAVE does it for you while
sleeping. Then those function will work while awake, but millis() will
not count the time you spent sleeping.

Edit: There are two interrupts related to the UART that are enabled
by Serial.begin():

USART_UDRE, “Data Register Empty”, is used for transmission. It
fires when the hardware transmit buffer is ready to receive new data.
The corresponding ISR's job is to copy one byte from the transmit
memory buffer (the one Serial.print() writes into) into the hardware
transmit buffer.
USART_RX, “Receive Complete”, is used for reception. It fires when a
byte is received. The corresponding ISR copies this byte into receive
memory buffer (the one Serial.read() reads from).

The first one fires when transmitting. Once you wait for the end of the
transmission (say with Serial.flush()), you shouldn't see this
interrupt firing anymore.
The second one fires only when receiving. If you are not receiving
anything, this interrupt shouldn't fire. If the RX pin is floating, the
interrupt could be triggered by external noise. This can be prevented by
enabling the internal pullup on the RX pin. Alternatively, you can
disable the receiver part of the UART:
UCSR0B &= ~_BV(RXEN0);  // disable the UART receiver

Note that if you stop the UART with Serial.end(), both the transmitter
and the receiver are disabled, and you don't get UART-related interrupts
anymore.

46979: <p>I am trying to use atmega88 timer2 with a 32.768KHz crystal. I'm using a slightly modified version of <a href="http://www.gammon.com.au/forum/?id=11504&amp;reply=10#reply10" rel="nofollow noreferrer">Nick Gammon's code</a>. I am using <a href="https://github.com/MCUdude/MiniCore" rel="nofollow noreferrer">Minicore</a>. No bootloader, 1MHz clock from internal oscillator, BOD disabled. Sleep is interrupted every 8 seconds. I use a counter to count 12 minutes. Since it overshoots about 8 seconds every 6 hours, I am subtracting 8 sec every 6 hours. I hope to eventually make a weather logger with this.</p>

<p>The code is mostly working in it's bare stripped down version, after I add a delay(100) after the digitalWrite. However, I also need Serial. When I enable Serial, it does not sleep anymore. Also, the serial output has a lot of excess weird characters. This happens at all baud rates, even 1200 (serial monitor set to same baud rate as in program). I think some interrupts are being called during digitalWrite and when the usart is powered on and it is messing with the sleep. I am a beginner regarding uC programming, and am really struggling with the datasheet and the code. Any help will be appreciated.</p>

<p>Here is the test code:</p>

<pre><code>#include &lt;avr/sleep.h&gt;
#include &lt;avr/power.h&gt;

const byte tickPin = 4;// (do not use 3 and 11)

//byte intCounter = 0;
//byte leapCounter = 0;

int intCounter = 0;
int leapCounter = 0;

unsigned long prevTime = 0;
unsigned long currTime = 0;

// interrupt on Timer 2 compare "A" completion - does nothing
EMPTY_INTERRUPT (TIMER2_COMPA_vect);

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


  Serial.begin(9600);
  prevTime = millis();
  Serial.print(" P: ");
  Serial.println(prevTime);


  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = bit (AS2);

  // set up timer 2 to count up to 256 * 1024  (8 seconds)
  TCCR2A = bit (WGM21);                             // CTC
  TCCR2B = bit (CS20) | bit (CS21) | bit (CS22);    // Prescaler of 1024
  OCR2A =  255;                                     // (zero-relative)

  // enable timer interrupts
  TIMSK2 |= bit (OCIE2A);

  // disable ADC
  ADCSRA = 0;

  // turn off everything we can
  power_twi_disable();
//  power_timer0_disable();
//  power_timer1_disable();
  power_spi_disable();
  power_usart0_disable();
  power_adc_disable ();

  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE);

  // get ready ...
  sleep_enable();

}  // end of setup

void loop(){
  sleep_cpu ();
  ++intCounter;

  power_usart0_enable();
  Serial.print("I: ");
  Serial.print(intCounter);
  Serial.print(" L: ");
  Serial.print(leapCounter);
  currTime = millis();
  Serial.print(" C: ");
  Serial.print(currTime);
  Serial.print(" E: ");
  Serial.print(currTime - prevTime);
  Serial.println();
  prevTime = currTime;
  power_usart0_disable();
  delay(1000);

  if ((leapCounter &gt; 30) &amp;&amp; (intCounter == 1)){
    leapCounter = 0;
    intCounter = 0;
  }
  if (intCounter &gt; 89){
    ++leapCounter;
    intCounter = 0;
    digitalWrite (tickPin, ! digitalRead (tickPin));
    delay(100);
  }
//  digitalWrite (tickPin, ! digitalRead (tickPin));
//  delay(100);
}  // end of loop
</code></pre>

<p>The chip is an Atmega88 (not P). It is drawing the same 6.5uA during sleep, with or without timer0 and timer1. So, I probably don't care if I have to leave them enabled.</p>

<p>I am planning to use a DHT11 and a ds18B20 and write the data to a w25Q64 flash, every 12 minutes. I'd prefer reading it all out via serial port every few weeks, without having to stop the uC.</p>

<p><strong>update</strong></p>

<p>Calling timer2 ISR, instead of handling wake up directly in main loop. Possibly more stable (not affected by Serial and digitalWrite)... but I am not sure.</p>

<pre><code>#include &lt;avr/sleep.h&gt;
#include &lt;avr/power.h&gt;
#include &lt;avr/wdt.h&gt;

//const byte tickPin = 4;// (do not use 3 and 11)

volatile bool t2flag = LOW;
volatile byte t2counter = 0;

byte leapCounter = 0;

//preventing digitalWrite from causing interrupt (did not help much)
EMPTY_INTERRUPT(PCINT2_vect);

void setup(){
  pinMode (4, OUTPUT);
  pinMode (1, INPUT_PULLUP); //set TX pin default HIGH

  // clock input to timer 2 from XTAL1/XTAL2
  ASSR = bit (AS2);
  // set up timer 2 to count up to 256 * 1024  (8 seconds)
  TCCR2A = bit (WGM21);                             // CTC
  TCCR2B = bit (CS20) | bit (CS21) | bit (CS22);    // Prescaler of 1024
  OCR2A =  255;                                     // (zero-relative)
  // enable timer interrupts
  TIMSK2 |= bit (OCIE2A);
  // disable ADC
  ADCSRA = 0;

  // turn off everything we can
  power_twi_disable();
//  power_timer0_disable();
//  power_timer1_disable();
  power_spi_disable();
  power_usart0_disable();
  power_adc_disable();
  wdt_disable();// reduces 6.5uA to 2.2uA @ 3.3V

  // full power-down doesn't respond to Timer 2
  set_sleep_mode (SLEEP_MODE_PWR_SAVE);
  sleep_enable();
}

//ISR to handle timer2
ISR (TIMER2_COMPA_vect){
  ++t2counter;
  if (t2counter &gt; 89){t2flag = HIGH;}
}

void loop(){
  if (t2flag == LOW){

    power_usart0_enable();
    Serial.begin(9600);
    Serial.print("I: ");
    Serial.print(t2counter);
    Serial.println();
    Serial.flush();
    delay(10);
    Serial.end();
    power_usart0_disable();

    //blip the tickPin every 8 sec
    PORTD |= (1&lt;&lt;PD4);
    delay(10);
    PORTD &amp;= ~(1&lt;&lt;PD4);

    delay(100);//helps a lot
    sleep_cpu();
    return;
  }

  ++leapCounter;  
  if (leapCounter == 30){
    t2flag = LOW;
    return; //delay another 8 sec every 6 hours
  }
  if (leapCounter &gt; 30){leapCounter = 0;}

  t2flag = LOW;
  t2counter = 0;


  power_usart0_enable();
  Serial.begin(9600);
  Serial.print("L: ");
  Serial.print(leapCounter);
  Serial.println();
  Serial.flush();
  delay(10);
  Serial.end();
  power_usart0_disable();

  //long blip every 12 minutes
  PORTD |= (1&lt;&lt;PD4);
  delay(100);
  PORTD &amp;= ~(1&lt;&lt;PD4);
}
</code></pre>

<p>The problem is not always present. But when it appears, it happens the same way. After pressing reset button, first led blink is always after 8 seconds. After that, one of three things seem to happen. 1. Second flash is after 8 seconds and everything works as expected. 2. Second flash is after 3 seconds and all flashes after that are also after every 3 seconds. 3. Second flash happens immediately after first flash (and any delay() in the code) and this keeps on happening. In all cases, the serial output also shows the same pattern.</p>

<p>Sometimes it seems that wires connected to the serial or miso, mosi, sck may be causing this, but that is not always the case. The problem may occur even if these wires are not connected. Also, the problem may or may not occur with the same code (e.g. pressing reset after 30 sec may not show any problem, but pressing reset within 5 or 10 seconds leads to problem cases 2 and 3 above. So there is some kind of race condition, or buffer or interrupt noise or something.</p>

<p>I have to program with Arduino as ISP, as the bootloader is unable to sync with the ftdi chip for some reason while uploading sketch. But data transfer from the sketch with serial.print is working fine. So pulling out the miso mosi sck pins everytime is a hassle. Everything is on breadboard. I transferred full circuit to new breadboard (from old loose breadboard) but there is no change. So maybe not a breadboard issue.</p>
 7508: <p>I see two issues in this code.</p>

<p>The first is that you are trying to send data through an UART that has
been powered off. <code>Serial.print()</code> doesn't wait for the data to get out,
it merely stores it into a memory buffer. You should wait until
everything gets out before switching the UART off. This can be done by
calling either <code>Serial.flush()</code> or <code>Serial.end()</code>. I would use the
latter, as it feels safer to stop the UART before switching if off. But
then you have to <code>Serial.begin()</code> again on wakeup.</p>

<p>To avoid the garbled characters in the serial stream, you could try to
either <code>pinMode(1, INPUT_PULLUP);</code> or <code>digitalWrite(1, HIGH);</code>. This way
you ensure that the TX line stays <code>HIGH</code> (which is its normal idle
state) when the UART goes off.</p>

<p>The second issue is your use of the Arduino timekeeping functions
<code>millis()</code> and <code>delay()</code>. These functions rely on an interrupt triggered
by Timer&nbsp;0. If you power off that timer, <code>millis()</code> and <code>delay()</code>
won't work. If you don't, <code>SLEEP_MODE_PWR_SAVE</code> does it for you while
sleeping. Then those function will work while awake, but <code>millis()</code> will
not count the time you spent sleeping.</p>

<hr>

<p><strong>Edit:</strong> There are two interrupts related to the UART that are enabled
by <code>Serial.begin()</code>:</p>

<ul>
<li><p><code>USART_UDRE</code>, “Data Register Empty”, is used for transmission. It
fires when the hardware transmit buffer is ready to receive new data.
The corresponding ISR's job is to copy one byte from the transmit
memory buffer (the one <code>Serial.print()</code> writes into) into the hardware
transmit buffer.</p></li>
<li><p><code>USART_RX</code>, “Receive Complete”, is used for reception. It fires when a
byte is received. The corresponding ISR copies this byte into receive
memory buffer (the one <code>Serial.read()</code> reads from).</p></li>
</ul>

<p>The first one fires when transmitting. Once you wait for the end of the
transmission (say with <code>Serial.flush()</code>), you shouldn't see this
interrupt firing anymore.</p>

<p>The second one fires only when receiving. If you are not receiving
anything, this interrupt shouldn't fire. If the RX pin is floating, the
interrupt could be triggered by external noise. This can be prevented by
enabling the internal pullup on the RX pin. Alternatively, you can
disable the receiver part of the UART:</p>

<pre class="lang-c++ prettyprint-override"><code>UCSR0B &amp;= ~_BV(RXEN0);  // disable the UART receiver
</code></pre>

<p>Note that if you stop the UART with <code>Serial.end()</code>, both the transmitter
and the receiver are disabled, and you don't get UART-related interrupts
anymore.</p>
