#include "NerfStatTrakConfig.h" #include "Globals.h" #include "StateHandler.h" #include "LowPower.h" #include "EEPROM.h" SegmentDisplay* display; Button* buttonA; Button* buttonB; Button* buttonArmed; uint32_t shots = 0; uint32_t hits = 0; unsigned long currentTime; AbstractStateHandler* currentState; byte shotCounterOffset; byte hitCounterOffset; #define counterTreshold (uint32_t)10000 uint32_t lastShotCounterIteration; uint32_t lastHitCounterIteration; void setCurrentState(AbstractStateHandler* value) { buttonA->block(); buttonB->block(); currentState = value; currentState->setup(); } void update() { currentTime = millis(); buttonA->update(currentTime); buttonB->update(currentTime); buttonArmed->update(currentTime); // Count the shot no matter which state we're in if (buttonArmed->changed() && !buttonArmed->pressed()) addShot(); } void wakeUp() { } void sleep() { display->clear(); // Uses RocketScream's Low-Power library // https://github.com/rocketscream/Low-Power uint32_t interrupt = digitalPinToInterrupt(NerfButtonWakeUp); attachInterrupt(interrupt, wakeUp, NerfButtonWakeUpState); LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); detachInterrupt(interrupt); currentTime = millis(); // The button triggers the wake-up, so block the first release after if (NerfButtonWakeUp == NerfButtonA) { buttonA->update(currentTime); buttonA->block(); } if (NerfButtonWakeUp == NerfButtonB) { buttonB->update(currentTime); buttonB->block(); } } #define counterLocation(offset) 2 + (offset * sizeof(uint32_t)) void readCounters() { shotCounterOffset = EEPROM.read(0); hitCounterOffset = EEPROM.read(1); EEPROM.get(counterLocation(shotCounterOffset), shots); EEPROM.get(counterLocation(hitCounterOffset), hits); lastShotCounterIteration = shots / counterTreshold; lastHitCounterIteration = hits / counterTreshold; } void setShots(uint32_t value) { shots = value; uint32_t newShotCounterIteration = shots / counterTreshold; if (newShotCounterIteration != lastShotCounterIteration || value == 0) { shotCounterOffset++; if (counterLocation(shotCounterOffset) > EEPROM.length() - sizeof(uint32_t)) { shotCounterOffset = 0; if (shotCounterOffset == hitCounterOffset) shotCounterOffset++; } EEPROM.write(0, shotCounterOffset); lastShotCounterIteration = newShotCounterIteration; } EEPROM.write(counterLocation(shotCounterOffset), shots); } void addShot() { setShots(shots + 1); } void setHits(uint32_t value) { hits = value; uint32_t newHitCounterIteration = hits / counterTreshold; if (newHitCounterIteration != lastHitCounterIteration || value == 0) { hitCounterOffset++; if (counterLocation(hitCounterOffset) > EEPROM.length() - sizeof(uint32_t)) { hitCounterOffset = 0; if (hitCounterOffset == shotCounterOffset) hitCounterOffset++; } EEPROM.write(1, hitCounterOffset); lastHitCounterIteration = newHitCounterIteration; } EEPROM.write(counterLocation(hitCounterOffset), hits); } void addHit() { setHits(hits + 1); } void resetShots() { setShots(0); } void resetHits() { setHits(0); }