NerfStatTrak/Globals.cpp
Mark van Renswoude 211740d51a Fixed #2 Persist counters
Added initialisation sketch and reset state
2016-12-10 12:01:43 +01:00

168 lines
3.2 KiB
C++

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