user47682: I've written a small sketch targeted at the Arduino Uno (ATmega328P) to debounce a mechanical pushbutton using the summing/integration technique:
#include <IntegratingDebounce.h>
#define PIN_BTN 4

IntegratingDebounce *btn;

ISR (TIMER2_OVF_vect) {
  ideb_poll(btn);
} // end timer2 overflow ISR

void set_debounce_timer() {
  TCNT2 = 0;                                  // Clear timer
  TCCR2A &= ~( bit( WGM21 ) | bit( WGM20 ) ); // Set waveform generation mode to normal
  TCCR2B &= ~bit( WGM22 );                    
  TIMSK2 |= bit( TOIE2 );                     // Enable interrupt on overflow
  TCCR2B |= 7;                                // Start clocking the timer
} // set_debounce_timer()

void setup() {
  Serial.begin(9600);
  pinMode(PIN_BTN, INPUT_PULLUP);

  ideb_init(&btn, PIN_BTN, 4);
  set_debounce_timer();
} // setup()

void loop() {
  while (ideb_read(btn) == HIGH);  // wait until the button pin goes low
  Serial.println("Pressed!");
  delay(100);
} // loop()

An IntegratingDebounce structure stores the data needed to perform the debounce. I keep a pointer to the structure, btn, in the global memory space.
The timer2 overflow ISR periodically polls the state of the button pin, updates the internal integrator, and sets the (also internal) debounced output accordingly. The ideb_read() function reads the debounced output out of the structure.
I'm having trouble determining where the volatile keyword should be placed in the declaration for the btn structure pointer. First I declared it as:
volatile IntegratingDebounce *btn;
I thought this would make all of the fields in the structure pointed to by btn volatile, but button presses are not detected in loop(). Declaring btn as a volatile pointer rather than a pointer to a volatile structure generates the expected output:
IntegratingDebounce *volatile btn;
This seems backwards. Why does this work?
IntegratingDebounce.h
#ifndef __INTEGRATING_DEBOUNCE_H__
#define __INTEGRATING_DEBOUNCE_H__

#include <Arduino.h>
#include <stdint.h>

extern "C" {

typedef struct IntegratingDebounce_S IntegratingDebounce;
typedef uint8_t ideb_size_t;

// Create a debounce structure and initialize.
void ideb_init(
  IntegratingDebounce **ideb,
  uint8_t pin,                  // I/O pin to debounce
  ideb_size_t clamp             // debounce clamp; the maximum value the
                                //   internal sum is able to take on
);

// Poll the state of the pin, integrate, and update the debounced output.
void ideb_poll(IntegratingDebounce *ideb);

// Read the debounced state of the pin.
uint8_t ideb_read(IntegratingDebounce *ideb);

// Reset the internal integrator to either the LOW or HIGH state.
void ideb_reset(IntegratingDebounce *ideb, uint8_t state);

} // extern C

#endif

IntegratingDebounce.c
#include "IntegratingDebounce.h"

struct IntegratingDebounce_S {
  uint8_t pin;              // pin to debounce
  uint8_t output;           // debounced output
  ideb_size_t clamp;        // debounce clamp
  ideb_size_t integrator;   // clamped running sum
};

void ideb_init(IntegratingDebounce **ideb, uint8_t pin, uint8_t clamp) {
  *ideb = (IntegratingDebounce *)malloc(sizeof(IntegratingDebounce));
  (*ideb)->pin = pin;
  (*ideb)->clamp = clamp;
  (*ideb)->output = 0;
  (*ideb)->integrator = 0;
} // ideb_init()

void ideb_poll(IntegratingDebounce *ideb) {
  // update the integrator based on the present state of the pin:
  // - if LOW, decrement the integerator; if HIGH, increment the integrator
  // - constrain the integrator to values between 0 and 'clamp'
  if (digitalRead(ideb->pin) == LOW) {
    if (ideb->integrator > 0) ideb->integrator--;
  } // if
  else {
    if (ideb->integrator < ideb->clamp) ideb->integrator++;
  } // else

  // update the output based on the value of the integrator; the output
  // will not change until the integrator reaches a limiting value
  if (ideb->integrator == 0 && ideb->output == HIGH) {
    ideb->output = LOW;
  } // if
  else if (ideb->integrator == ideb->clamp && ideb->output == LOW) {
    ideb->output = HIGH;
  } // else if
} // ideb_poll()

