user51302: I tried to follow the answer here:
https://arduino.stackexchange.com/a/18545/51302
Unfortunately I can only get the interrupt to go once (on serial monitor is the time of that first interrupt), then nothing.
I know this has already been answered but I don't understand the mistake and would appreciate help.
What I'm trying to do:
get a button to set an interrupt to trigger foo and thus write the steps on the monitor.
I've left remarks to try and explain what I try to do, so it would be easier to understand what I left out or used incorrectly.
Thanks.

#define IRF520 A2
#define BUTTON 3
static unsigned long last_press = 0;
static bool button_state = HIGH;             //pull up resistor
volatile bool interrupt_flag = 0;            //when the interrupt fires, button press or noise
bool is_pressed = false;                     //after checking that the button was really pressed
bool was_pressed = false;                    //last state of the button
unsigned long button_pause_duration = 20;        //pause required to accept press in ms
unsigned long interrupt_time=0;

void button_interrupt() {
  interrupt_flag = true;                      //can be a false alarm
  Serial.print("interrupt time: ");         //this is the onlt step that works
  Serial.print(millis());
  Serial.print("\n");
}

void setup() {
  Serial.begin(9600);
  pinMode(IRF520, OUTPUT); //A2 controls IRF520
  pinMode(BUTTON, INPUT_PULLUP);  //pin D2 and D3 are sutible for interrupts
  attachInterrupt(digitalPinToInterrupt(BUTTON), button_interrupt, FALLING);
}

void debounce_button() {
  if (digitalRead(BUTTON) != button_state) {
    button_state = digitalRead(BUTTON);         //if button changed state remember the new state
    interrupt_time=millis();
  }
  if (button_state == LOW) {
    last_press = millis();
    Serial.print("last_press was updated to: ");
    Serial.print(last_press);
    Serial.print("\n");
  } else {
    last_press = 0;
    interrupt_flag = false;
  }
  if ( last_press && (millis() - last_press) > button_pause_duration) {
    last_press = 0;     //set to 0 for the next check
    is_pressed = true;   //button was really pressed
    Serial.print("last_press was set to 0 and is_pressed to true - BUTTON WAS PRESSED at: ");
    Serial.print(millis());
    Serial.print("\n");
  }
}

unsigned int foo(bool is_pressed) {
  if (is_pressed) {
    Serial.print("foo is active, MOSFET does its thing");
    Serial.print("\n");
    }
  }
}

void loop() {
 if(interrupt_flag){
    Serial.print("the button is now being pressed: ");
    Serial.print(millis());
    Serial.print("\n");
 }
 debounce_button();
 foo(is_pressed);
}


user57952: So, I grabbed a Mega and several pushbutton switches (one of which turned out to be a push-on, push-off, much to my bemusement), and ginned up a small Arduino program to illustrate an interrupt-driven button debounce technique.  Please feel free to point out any and all errors ;-)
Here is a small program to debounce any momentary contact switch.  The Mega interrupt line (pin 2, interrupt 0) triggers on any low-to-high or high-to-low transition.  the interrupt service routine (ISR) simply sets a flag to TRUE and exits.  If multiple interrupts occur before the loop() function can service the flag, the second and subsequent ISR calls do nothing (well, they set the flag, but since it was already set...).  The loop() code looks for a set flag, and if it finds one, generates a 50uSec pulse on a selected pin, delays 100mSec, resets the flag, and exits.  As long as the switch's contact bounce activity ceases before the 100mSec delay expires, one and only one pulse per transition will be generated.  YMMV.
/*
Small program to demonstrate switch debounce technique using an interrupt
The ISR is called for low-to-high and high-to-low transitions, and may get
called multiple times per button press.  However, the code in loop() ensures
that each transition produces one and only one pulse per transition, assuming
the typical 10-20 mSec max bounce duration.

Note that if the line 'delayMicroseconds(50); //used to show multiple bounces'
is used instead of the line 'delay(100);//ignore bounces for 100mSec', then 
multiple contact bounces will each generate their own 50uSec pulse.  This is 
useful for O'scope diagnosis if you happen to have one.
*/

