Smajdalf:
After wake up from PCINT check the pin. If it is HIGH it was rising edge so you go back to sleep. If the pin is LOW it was falling edge and it is time to act. This works for power down sleep which is much better if you aim for low power consumption.
Good idea of save the current status of the register, if it's changed, power all modules. ( or i need to wake up some module to do this check?? )
DrAzzy:
Use SLEEP_MODE_POWER_DOWN, and a PCINT or level interrupt to wake on. Leaving it in IDLE mode instead of putting it all the way to sleep, just so you can use a rising edge interrupt is insane if you want low power consumption.
Yes you are right. Moreover SLEEP_MODE_IDLE not stops the millis over timer0 and the tiny85 wake-up immediately.
Interesting topic: wake atmega328 from sleep with rising event - #2 by johnwasser - Programming Questions - Arduino Forum
Gemmon uses the SLEEP_MODE_PWR_DOWN and the edge.
The only different is "EIFR = bit (INTF0); // clear flag for interrupt 0"
void sleepNow (){
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // make sure we don't get interrupted before we sleep
sleep_enable (); // enables the sleep bit in the mcucr register
EIFR = bit (INTF0); // clear flag for interrupt 0
attachInterrupt (0, wake, RISING); // wake up on rising edge
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // here the device is put to sleep
detachInterrupt (0); // stop this interrupt until next time
}
So the question is:
Save the register status ( probably the best solution ) Gammon Forum : Electronics : Microprocessors : Interrupts at "Why disable interrupts?"
void sleepMode() {
// Set sleepMode
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // make sure we don't get interrupted before we sleep
// Turn off ADC
// You must use the PRR after setting ADCSRA to zero,
// otherwise the ADC is "frozen" in an active state.
ADCSRA = 0;
// Power Reduction Register (PRR)
// This lets you "turn off" various things inside the processor.
// diable all modules availables
power_all_disable (); // power off ADC, Timer 0 and 1, serial interface
sleep_enable (); // ready to sleep
uint8_t oldSREG = SREG;
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // sleep
// Check the register status
if( oldSREG == SREG) { // no change in the interrupt, go to sleep again
sleep_enable (); // ready to sleep
oldSREG = SREG;
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // sleep
}
detachInterrupt(interruptPin); // Disable external pin interrupt on wake up pin.
sleep_disable (); // precaution
power_all_enable (); // power everything back on
}
OR uses the Gammon solution ( what is EIFR is GIFR in the Tiny85 ?? ):
void sleepMode() {
// Set sleepMode
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // make sure we don't get interrupted before we sleep
// Turn off ADC
// You must use the PRR after setting ADCSRA to zero,
// otherwise the ADC is "frozen" in an active state.
ADCSRA = 0;
// Power Reduction Register (PRR)
// This lets you "turn off" various things inside the processor.
// diable all modules availables
power_all_disable (); // power off ADC, Timer 0 and 1, serial interface
sleep_enable (); // ready to sleep
GIFR = bit (INTF0); // clear flag for interrupt 0
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // sleep
detachInterrupt(interruptPin); // Disable external pin interrupt on wake up pin.
sleep_disable (); // precaution
power_all_enable (); // power everything back on
}