uint8_t ideb_read(IntegratingDebounce *ideb) {
  return ideb->output;
} // ideb_read()

void ideb_reset(IntegratingDebounce *ideb, uint8_t state) {
  if (state == LOW) {
    ideb->integrator = 0;
    ideb->output = LOW;
  } // if
  else {
    ideb->integrator = ideb->clamp;
    ideb->output = HIGH;
  } // else
} // ideb_reset()


user15180: I think, that the problem is in ideb_read, which expects "a pointer to (non-volatile) structure" and so it does not care about re-reading ideb->output if it can it optimize out somehow (say putting it in free register).
IMHO the ideb_read should have parameter declared as (volatile IntegratingDebounce *ideb) (to know, that structure pointed by ideb is volatile) or use global variable btn (which is pointer to volatile structure) instead of pointer parametr to non-volatitle structure.

And why the second works would be because it forces re-read the parameter of ideb_read and so it cannot be saved out somewhere and the function is indirectly forced to expect changed pointer, so it have to use its 'new value' and read the structure (as it is simpler, than ensure, that the ideb have the same value as it had last call and so the whole structure there (which is declared as non-volatile in header of ideb_read) could be cached)

Another wording of the above:
Declaring volatile IntegratingDebounce *btn; the main program in loop simply takes the value of btn (which is non-volatile pointer to volatile structure) and copy that (non-volatile) value to ideb parametr od ideb_read, which is non-volatile pointer to non-volatile structure. ideb_read use it that way and compiler somehow was able to cache all of that and so not read ideb->output again, as it knows, that it is part of non-volatile struct. (So it does not work)
Declaring IntegratingDebounce *volatile btn; you made the btn volatile, so it gets read each time ideb_read is called and the 'new actual value' is passed to (non-volatile) ideb parametr (which is this way given 'new value' and so cannot be cached between calls) and it results to reading (non-volatile) date from "new" place pointed by ideb. So it works (by mistake).
Right solution would be declare correctly volatile IntegratingDebounce *btn; in main program AND declare correctly uint8_t ideb_read(volatile IntegratingDebounce *ideb) so the ideb_read function is forced read value pointed by ideb every time again (which is the right thing to do)
And it should be used for all other ideb_** functions too. 
And I think, that it would be simpler to declare some typedef for this volatile structure (something like typedef struct { ... } volatile ideb_t; ) and use the new type everywhere.

user313: Getting pointer declarations right can be anything but obvious, especially where const and volatile are concerned (which are syntactically equivalent). Your problem stemmed from the confusion between "volatile pointer to struct" and "pointer to volatile struct". See the difference? In words it's fairly clear. In C, it has you - and me - running to your C manual's Table of Precedence.
I keep a copy of Dan Saks' article, "Const T vs. T Const" on hand for just exactly this case - it seems I always need to look it up.
And while you're there, check out some of his other articles as well. I learn something every time I read one.

47682: <p>I've written a small sketch targeted at the Arduino Uno (ATmega328P) to debounce a mechanical pushbutton using the summing/integration technique:</p>

<pre><code>#include &lt;IntegratingDebounce.h&gt;
#define PIN_BTN 4

IntegratingDebounce *btn;

ISR (TIMER2_OVF_vect) {
  ideb_poll(btn);
} // end timer2 overflow ISR

void set_debounce_timer() {
  TCNT2 = 0;                                  // Clear timer
  TCCR2A &amp;= ~( bit( WGM21 ) | bit( WGM20 ) ); // Set waveform generation mode to normal
  TCCR2B &amp;= ~bit( WGM22 );                    
  TIMSK2 |= bit( TOIE2 );                     // Enable interrupt on overflow
  TCCR2B |= 7;                                // Start clocking the timer
} // set_debounce_timer()