#include <elapsedMillis.h>
#include <PrintEx.h> //allows printf-style printout syntax

StreamEx mySerial = Serial; //added for printf-style printing

//pin assignments
const int LED_PIN = 13;
const int BUTTON_PIN = 2;
const int BUTTON_STATE_PIN = 3;

//variables
bool buttonState = 0;
bool blinkState = 0;

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool Interrupt = false;     // indicates whether MPU interrupt pin has gone high
void BtnInterrupt() 
{
    Interrupt = true;
}



// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
    // configure pins
    pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(BUTTON_STATE_PIN, OUTPUT); //scope monitor pin
    digitalWrite(BUTTON_STATE_PIN, LOW);

    buttonState = digitalRead(BUTTON_PIN);
    mySerial.printf("Initial button state is %s\n", buttonState == LOW ? "LOW" : "HIGH");
    attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), BtnInterrupt, CHANGE);
}



// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() 
{
    if (Interrupt)
    {
        digitalWrite(BUTTON_STATE_PIN, HIGH);
        delayMicroseconds(50);
        digitalWrite(BUTTON_STATE_PIN, LOW);
        //delayMicroseconds(50); //used to show multiple bounces
        delay(100);//ignore bounces for 100mSec
        Interrupt = false;
    }
}

Here are two O'scope screen grabs. One shows the pulse train generated by a single button transition with a 50uSec delay, and the other shows the same switch with the 100mSec delay.  In both photos, the horizontal time scale is 500uSec/cm
 


51302: <p>I tried to follow the answer here:
<a href="https://arduino.stackexchange.com/a/18545/51302">https://arduino.stackexchange.com/a/18545/51302</a></p>

<p>Unfortunately I can only get the interrupt to go once (on serial monitor is the time of that first interrupt), then nothing.
I know this has already been answered but I don't understand the mistake and would appreciate help.</p>

<p>What I'm trying to do:
get a button to set an interrupt to trigger foo and thus write the steps on the monitor.</p>

<p>I've left remarks to try and explain what I try to do, so it would be easier to understand what I left out or used incorrectly.
Thanks.
</p>

<pre class="lang-cpp prettyprint-override"><code>#define IRF520 A2
#define BUTTON 3
static unsigned long last_press = 0;
static bool button_state = HIGH;             //pull up resistor
volatile bool interrupt_flag = 0;            //when the interrupt fires, button press or noise
bool is_pressed = false;                     //after checking that the button was really pressed
bool was_pressed = false;                    //last state of the button
unsigned long button_pause_duration = 20;        //pause required to accept press in ms
unsigned long interrupt_time=0;

void button_interrupt() {
  interrupt_flag = true;                      //can be a false alarm
  Serial.print("interrupt time: ");         //this is the onlt step that works
  Serial.print(millis());
  Serial.print("\n");
}

void setup() {
  Serial.begin(9600);
  pinMode(IRF520, OUTPUT); //A2 controls IRF520
  pinMode(BUTTON, INPUT_PULLUP);  //pin D2 and D3 are sutible for interrupts
  attachInterrupt(digitalPinToInterrupt(BUTTON), button_interrupt, FALLING);
}

void debounce_button() {
  if (digitalRead(BUTTON) != button_state) {
    button_state = digitalRead(BUTTON);         //if button changed state remember the new state
    interrupt_time=millis();
  }
  if (button_state == LOW) {
    last_press = millis();
    Serial.print("last_press was updated to: ");
    Serial.print(last_press);
    Serial.print("\n");
  } else {
    last_press = 0;
    interrupt_flag = false;
  }
  if ( last_press &amp;&amp; (millis() - last_press) &gt; button_pause_duration) {
    last_press = 0;     //set to 0 for the next check
    is_pressed = true;   //button was really pressed
    Serial.print("last_press was set to 0 and is_pressed to true - BUTTON WAS PRESSED at: ");
    Serial.print(millis());
    Serial.print("\n");
  }
}

