I'm using an atmega328 on AVR. I haven't done any coding yet but I am planning. How I will do so in my head. So I want to be able to wake up the ATmega328 via a button press, and go to sleep after I've pressed the same button. How will I do that?
In my head, it is similar to this.
I will place the sleep code in the main function, and also a while loop in the ISR function.
When it detects a button press, it will break out of the while loop and go back to sleep.
Will this work?
How does an ATmega handle button press while it is in the interrupt service routine function? Or how does it distinguish between a button press to interrupt the sleep and a button press to go to sleep?
Best Answer
Interrupts and button pushes don't mix AT ALL. Buttons have a phenomenon knows a bounce. Just before the contacts close they "bounce" making and breaking contact. If for example using a pin change interrupt with a button you may enter and exit sleep mode a bunch of times before the button stabilizes. Buttons need debounced, a technique that makes sure that the button state is stable before reading that button.
The best way to debounce a button is to read the state of the button in regular intervals, 1ms for example. If the state of the button stays constant for at least 50ms the button can be considered stable.
The way i normally write such a routine is check the button every 1ms. If a debounce event is not in progress and the current button state does not match the past button state, start a debounce event. Continue checking the button every 1ms but increment a counter every time a button read occurs. Normally i'll start at 50. If the button is lows i'll decrement and if the button is high i'll increment. If you get to 100 then the button is high and if you get to 0 the button is low. Reset the start variable back to 50 and set debounce event to false.
In your case i would use the pin change interrupt to wake the micro but then impose a mandatory debounce. If the debounce passes then stay awake. If the debouce fails, meaning that a button was not pushed, then fall back to sleep.