void setup() {
  Serial.begin(9600);
  pinMode(PIN_BTN, INPUT_PULLUP);

  ideb_init(&amp;btn, PIN_BTN, 4);
  set_debounce_timer();
} // setup()

void loop() {
  while (ideb_read(btn) == HIGH);  // wait until the button pin goes low
  Serial.println("Pressed!");
  delay(100);
} // loop()
</code></pre>

<p>An <code>IntegratingDebounce</code> structure stores the data needed to perform the debounce. I keep a pointer to the structure, <code>btn</code>, in the global memory space.</p>

<p>The timer2 overflow ISR periodically polls the state of the button pin, updates the internal integrator, and sets the (also internal) debounced output accordingly. The <code>ideb_read()</code> function reads the debounced output out of the structure.</p>

<p>I'm having trouble determining where the <code>volatile</code> keyword should be placed in the declaration for the <code>btn</code> structure pointer. First I declared it as:</p>

<p><code>volatile IntegratingDebounce *btn;</code></p>

<p>I thought this would make all of the fields in the structure pointed to by <code>btn</code> volatile, but button presses are not detected in loop(). Declaring <code>btn</code> as a volatile pointer rather than a pointer to a volatile structure generates the expected output:</p>

<p><code>IntegratingDebounce *volatile btn;</code></p>

<p>This seems backwards. Why does this work?</p>

<p><strong>IntegratingDebounce.h</strong></p>

<pre><code>#ifndef __INTEGRATING_DEBOUNCE_H__
#define __INTEGRATING_DEBOUNCE_H__

#include &lt;Arduino.h&gt;
#include &lt;stdint.h&gt;

extern "C" {

typedef struct IntegratingDebounce_S IntegratingDebounce;
typedef uint8_t ideb_size_t;

// Create a debounce structure and initialize.
void ideb_init(
  IntegratingDebounce **ideb,
  uint8_t pin,                  // I/O pin to debounce
  ideb_size_t clamp             // debounce clamp; the maximum value the
                                //   internal sum is able to take on
);

// Poll the state of the pin, integrate, and update the debounced output.
void ideb_poll(IntegratingDebounce *ideb);

// Read the debounced state of the pin.
uint8_t ideb_read(IntegratingDebounce *ideb);

// Reset the internal integrator to either the LOW or HIGH state.
void ideb_reset(IntegratingDebounce *ideb, uint8_t state);

} // extern C

#endif
</code></pre>

<p><strong>IntegratingDebounce.c</strong></p>

<pre><code>#include "IntegratingDebounce.h"

struct IntegratingDebounce_S {
  uint8_t pin;              // pin to debounce
  uint8_t output;           // debounced output
  ideb_size_t clamp;        // debounce clamp
  ideb_size_t integrator;   // clamped running sum
};

void ideb_init(IntegratingDebounce **ideb, uint8_t pin, uint8_t clamp) {
  *ideb = (IntegratingDebounce *)malloc(sizeof(IntegratingDebounce));
  (*ideb)-&gt;pin = pin;
  (*ideb)-&gt;clamp = clamp;
  (*ideb)-&gt;output = 0;
  (*ideb)-&gt;integrator = 0;
} // ideb_init()

void ideb_poll(IntegratingDebounce *ideb) {
  // update the integrator based on the present state of the pin:
  // - if LOW, decrement the integerator; if HIGH, increment the integrator
  // - constrain the integrator to values between 0 and 'clamp'
  if (digitalRead(ideb-&gt;pin) == LOW) {
    if (ideb-&gt;integrator &gt; 0) ideb-&gt;integrator--;
  } // if
  else {
    if (ideb-&gt;integrator &lt; ideb-&gt;clamp) ideb-&gt;integrator++;
  } // else

  // update the output based on the value of the integrator; the output
  // will not change until the integrator reaches a limiting value
  if (ideb-&gt;integrator == 0 &amp;&amp; ideb-&gt;output == HIGH) {
    ideb-&gt;output = LOW;
  } // if
  else if (ideb-&gt;integrator == ideb-&gt;clamp &amp;&amp; ideb-&gt;output == LOW) {
    ideb-&gt;output = HIGH;
  } // else if
} // ideb_poll()

