This is an alternative to a soft latching power switch circuit using only one momentary switch, like an ordinary tactile push button and one MCU pin to deliver power to the system.
When a Power-on reset occurs, for example when the MCU is connected to the power supply, the microcontroller goes to sleep using the power down mode and the system, which means the whole circuit that receives power from a MCU pin, is turned off. When the switch is turned on the microcontroller wakes up and turn on the system delivering power. During the main event loop of the application, the power switch is polled in order to know if the switch was pressed again. When the switch is pressed by the second time the MCU turns off the system and goes to sleep again. If the button is presseg again(the third time) the microcontroller wakes up and it resets itself using a watchdog timer in reset mode, and the whole cycle begins again.
#include <power_switch.hpp>
#define F_CPU 1e6
#include <util/delay.h>
using namespace avr::io;
/** This demo illustrates how to use only one momentary switch plus
one pin to deliver power to implement a power switch.
The load is represented by a LED connected to the pin PB0 and it
can be turned on or off by a push button connected to the pin
PB2. When the MCU is started it goes to sleep using the power-down
sleep mode. If the switch is pressed the MCU wakes up and turns on
the LED. If the switch is pressed again the MCU turns off the LED
and goes to sleep.
*/
static auto& load{pb0};
static auto& sw{pb2};
/** ISR to turn on the system when the MCU is sleeping and the power
switch is pressed. */
AVRINT_PCINT0(){ power::turnon(sw, load); }
int main() {
/** The system is halted at the startup and it turns on when the
switch is pressed.
btn_pressed and btn_released are predicates to be implemented
by the user. It's vital that the implementation debounces the
button if it's necessary.
*/
power::sw power(sw, load, btn_pressed, btn_released);
while(true) {
/** Polling to check if the system should be turned off. */
power.poll();
}
}
The demo uses 351 bytes
when compiled with avr-gcc 10.2 -Os -flto
-mmcu=attiny85
.
avr-gcc
with at least support to C++17.- avrcxx
- The pin connected to the push button must be a
PCINT
pin.
Any AVR8 that offers PCINT
and the watchdog timer with a timeout value of 16ms
should be supported.
- ATtiny25/45/85