#include "power.h" #ifdef BTN_PWR Button buttonPower(BTN_PWR, 250UL, 1U, 0); #endif #ifdef VBATTPIN Battery battery(VBATTMIN, VBATTMAX, VBATTPIN); #endif uint64_t measure_timer = 0; uint64_t powerOnOffDelay = 0; powerStates powerstate = off; void initBattery(void) { #ifdef VBATTPIN #ifdef MEAS_EN battery.onDemand(MEAS_EN, LOW); 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 measureBattery(void) { uint16_t vbatt = battery.voltage(); if (vbatt < VBATTMIN) { return true; } return false; } bool handleBattery(void) { #ifdef VBATTPIN uint64_t currentmillis = millis(); if (currentmillis - measure_timer > BATTERYMEASUREDELAY) { return measureBattery(); measure_timer = currentmillis; } #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(500)) { turnOnLed(2); } else if (buttonPower.pressedFor(200)) { turnOnLed(3); } else { turnOffAllLed(); powerstate = off; } } break; case poweringOn2: { if (!buttonread) { powerstate = powerinit; powerOn(); turnOffAllLed(); delay(200); batterydisplay(); delay(500); turnOffAllLed(); if(measureBattery()) { powerstate = lowBatt; } } } break; case powerinit: { initGames(); powerstate = on; } break; case on: { if (buttonPower.pressedFor(100)) { powerstate = poweringOff; turnOnAllLed(); break; } if (HandleTimeOut()) { powerstate = timeOut; break; } if (handleBattery()) { powerstate = lowBatt; break; } } break; case poweringOff: { if (buttonPower.pressedFor(POWERBUTTONDELAY)) { turnOffLed(1); powerstate = poweringOff2; } else if (buttonPower.pressedFor(500)) { turnOffLed(2); } else if (buttonPower.pressedFor(200)) { 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; } } uint64_t lasttimeOut = 0; bool buttonChanged = false; uint8_t buttonCount = 0; //handleTimeout //return true when timed out bool HandleTimeOut(void) { uint64_t currentmillis = millis(); if (!lasttimeOut) { lasttimeOut = currentmillis; buttonChanged = anybutton(); } //check if lastTime is initialized or timeout expired if ((currentmillis - lasttimeOut > IDLESHUTDOWN)) { return true; } else { if (buttonPressedCount() != buttonCount) { buttonCount = buttonPressedCount(); lasttimeOut = currentmillis; } // if (buttonChanged != anybutton()) // { // buttonChanged = anybutton(); // //game in progress, update timer // lasttimeOut = currentmillis; // } } return false; } void HandlePower(void) { handlePowerState(); }