unsigned int foo(bool is_pressed) {
  if (is_pressed) {
    Serial.print("foo is active, MOSFET does its thing");
    Serial.print("\n");
    }
  }
}

void loop() {
 if(interrupt_flag){
    Serial.print("the button is now being pressed: ");
    Serial.print(millis());
    Serial.print("\n");
 }
 debounce_button();
 foo(is_pressed);
}
</code></pre>
 57952: <p>So, I grabbed a Mega and several pushbutton switches (one of which turned out to be a push-on, push-off, much to my bemusement), and ginned up a small Arduino program to illustrate an interrupt-driven button debounce technique.  Please feel free to point out any and all errors ;-)</p>

<p>Here is a small program to debounce any momentary contact switch.  The Mega interrupt line (pin 2, interrupt 0) triggers on any low-to-high or high-to-low transition.  the interrupt service routine (ISR) simply sets a flag to TRUE and exits.  If multiple interrupts occur before the loop() function can service the flag, the second and subsequent ISR calls do nothing (well, they set the flag, but since it was already set...).  The loop() code looks for a set flag, and if it finds one, generates a 50uSec pulse on a selected pin, delays 100mSec, resets the flag, and exits.  As long as the switch's contact bounce activity ceases before the 100mSec delay expires, one and only one pulse per transition will be generated.  YMMV.</p>

<pre><code>/*
Small program to demonstrate switch debounce technique using an interrupt
The ISR is called for low-to-high and high-to-low transitions, and may get
called multiple times per button press.  However, the code in loop() ensures
that each transition produces one and only one pulse per transition, assuming
the typical 10-20 mSec max bounce duration.

Note that if the line 'delayMicroseconds(50); //used to show multiple bounces'
is used instead of the line 'delay(100);//ignore bounces for 100mSec', then 
multiple contact bounces will each generate their own 50uSec pulse.  This is 
useful for O'scope diagnosis if you happen to have one.
*/

#include &lt;elapsedMillis.h&gt;
#include &lt;PrintEx.h&gt; //allows printf-style printout syntax

StreamEx mySerial = Serial; //added for printf-style printing

//pin assignments
const int LED_PIN = 13;
const int BUTTON_PIN = 2;
const int BUTTON_STATE_PIN = 3;

//variables
bool buttonState = 0;
bool blinkState = 0;

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool Interrupt = false;     // indicates whether MPU interrupt pin has gone high
void BtnInterrupt() 
{
    Interrupt = true;
}



// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
    // configure pins
    pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(BUTTON_STATE_PIN, OUTPUT); //scope monitor pin
    digitalWrite(BUTTON_STATE_PIN, LOW);

    buttonState = digitalRead(BUTTON_PIN);
    mySerial.printf("Initial button state is %s\n", buttonState == LOW ? "LOW" : "HIGH");
    attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), BtnInterrupt, CHANGE);
}



// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() 
{
    if (Interrupt)
    {
        digitalWrite(BUTTON_STATE_PIN, HIGH);
        delayMicroseconds(50);
        digitalWrite(BUTTON_STATE_PIN, LOW);
        //delayMicroseconds(50); //used to show multiple bounces
        delay(100);//ignore bounces for 100mSec
        Interrupt = false;
    }
}
</code></pre>

<p>Here are two O'scope screen grabs. One shows the pulse train generated by a single button transition with a 50uSec delay, and the other shows the same switch with the 100mSec delay.  In both photos, the horizontal time scale is 500uSec/cm</p>

<p><a href="https://i.stack.imgur.com/5Gvt9.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5Gvt9.jpg" alt="enter image description here"></a> </p>

<p><a href="https://i.stack.imgur.com/E3WXp.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/E3WXp.jpg" alt="enter image description here"></a></p>
