How to use debounce with an external interrupt

Hi, I am doing tests with an ESP8266-12F and I want to implement an external interrupt through the GPIO14, when pressing the button you can see that there is noise and I have tried to add a debounce with a delay in the interrupt routine, it has improved but I still have some jumps Can someone tell me what is the best method to implement a debounce with an external interrupt?

Here is my code:

int interruptPin(14);
int numberOfInterrupts = 0;

void setup() {
  Serial.println("Interrupt Test");
  pinMode(interruptPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), IntCallback, FALLING);

void loop() {

void IntCallback() {
  if (!digitalRead(interruptPin)) {
    if (!digitalRead(interruptPin)) {
      numberOfInterrupts = numberOfInterrupts + 1;
      Serial.print("Interrupcion Nro = ");
  attachInterrupt(digitalPinToInterrupt(interruptPin), IntCallback, FALLING);

Rule #1 of interrupts.

Don’t do things that require interrupts, or that are ‘slow’ inside an ISR.
(no serial prints is a good start!)

Maintain a static time stamp variable in the ISR.

volatile variable flag
static variable timeStamp
if (now - timeStamp >= debounce interval)
  if (switch detected)
    flag = true
    timeStamp = now

in the main program, read 'flag', if it's set, you've read a switch event, clear it.

I would consider not using an interrupt. Is the button press so time sensitive it needs an interrupt?

If you plan to print the Interrupt count every button press then the timing cannot be that critical.

So, is this a kind of academic exercise, or do you really need interrupts?

Now, this is the first question we should ask an Op.


I'm using print just to check that the interrupt is executed

Yes I need an interruption

Ok, can not knowing the final goal for using an interrupt I would suggest.

In the interrupt:

  1. disable interrupts
  2. capture millis()
  3. Maybe set a variable to "TRUE" signifying the interrupt was received.

In the main program you can use the millis() to wait a debounce time after which you can enable interrupts
and you can increment and print counts.

Debounce the button with a capacitor. Then use it like normal, that is to execute only a couple instructions max.

But the question remains, how critical is your timing in milliseconds?

Interrupts are automatically disabled by the CPU when an interrupt vector is called.

My thought is to disable interrupt even after leaving the interrupt routine. Then disabling enabling it after some millis(). Kind of a odd debounce function.

UPDATED changed disabling to enabling.

Or enabling it. :expressionless:


That too.... :slight_smile:

But why?