Ok so having a little bit of an issue here. I have tried searching this on google and have gotten some ok info which has helped get me to the point I am, but I'm kind of stuck. The code works, but not exactly as intended so I'm hoping someone can help me out. I cannot post "all" of the code due to 1(its way to long, and 2(some of it is proprietary. So, I am posting what is relevant. So, I am trying to put the unit to sleep and wake it up with one button. Upon initial power up the board goes straight to sleep (like I want). If I press the interrupt button it will wake up perfectly into one on of two operating modes depending on which is selected before waking up. Now Going back into sleep the button is held, a LED does a little flash, and the unit goes to sleep. Here is the problem.... When I press the button to wake it up it should just wake up, but instead it has to be pressed and held. The status led will go a little crazy and then flash its startup indicating flashes and when you get to that point you have to let off the button and it looks like it's still asleep but if you tap the button again it wakes up just fine. Any Ideas on this one??? The button is being debounced. That portion of the code is in the code post below. That portion seems to work just fine as well I've never encountered any issues with it, and I use it to bounce two other buttons one of which has similar function of the wake and sleep but it's just turning on and off an LED.
#include <avr/sleep.h> // for sleep mode
byte PriorPowerButtonState = 0;
byte PowerButtonState = 0;
volatile bool enableSleepButton = false;
volatile bool Op_SleepMode = false;
unsigned long Op_LastSleepMS = 0.00;
bool Op_PowerButtonWasPressed = false;
void setup_pins() {
pinMode(POWER_PIN, OUTPUT);
digitalWrite(POWER_PIN, HIGH);
}
void goToSleep(void) {
Op_SleepMode = true;
ledOffSleep();
disableEyeTX(); // TURN EYES OFF
attachInterrupt(digitalPinToInterrupt(POWER_PIN), wakeUp, LOW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable(); // enables the sleep bit in the mcucr register
sleep_cpu(); // here the device is put to sleep
}
void wakeUp() {
Op_SleepMode = false;
enableSleepButton = true;
detachInterrupt(digitalPinToInterrupt(POWER_PIN));
sleep_disable();
setup_pins();
loop(); //HAD TO ADD THIS TO MAKE THE BOARD WAKE UP AT ALL AFTER THE INTIAL WAKE UP AND THEN GOING BACK TO SLEEP
}
unsigned long getPowerButtonDownMS() {
if (POWER_PIN_STATE_PRESSED == PowerButton_State || POWER_PIN_STATE_HELD == PowerButton_State) {
return millis() - PowerButton_PressStartMS;
} else {
return 0;
}
}
int getPowerButtonState() {
int powerButtonReading = digitalRead(POWER_PIN); // read the state of the pushbutton value:
if (POWER_PIN_CLOSED == powerButtonReading) { // BUTTON APPEARS TO BE PUSHED
if (PowerButton_PriorReading == powerButtonReading) {
bool powerButtonDebounced = false;
switch (Conf_DebounceMode) {
case DEBOUNCE_MODE_DELAY:
powerButtonDebounced = debouncePowerButtonDelay();
break;
case DEBOUNCE_MODE_DELAY_FINE:
powerButtonDebounced = debouncePowerButtonDelayFine();
break;
default:
case DEBOUNCE_MODE_SEQUENTIAL:
powerButtonDebounced = debouncePowerButtonSequential();
break;
}
if (powerButtonDebounced) { // bouncing has stopped, now perform button push action
if (POWER_PIN_STATE_DEBOUNCING == PowerButton_State) {
PowerButton_PriorState = PowerButton_State;
PowerButton_State = POWER_PIN_STATE_PRESSED;
PowerButton_PressStartMS = millis(); // track this once, when we first note that the button is pushed
} else if (POWER_PIN_STATE_PRESSED == PowerButton_State) {
PowerButton_State = POWER_PIN_STATE_HELD; // already registered the push, but still getting button down signal
}
}
} else {
PowerButton_State = POWER_PIN_STATE_DEBOUNCING; // button is down, start counting
PowerButton_PriorReading = powerButtonReading;
Debounce_PowerPinSameStateCount = 1; // track this for DEBOUNCE_MODE_SEQUENTIAL
}
} else {
// trigger appears to be released
if (PowerButton_PriorReading == powerButtonReading) {
bool powerButtonDebounced = false;
switch (Conf_DebounceMode) {
case DEBOUNCE_MODE_DELAY:
powerButtonDebounced = debouncePowerButtonDelay();
break;
case DEBOUNCE_MODE_DELAY_FINE:
powerButtonDebounced = debouncePowerButtonDelayFine();
break;
default:
case DEBOUNCE_MODE_SEQUENTIAL:
powerButtonDebounced = debouncePowerButtonSequential();
break;
}
if (powerButtonDebounced) { // bouncing has stopped, now perform button push action
if (POWER_PIN_STATE_DEBOUNCING == PowerButton_State) {
PowerButton_PriorState = PowerButton_State;
PowerButton_State = POWER_PIN_STATE_RELEASED;
// do we need to track button release start?
//// track this once, when we first note that the button is pressed
//PowerButton_PressStartMS = millis();
} else if (POWER_PIN_STATE_RELEASED == PowerButton_State) {
// already registered the pull, but still getting button down signal
PowerButton_State = POWER_PIN_STATE_WAITING;
}
}
} else {
// button is up, start counting
PowerButton_State = POWER_PIN_STATE_DEBOUNCING;
PowerButton_PriorReading = powerButtonReading;
// track this for DEBOUNCE_MODE_SEQUENTIAL
Debounce_PowerPinSameStateCount = 1;
}
}
return PowerButton_State;
}
// this debounce method waits for Debounce_MinPowerButtonDownCount sequential POWER_PIN_CLOSED reads
// you can be sure that after a reasonable number of idential sequential reads that the state is stable
// this is based on code from http://www.ganssle.com/debouncing-pt2.htm
bool debouncePowerButtonSequential() {
// increment counter and keep checking
Debounce_PowerPinSameStateCount++;
if (Debounce_PowerPinSameStateCount >= Debounce_MinPowerButtonDownCount) {
return true;
}
return false;
}
// this is a generic debounce method that simply waits for a short
// period of time for the switch to stop bouncing.
bool debouncePowerButtonDelay() {
// delay Debounce_DelayTime ms and return true
delay(Debounce_DelayTime * 3);
return true;
}
// this is a generic debounce method that simply waits for a short
// period of time for the switch to stop bouncing.
// this version delays in smaller increments
bool debouncePowerButtonDelayFine() {
// delay Debounce_DelayTime * 100 ms and return true
delayMicroseconds(Debounce_DelayTime * 100);
return true;
}
void FM_UpdatePowerButtonState() {
PriorPowerButtonState = PowerButtonState;
PowerButtonState = getPowerButtonState();
}
void FM_HandlePowerButton() {
FM_UpdatePowerButtonState();
if (!Op_SleepMode) {
if (POWER_PIN_STATE_PRESSED == PowerButtonState || POWER_PIN_STATE_HELD == PowerButtonState) {
if (POWER_PIN_STATE_HELD == PowerButtonState) {
unsigned long ms = getPowerButtonDownMS();
if (ms >= OP_POWER_OFF_BUTTON_TIME) { //---make sure we didn't do this already----
if (enableSleepButton) { // after adding this, it now works properly - but is the approach correct?
delay(1000);
powerOffLEDBurst();
goToSleep();
}
}
}
}
}
}
void setup() {
setup_pins();
attachInterrupt(digitalPinToInterrupt(POWER_PIN), goToSleep, RISING);
}
void loop() {
FM_HandlePowerButton();
if (MODE_FIRING == OperatingMode) {
firingMode();
operatingLEDBlink(); //BLINK TO INDICATE THAT THE UNIT IS ON IF LED_DISABLE_BLINKING IS SET TO TURE IN THE CONFIGURATIN.H PAGE
} else {
if (MODE_PROGRAMMING == OperatingMode) {
programmingMode();
}
}
}