Fixed issue #1 Power saving
This commit is contained in:
parent
40b6b68933
commit
e79cbc265a
51
Globals.cpp
51
Globals.cpp
|
@ -1,5 +1,7 @@
|
||||||
|
#include "NerfStatTrakConfig.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "StateHandler.h"
|
#include "StateHandler.h"
|
||||||
|
#include "LowPower.h"
|
||||||
|
|
||||||
|
|
||||||
SegmentDisplay* display;
|
SegmentDisplay* display;
|
||||||
|
@ -22,3 +24,52 @@ void setCurrentState(AbstractStateHandler* value)
|
||||||
currentState = value;
|
currentState = value;
|
||||||
currentState->setup();
|
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())
|
||||||
|
shots++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,5 +18,7 @@ extern unsigned long currentTime;
|
||||||
extern AbstractStateHandler* currentState;
|
extern AbstractStateHandler* currentState;
|
||||||
|
|
||||||
void setCurrentState(AbstractStateHandler* value);
|
void setCurrentState(AbstractStateHandler* value);
|
||||||
|
void update();
|
||||||
|
void sleep();
|
||||||
|
|
||||||
#endif
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,169 @@
|
||||||
|
#ifndef LowPower_h
|
||||||
|
#define LowPower_h
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
enum period_t
|
||||||
|
{
|
||||||
|
SLEEP_15MS,
|
||||||
|
SLEEP_30MS,
|
||||||
|
SLEEP_60MS,
|
||||||
|
SLEEP_120MS,
|
||||||
|
SLEEP_250MS,
|
||||||
|
SLEEP_500MS,
|
||||||
|
SLEEP_1S,
|
||||||
|
SLEEP_2S,
|
||||||
|
SLEEP_4S,
|
||||||
|
SLEEP_8S,
|
||||||
|
SLEEP_FOREVER
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bod_t
|
||||||
|
{
|
||||||
|
BOD_OFF,
|
||||||
|
BOD_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum adc_t
|
||||||
|
{
|
||||||
|
ADC_OFF,
|
||||||
|
ADC_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer5_t
|
||||||
|
{
|
||||||
|
TIMER5_OFF,
|
||||||
|
TIMER5_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer4_t
|
||||||
|
{
|
||||||
|
TIMER4_OFF,
|
||||||
|
TIMER4_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer3_t
|
||||||
|
{
|
||||||
|
TIMER3_OFF,
|
||||||
|
TIMER3_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer2_t
|
||||||
|
{
|
||||||
|
TIMER2_OFF,
|
||||||
|
TIMER2_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer1_t
|
||||||
|
{
|
||||||
|
TIMER1_OFF,
|
||||||
|
TIMER1_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum timer0_t
|
||||||
|
{
|
||||||
|
TIMER0_OFF,
|
||||||
|
TIMER0_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum spi_t
|
||||||
|
{
|
||||||
|
SPI_OFF,
|
||||||
|
SPI_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum usart0_t
|
||||||
|
{
|
||||||
|
USART0_OFF,
|
||||||
|
USART0_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum usart1_t
|
||||||
|
{
|
||||||
|
USART1_OFF,
|
||||||
|
USART1_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum usart2_t
|
||||||
|
{
|
||||||
|
USART2_OFF,
|
||||||
|
USART2_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum usart3_t
|
||||||
|
{
|
||||||
|
USART3_OFF,
|
||||||
|
USART3_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum twi_t
|
||||||
|
{
|
||||||
|
TWI_OFF,
|
||||||
|
TWI_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum usb_t
|
||||||
|
{
|
||||||
|
USB_OFF,
|
||||||
|
USB_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
enum idle_t
|
||||||
|
{
|
||||||
|
IDLE_0,
|
||||||
|
IDLE_1,
|
||||||
|
IDLE_2
|
||||||
|
};
|
||||||
|
|
||||||
|
class LowPowerClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if defined (__AVR__)
|
||||||
|
|
||||||
|
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
|
||||||
|
void idle(period_t period, adc_t adc, timer2_t timer2,
|
||||||
|
timer1_t timer1, timer0_t timer0, spi_t spi,
|
||||||
|
usart0_t usart0, twi_t twi);
|
||||||
|
#elif defined __AVR_ATmega2560__
|
||||||
|
void idle(period_t period, adc_t adc, timer5_t timer5,
|
||||||
|
timer4_t timer4, timer3_t timer3, timer2_t timer2,
|
||||||
|
timer1_t timer1, timer0_t timer0, spi_t spi,
|
||||||
|
usart3_t usart3, usart2_t usart2, usart1_t usart1,
|
||||||
|
usart0_t usart0, twi_t twi);
|
||||||
|
#elif defined __AVR_ATmega256RFR2__
|
||||||
|
void idle(period_t period, adc_t adc, timer5_t timer5,
|
||||||
|
timer4_t timer4, timer3_t timer3, timer2_t timer2,
|
||||||
|
timer1_t timer1, timer0_t timer0, spi_t spi,
|
||||||
|
usart1_t usart1,
|
||||||
|
usart0_t usart0, twi_t twi);
|
||||||
|
#elif defined __AVR_ATmega32U4__
|
||||||
|
void idle(period_t period, adc_t adc, timer4_t timer4,
|
||||||
|
timer3_t timer3, timer1_t timer1, timer0_t timer0,
|
||||||
|
spi_t spi, usart1_t usart1, twi_t twi, usb_t usb);
|
||||||
|
#else
|
||||||
|
#error "Please ensure chosen MCU is either 168, 328P, 32U4, 2560 or 256RFR2."
|
||||||
|
#endif
|
||||||
|
void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2) __attribute__((optimize("-O1")));
|
||||||
|
void powerDown(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1")));
|
||||||
|
void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1")));
|
||||||
|
void powerStandby(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1")));
|
||||||
|
void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1")));
|
||||||
|
|
||||||
|
#elif defined (__arm__)
|
||||||
|
|
||||||
|
#if defined (__SAMD21G18A__)
|
||||||
|
void idle(idle_t idleMode);
|
||||||
|
void standby();
|
||||||
|
#else
|
||||||
|
#error "Please ensure chosen MCU is ATSAMD21G18A."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "Processor architecture is not supported."
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LowPowerClass LowPower;
|
||||||
|
#endif
|
|
@ -39,15 +39,6 @@ void setup()
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
currentTime = millis();
|
update();
|
||||||
|
|
||||||
buttonA->update(currentTime);
|
|
||||||
buttonB->update(currentTime);
|
|
||||||
buttonArmed->update(currentTime);
|
|
||||||
|
|
||||||
// Count the shot no matter which state we're in
|
|
||||||
if (buttonArmed->changed() && !buttonArmed->pressed())
|
|
||||||
shots++;
|
|
||||||
|
|
||||||
currentState->loop();
|
currentState->loop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,17 @@
|
||||||
#define NerfButtonB 2
|
#define NerfButtonB 2
|
||||||
#define NerfButtonArmed 4
|
#define NerfButtonArmed 4
|
||||||
|
|
||||||
|
// Must be usable for interrupts
|
||||||
|
#define NerfButtonWakeUp 2
|
||||||
|
#define NerfButtonWakeUpState LOW
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default state configuration
|
* Default state configuration
|
||||||
**/
|
**/
|
||||||
#define NerfDefaultIntroTime 1000
|
#define NerfDefaultIntroTime 1000
|
||||||
|
#define NerfDefaultSleepTime 10000
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,12 +8,13 @@
|
||||||
bool DefaultState::ShowHits = true;
|
bool DefaultState::ShowHits = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DefaultState::setup()
|
void DefaultState::setup()
|
||||||
{
|
{
|
||||||
introStart = currentTime;
|
introStart = currentTime;
|
||||||
|
lastAction = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DefaultState::loop()
|
void DefaultState::loop()
|
||||||
{
|
{
|
||||||
if (buttonA->pressed() && buttonB->pressed())
|
if (buttonA->pressed() && buttonB->pressed())
|
||||||
|
@ -30,12 +31,15 @@ void DefaultState::loop()
|
||||||
|
|
||||||
if (!DefaultState::ShowHits)
|
if (!DefaultState::ShowHits)
|
||||||
setShowHits(true);
|
setShowHits(true);
|
||||||
|
|
||||||
|
lastAction = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// B short (triggered on release)
|
// B short (triggered on release)
|
||||||
if (buttonB->changed() && !buttonB->pressed() && buttonB->pressedMillis(currentTime) <= NerfButtonLongPressThreshold)
|
if (buttonB->changed() && !buttonB->pressed() && buttonB->pressedMillis(currentTime) <= NerfButtonLongPressThreshold)
|
||||||
{
|
{
|
||||||
setShowHits(!DefaultState::ShowHits);
|
setShowHits(!DefaultState::ShowHits);
|
||||||
|
lastAction = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// B long
|
// B long
|
||||||
|
@ -45,6 +49,13 @@ void DefaultState::loop()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shot
|
||||||
|
if (buttonArmed->changed() && !buttonArmed->pressed())
|
||||||
|
{
|
||||||
|
// The shot has already been counted in Globals.cpp
|
||||||
|
lastAction = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (showIntro)
|
if (showIntro)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +76,13 @@ void DefaultState::loop()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (currentTime - lastAction >= NerfDefaultSleepTime)
|
||||||
|
{
|
||||||
|
sleep();
|
||||||
|
|
||||||
|
lastAction = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
if (DefaultState::ShowHits)
|
if (DefaultState::ShowHits)
|
||||||
display->writeNumber(hits);
|
display->writeNumber(hits);
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,6 +20,7 @@ class DefaultState : public AbstractStateHandler
|
||||||
private:
|
private:
|
||||||
bool showIntro = true;
|
bool showIntro = true;
|
||||||
unsigned long introStart;
|
unsigned long introStart;
|
||||||
|
unsigned long lastAction;
|
||||||
|
|
||||||
void setShowHits(bool value);
|
void setShowHits(bool value);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue