#include "power.h" #ifdef BTN_PWR Button buttonPower(BTN_PWR, 250UL, 1U, 0); #endif #ifdef VBATTPIN Battery battery(VBATTMIN, VBATTMAX, VBATTPIN); #endif uint64_t delay_timer = 0; uint64_t powerOnOffDelay = 0; powerStates powerstate = off; void initBattery(void) { #ifdef VBATTPIN #ifdef MEAS_EN battery.onDemand(MEAS_EN, LOW); //pinMode(MEAS_EN, OUTPUT); //digitalWrite(MEAS_EN, HIGH); battery.begin(VBATTREF, (R12 + R13) / R13); //R1 = 220K, R2 = 100K, factor = (R1+R2)/R2 #else battery.begin(VBATTREF, (R12 + R13) / R13); //R1 = 220K, R2 = 100K, factor = (R1+R2)/R2 #endif #endif } void batterydisplay(void) { #ifdef VBATTPIN uint16_t currentlevel = battery.level(); if (currentlevel > 90) { turnOnLed(3); } if (currentlevel > 50) { turnOnLed(2); } if (currentlevel > 20) { turnOnLed(1); } #endif } void powerOn(void) { digitalWrite(PW_HOLD, HIGH); } void powerOff(void) { digitalWrite(PW_HOLD, LOW); } bool handleBattery(void) { #ifdef VBATTPIN uint64_t currentmillis = millis(); if (currentmillis - delay_timer > BATTERYMEASUREDELAY) { uint32_t vbatt = battery.voltage(); if (vbatt < VBATTMIN) { return true; } } #endif return false; } void initPowerOn(void) { #ifdef PW_HOLD pinMode(PW_HOLD, OUTPUT); powerstate = poweringOn; buttonPower.begin(); #endif } //low power void initPower(void) { initBattery(); initPowerOn(); } void shutdown(void) { powerOff(); //LowPower_shutdown(); delay(10000); } powerStates getPowerState(void) { return powerstate; } //handle power asynchronious void handlePowerState(void) { bool buttonread = buttonPower.read(); //update powerbutton switch (powerstate) { case off: { if (buttonread) { powerstate = poweringOn; } powerOff(); } break; case poweringOn: { if (buttonPower.pressedFor(POWERBUTTONDELAY)) { turnOnLed(1); powerstate = poweringOn2; } else if (buttonPower.pressedFor(800)) { turnOnLed(2); } else if (buttonPower.pressedFor(100)) { turnOnLed(3); } else { turnOffAllLed(); powerstate = off; } } break; case poweringOn2: { if (!buttonread) { powerstate = on; powerOn(); turnOffAllLed(); delay(500); batterydisplay(); delay(1000); turnOffAllLed(); } } break; case on: { if (buttonPower.pressedFor(100)) { powerstate = poweringOff; turnOnAllLed(); } else if (HandleTimeOut()) { powerstate = timeOut; } else if (handleBattery()) { powerstate = lowBatt; } } break; case poweringOff: { if (buttonPower.pressedFor(POWERBUTTONDELAY)) { turnOffLed(1); powerstate = poweringOff2; } else if (buttonPower.pressedFor(950)) { turnOffLed(2); } else if (buttonPower.pressedFor(450)) { turnOffLed(3); } else { turnOffAllLed(); powerstate = on; } } break; case poweringOff2: { if(!buttonread) { powerstate = off; } } break; case timeOut: { powerstate = off; powerOff(); delay(5000); } break; case lowBatt: { powerstate = off; for (int i = 0; i < 6; i++) { turnOnAllLed(); delay(200); turnOffAllLed(); delay(200); } } break; } } //handleTimeout //return true when timed out bool HandleTimeOut(void) { uint64_t currentmillis = millis(); static uint64_t lasttimeOut = 0; static bool buttonChanged = false; if (!lasttimeOut) { lasttimeOut = currentmillis; buttonChanged = anybutton(); } //check if lastTime is initialized or timeout expired if ((currentmillis - lasttimeOut > IDLESHUTDOWN)) { return true; } else { if (buttonChanged != anybutton()) { buttonChanged = anybutton(); //game in progress, update timer lasttimeOut = currentmillis; } } return false; } void HandlePower(void) { handlePowerState(); }