/power_switch

C++17 solution to implement a power switch using only one push button plus one MCU pin to deliver power.

Primary LanguageC++

power switch

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.

How it works?

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.

Demo using one LED as load

#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();
    }
}

demo.cpp

The demo uses 351 bytes when compiled with avr-gcc 10.2 -Os -flto -mmcu=attiny85.

Requirements and dependencies

  1. avr-gcc with at least support to C++17.
  2. avrcxx
  3. The pin connected to the push button must be a PCINT pin.

Supported MCUs

Any AVR8 that offers PCINT and the watchdog timer with a timeout value of 16ms should be supported.

Tested on

  1. ATtiny25/45/85