Fixed issue #1 Power saving

This commit is contained in:
Mark van Renswoude 2016-12-10 00:00:42 +01:00
parent 40b6b68933
commit e79cbc265a
8 changed files with 1310 additions and 11 deletions

View File

@ -1,5 +1,7 @@
#include "NerfStatTrakConfig.h"
#include "Globals.h"
#include "StateHandler.h"
#include "LowPower.h"
SegmentDisplay* display;
@ -22,3 +24,52 @@ void setCurrentState(AbstractStateHandler* value)
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())
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();
}
}

View File

@ -18,5 +18,7 @@ extern unsigned long currentTime;
extern AbstractStateHandler* currentState;
void setCurrentState(AbstractStateHandler* value);
void update();
void sleep();
#endif

1062
LowPower.cpp Normal file

File diff suppressed because it is too large Load Diff

169
LowPower.h Normal file
View File

@ -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

View File

@ -39,15 +39,6 @@ void setup()
void loop()
{
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++;
update();
currentState->loop();
}

View File

@ -33,12 +33,17 @@
#define NerfButtonB 2
#define NerfButtonArmed 4
// Must be usable for interrupts
#define NerfButtonWakeUp 2
#define NerfButtonWakeUpState LOW
/**
* Default state configuration
**/
#define NerfDefaultIntroTime 1000
#define NerfDefaultSleepTime 10000
#endif

View File

@ -8,12 +8,13 @@
bool DefaultState::ShowHits = true;
void DefaultState::setup()
{
introStart = currentTime;
lastAction = currentTime;
}
void DefaultState::loop()
{
if (buttonA->pressed() && buttonB->pressed())
@ -30,12 +31,15 @@ void DefaultState::loop()
if (!DefaultState::ShowHits)
setShowHits(true);
lastAction = currentTime;
}
// B short (triggered on release)
if (buttonB->changed() && !buttonB->pressed() && buttonB->pressedMillis(currentTime) <= NerfButtonLongPressThreshold)
{
setShowHits(!DefaultState::ShowHits);
lastAction = currentTime;
}
// B long
@ -45,6 +49,13 @@ void DefaultState::loop()
return;
}
// Shot
if (buttonArmed->changed() && !buttonArmed->pressed())
{
// The shot has already been counted in Globals.cpp
lastAction = currentTime;
}
if (showIntro)
{
@ -65,6 +76,13 @@ void DefaultState::loop()
}
else
{
if (currentTime - lastAction >= NerfDefaultSleepTime)
{
sleep();
lastAction = currentTime;
}
if (DefaultState::ShowHits)
display->writeNumber(hits);
else

View File

@ -20,6 +20,7 @@ class DefaultState : public AbstractStateHandler
private:
bool showIntro = true;
unsigned long introStart;
unsigned long lastAction;
void setShowHits(bool value);