My current setup has the arduino in 'stand-by' power saving mode, therefore i am unable to use any means of a traditional soft debouncer, such as Bounce2, as far as I know.
I went ahead and attached the buttons to pin change interrupts, since I have one button on each bank, i.e. pin 7 and pin 11.
The technique I'm using doesn't seem to be behaving since the routines are being fired too regularly (inconsistently), and at the rising edge too.
I have the pins set to use their internal pull-ups.
Using the PCI library:
void pciSetup(byte pin)
{
*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the
pciSetup(POWER_SWITCH);
pciSetup(SELECTOR_BTN);
// check if IR IN or Power switch
ISR (PCINT0_vect) // handle pin change interrupt for D8 to D13 here
{
if (digitalRead(POWER_SWITCH) == LOW)
{
noInterrupts();
unsigned long last_millis = millis();
while (millis() - last_millis >= 500);
ir_power_pressed = true;
}
interrupts();
}
ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7
noInterrupts();
unsigned long last_millis = millis();
while (millis() - last_millis >= 500);
ir_selector_pressed = true;
interrupts();
}
Am I doing something silly?
Update 1
As suggested in the comments, i've adjusted the code, but it still triggers on the rising edge, and a few times rapidly at the falling edge.
ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
{
if (digitalRead(SELECTOR_BTN) == LOW)
{
noInterrupts();
static unsigned long last_millis = millis();
if (millis() - last_millis >= 500)
{
ir_selector_pressed = true;
interrupts();
}
}
}
1 Answer 1
You don't update last_millis.
Also, you don't know whether SELECTOR_BTN went from HIGH to LOW or whether another pin fired the interrupt while SELECTOR_BTN was low. Remember the previous state to solve this.
const unsigned long debounceTime = 50;
volatile bool ir_selector_pressed = false;
ISR (PCINT2_vect) { // handle pin change interrupt for D0 to D7 here
static unsigned long previousStateChangeMillis = 0;
static bool previousPinState = HIGH;
bool pinState = digitalRead(SELECTOR_BTN);
if (pinState != previousPinState) { // ignore pin changes of pins other than SELECTOR_BTN
if (pinState == LOW) { // only falling events
if ((millis() - previousStateChangeMillis) > debounceTime) { // debounce
ir_selector_pressed = true;
}
}
previousPinState = pinState;
previousStateChangeMillis = millis();
}
}
-
Thank you, this works very well. Is there a reason why you're not deactivating interrupts during the ISR body?Orbitronics– Orbitronics09/26/2017 12:31:39Commented Sep 26, 2017 at 12:31
-
1When an interrupt service routine (ISR) is called, interrupts are automatically disabled. Interrupts are automatically enabled when returning from an ISR. It is not necessary to explicitly enable nor disable interrupts inside of an ISR. The processor does these two things for you. Sourcetttapa– tttapa09/26/2017 13:44:32Commented Sep 26, 2017 at 13:44
Explore related questions
See similar questions with these tags.
last_millis
static, and replace the while loop with an if statement.