I have these snippets of my ATtiny85 and '328 sleep code from years ago. I never use "attach interrupt", just the reserved labels for them. Note for min. current draw I had to shut off the A/D and BOD. The code is not pretty but works. Wakes up due to a pin (ignition key or pushbutton) interrrupt. I was testing on '328 Uno and the final H/W is Tiny 85, so I left both MCU-specific routines in the source, just commented it out as not needed.
//------------------------------------------------------------------------
void SleepSession328(void) {
// http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html
// configure and enter sleep mode, only pin change interrupt (ign switch or pushbutton press) wakes us
ADCSRA &= ~(1 << ADEN); // shutoff ADC
MCUCR |= (1 << BODS); // disable BOD 328P only, override fuses for sleep
// config and enable pin-change interrupts
cli(); // disable global interrupts as we are reconfiguring them
PCMSK2 |= (1 << PCINT21) | (1 << PCINT23); // unmask pin-change int for D5, D7- the switch inputs
PCIFR &= ~(1 << PCIF2); // clear flag for any outstanding pin-change interrupt 2 flag PCINT[23:16] for D0-D7
PCICR |= (1 << PCIE2); // enable pin-change interrupt group2
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
// sleep_bod_disable(); // time limited, have to try
sei(); // re-enable global interrupts, sleep is set up now
DEBUG_PRINTLN("** SLEEP **"); delay(100); // to empty serial buffer
sleep_cpu(); // go to sleep
//---------------------- W A K E ---------
/* Upon waking, the program will continue from here. */
sleep_disable(); // now that we've woken up, stay up;
// BOD is automatically turned on after sleep,, A/D left off
PCICR &= ~(1 << PCIE2); // disable pin-change interrupt group2, left pcmsk alone
DEBUG_PRINTLN("** WAKE **");
}
//------------------------------------------------------------------------
void SleepSession(void) { // Tiny85
// http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html
// configure and enter sleep mode, only pin change interrupt (ign switch or pushbutton press) wakes us
ADCSRA &= ~(1 << ADEN); // shutoff ADC if it was on and save power ~0.3mA at 5V;
// not sure if BOD (fuse) is used, analog comparator if used may need to disconnect too to save power.
// config and enable pin-change interrupts
cli(); // disable global interrupts as we are reconfiguring them
PCMSK = 0b00011000; // allow pin-change interrupts on pins PB3, PB4- the switch inputs; Interrupt unmask
GIMSK |= (1 << PCIE); // enable pin-change interrupts; Interrupt source
// not sure if timer interrupts happenin on Arduino with Attiny85
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
// sleep_bod_disable(); // time limited, have to try
sei(); // re-enable global interrupts, sleep is set up now
//state = sSLEEPING;
DEBUG_PRINTLN("** SLEEP **"); delay(100); // to empty serial buffer
sleep_cpu(); // go to sleep
//---------------------- W A K E ---------
// Upon waking due to Pin Change Interrupt, program execution will continue from here.
sleep_disable(); // now that we've woken up, stay up;
// disable further pin-change interrupts, so no spurious interrupt
GIMSK &= ~(1 << PCIE); // turn off pin-change interrupts off
DEBUG_PRINTLN("** WAKE **");
}
//------------------------------------------------------------------------
ISR (PCINT0_vect) { // Pin Change Interrupt for Tiny85
// GIFR automatically cleared here; hope timers don't use them
//clear the pin change interrupt, good to wake and run now; or no change if spurious interrupt
// do nothing here, other than wake up and resume Main
// old code: GIMSK &= ~(1 << PCIE); // We are awake, no more Pin Change interrupts; mask them off
}
//------------------------------------------------------------------------
ISR (PCINT2_vect) { // '328 Uno Pin Change Interrupt for D0-D7
// GIFR automatically cleared here; hope timers don't use them
//clear the pin change interrupt, good to wake and run now; or no change if spurious interrupt
// do nothing here, other than wake up and resume Main
// old GIMSK &= ~(1 << PCIE); // We are awake, no more Pin Change interrupts; mask them off
// who woke us up?
ign.wake = digitalRead(IgnSwitchPin); //
PB.wake = !digitalRead(Power_ButtonPin); //
}