uint8_t ideb_read(IntegratingDebounce *ideb) {
  return ideb-&gt;output;
} // ideb_read()

void ideb_reset(IntegratingDebounce *ideb, uint8_t state) {
  if (state == LOW) {
    ideb-&gt;integrator = 0;
    ideb-&gt;output = LOW;
  } // if
  else {
    ideb-&gt;integrator = ideb-&gt;clamp;
    ideb-&gt;output = HIGH;
  } // else
} // ideb_reset()
</code></pre>
 15180: <p>I think, that the problem is in <code>ideb_read</code>, which expects "a pointer to (non-volatile) structure" and so it does not care about re-reading <code>ideb-&gt;output</code> if it can it optimize out somehow (say putting it in free register).</p>

<p>IMHO the <code>ideb_read</code> should have parameter declared as <code>(volatile IntegratingDebounce *ideb)</code> (to know, that structure pointed by <code>ideb</code> is volatile) or use global variable <code>btn</code> (which is pointer to volatile structure) instead of pointer parametr to non-volatitle structure.</p>

<hr>

<p>And why the second works would be because it forces re-read the parameter of <code>ideb_read</code> and so it cannot be saved out somewhere and the function is indirectly forced to expect changed pointer, so it have to use its 'new value' and read the structure (as it is simpler, than ensure, that the <code>ideb</code> have the same value as it had last call and so the whole structure there (which is declared as non-volatile in header of <code>ideb_read</code>) could be cached)</p>

<hr>

<p>Another wording of the above:</p>

<p>Declaring <code>volatile IntegratingDebounce *btn;</code> the main program in <code>loop</code> simply takes the value of <code>btn</code> (which is non-volatile pointer to volatile structure) and copy that (non-volatile) value to <code>ideb</code> parametr od <code>ideb_read</code>, which is non-volatile pointer to non-volatile structure. <code>ideb_read</code> use it that way and compiler somehow was able to cache all of that and so not read <code>ideb-&gt;output</code> again, as it knows, that it is part of non-volatile struct. (So it does not work)</p>

<p>Declaring <code>IntegratingDebounce *volatile btn;</code> you made the <code>btn</code> volatile, so it gets read each time <code>ideb_read</code> is called and the 'new actual value' is passed to (non-volatile) <code>ideb</code> parametr (which is this way given 'new value' and so cannot be cached between calls) and it results to reading (non-volatile) date from "new" place pointed by <code>ideb</code>. So it works (by mistake).</p>

<p>Right solution would be declare correctly <code>volatile IntegratingDebounce *btn;</code> in main program AND declare correctly <code>uint8_t ideb_read(volatile IntegratingDebounce *ideb)</code> so the <code>ideb_read</code> function is forced read value pointed by <code>ideb</code> every time again (which is the right thing to do)</p>

<p>And it should be used for all other <code>ideb_**</code> functions too. </p>

<p>And I think, that it would be simpler to declare some typedef for this volatile structure (something like <code>typedef struct { ... } volatile ideb_t;</code> ) and use the new type everywhere.</p>
 313: <p>Getting pointer declarations right can be anything but obvious, especially where <code>const</code> and <code>volatile</code> are concerned (which are syntactically equivalent). Your problem stemmed from the confusion between "volatile pointer to struct" and "pointer to volatile struct". See the difference? In words it's fairly clear. In C, it has you - and me - running to your C manual's Table of Precedence.</p>

<p>I keep a copy of Dan Saks' article, <a href="http://www.dansaks.com/articles/1999-02%20const%20T%20vs%20T%20const.pdf" rel="nofollow noreferrer">"Const T vs. T Const"</a> on hand for just exactly this case - it seems I always need to look it up.</p>

<p>And while you're there, check out some of <a href="http://dansaks.com/articles/" rel="nofollow noreferrer">his other articles</a> as well. I learn something every time I read one.</p>
