For those who run into the same issue and want to power down between button clicks and use this handy "Onebutton" library, here is a general sketch that I got to work.
I had to edit the library, see attached, to create a new function that gets called when a debounce error is detected. This allows the while loop to exit and the uC to go back to sleep without getting caught in the loop. Makes the sketch more low power friendly.
#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <LowPower.h>
#include <OneButton.h>
#include <RFM69.h>
#include <SPI.h>
// Setup a new OneButton on pin D5 (UP BUTTON) --> true parameter enables the pullup resistor on this pin
OneButton button1(5, true);
// Setup a new OneButton on pin D3 (DOWN BUTTON) --> true parameter enables the pullup resistor on this pin
OneButton button2(3, true);
#define UPPIN 5
#define DOWNPIN 3
// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID 0 // Must be the same for all nodes
#define MYNODEID 2 // My node ID
#define TONODEID 1 // Destination node ID
// RFM69 frequency
#define FREQUENCY RF69_915MHZ
// AES encryption (or not):
#define ENCRYPT true // Set to "true" to use encryption
#define ENCRYPTKEY "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes
// Use ACKnowledge when sending messages (or not):
#define USEACK true // Request ACKs or not
// Packet sent/received indicator LED (optional):
#define LED 9 // LED positive pin
//#define GND 8 // LED ground pin
// Create a library object for our RFM69HCW module:
RFM69 radio;
volatile bool newbutton = false;
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
void setup() {
pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
// link the button 1 functions.
button1.attachClick(click1); //single click
button1.attachNull(nullclick1); //debounce error
//button1.attachDoubleClick(doubleclick1);
//button1.attachLongPressStop(longPressStop1);
// link the button 2 functions.
button2.attachClick(click2); //single click
button2.attachNull(nullclick2); //debounce error
//button2.attachDoubleClick(doubleclick2);
//button2.attachLongPressStop(longPressStop2);
//Initialize the RFM69HCW:
radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
// Turn on encryption if set to true above
if (ENCRYPT)
radio.encrypt(ENCRYPTKEY);
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
void upinterrupt(){
newbutton = true; //this variable will be used to enter loop to start checking for button clicks
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
void downinterrupt(){
newbutton = true; //this variable will be used to enter loop to start checking for button clicks
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
void loop()
{
digitalWrite(LED,LOW); //make sure the LED is off before going to sleep indefinitely.
//These interrupts will wake the module when it is powered down to save battery
enableInterrupt(UPPIN, upinterrupt, FALLING); //enables interrupt on UPPIN and calls upinterrupt. This is using the enable interrupt library for a pin change interrupt
attachInterrupt(digitalPinToInterrupt(DOWNPIN), downinterrupt, FALLING); //enables interrupt on DOWNPIN and calls downinterrupt. This is the standard external interrupt pin
radio.sleep(); //Put the RFM69 to sleep
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //Put Moteino to power down sleep. Will wake on interrupt and run the next line of code after ISR
//First line to run after the ISR that wakes the module:
disableInterrupt(UPPIN);
detachInterrupt(DOWNPIN); //Prevents interrupts being called again until everything is complete
while(newbutton){ //ISR that wakes up module will set this to true and we can keep checking for click/doubleclick/hold
button1.tick(); //check button1 (UP) for click, double click, hold
button2.tick(); //check button1 (UP) for click, double click, hold
}
} // loop
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//UP BUTTON PRESSED
void click1() {
//do something here on a single click event. Send a message with the radio or check for messages etc.
newbutton = false; //after the event is complete it allows us to exit the loop checking for button presses
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
// DOWN BUTTON PRESSED
void click2() {
//do something here on a single click event. Send a message with the radio or check for messages etc.
newbutton = false; //after the event is complete it allows us to exit the loop checking for button presses
}
// click2
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//Debounce Error on first button
void nullclick1() {
newbutton = false; //in the event of a debounce error we still need to set this variable to false, otherwise while loop will keep moteino awake until the next button press essentially wasting battery
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//Debounce Error on second button
void nullclick2() {
newbutton = false; //in the event of a debounce error we still need to set this variable to false, otherwise while loop will keep moteino awake until the next button press essentially wasting battery
}
Also note that the RFM69 and SPI libraries are not necessary if you do not have the RFM69 module in your project. I left them in there along with the radio initialization code but removed my code that was sending messages through the radio. Cut things out as required for your project.
Hope this helps someone in the future!
OneButtonEdited.zip (12.3 KB)