user34530: I am trying to understand in details the (great tutorial and) code of Nick Gammon ''Improved sketch using Timer 1'', available here: http://www.gammon.com.au/forum/?id=12075 . I post the whole code at the end of this in the case the web page would go down.
I find the code quite clear: Nick wants to estimate the value of a capacitor by measuring its characteristic discharge time. For this he uses one of the Arduino timers, together with an interrupt raised by the analog comparator. As the Arduino timer he uses is only 16 bits and he uses a pre-factor of 1 at 16MHz, he expects overflow of the timer to occur so he keeps track of the number of overflows that happened:
ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER1_OVF_vect

However, what I do not understand is why he tries to find a 'missed overflow' in the ISR raised by the analog comparator (this is in the ISR (ANALOG_COMP_vect) function body):
// if just missed an overflow
    if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
      overflowCopy++;

So my questions are:

How could a missed overflow happen? 'Naively' I would guess that, as soon as the analog comparator ISR is called, the timer stops incrementing so that it should not overflow after the comparator ISR fires, am I wrong?
If there is a timer overflow happening, I understand why one wants to check TIFR1 at TOV1 (this is the overflow flag, set automatically at timer overflow, which should be cleared as a side-effect of execution of ISR(TIMER1_0VF_vect) according to datasheet), why add also the && timer1CounterValue < 256 in the if condition? I understand that 256 is a 'small' value, any reason for this exact numerical value?

Copy of the whole code:
/*
Capacitance meter

Author: Nick Gammon
Date:   27 June 2013

Pulse pin (D2): Connect to capacitor via 10K resistor.

Reference voltage of 0.632 of output pin (pulsePin) connected to D7.
In my case I used 3.06V because I measured 4.84 on the 5V pin.

Measure pin (D6) connected to first leg of capacitor, other leg connected to Gnd.

Like this:

Capacitor to test:

D2  ----> 10K ----> D6 ----> capacitor_under_test ----> Gnd

Reference voltage:

+5V ----> 1.8K ---> D7 ---> 3.1K ----> Gnd

*/

const byte pulsePin = 2;
const float resistance = 10000.0;

volatile boolean triggered;
volatile boolean active;

volatile unsigned long timerCounts;
volatile unsigned long overflowCount;

ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER1_OVF_vect

ISR (ANALOG_COMP_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  if (active)
    {
    // if just missed an overflow
    if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
      overflowCopy++;
    // calculate total count
    timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
    triggered = true;
    digitalWrite (pulsePin, LOW);  // start discharging capacitor
    }
  }  // end of ANALOG_COMP_vect

void setup ()
  {
  pinMode (pulsePin, OUTPUT);
  digitalWrite (pulsePin, LOW);

  Serial.begin (115200);
  Serial.println ("Started.");
  ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
  ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
        | bit (ACIE)    // Analog Comparator Interrupt Enable
        | bit (ACIS0) | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on rising edge)
   }  // end of setup

void startTiming ()
  {
  active = true;
  triggered = false;

  // prepare timer
  overflowCount = 0;            // no overflows yet
  // reset Timer 1
  TCCR1A = 0;             
  TCCR1B = 0;   
  TCNT1 = 0;      // Counter to zero
  TIFR1 = bit (TOV1);  // clear overflow bit
  // Timer 1 - counts clock pulses
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // get on with it
  digitalWrite (pulsePin, HIGH);  // start charging capacitor
  // start Timer 1, no prescaler
  TCCR1B =  bit (CS10);

  } // end of startTiming

void finishTiming ()
  {
  active = false;
  Serial.print ("Capacitance = ");
  float capacitance = (float) timerCounts * 1000.0 / 16.0 / resistance;
  Serial.print (capacitance);
  Serial.println (" nF");
  triggered = false;
  delay (3000);
  }  // end of finishTiming

void loop ()
  {
  // start another test?
  if (!active)
    startTiming ();

  // if the ISR noted the time interval is up, display results
  if (active && triggered)
    finishTiming ();

  }  // end of loop


user7508: 
'Naively' I would guess that, as soon as the analog comparator ISR is
   called, the timer stops incrementing

It doesn't. The timer stops only when you ask it to stop.
Now, consider this scenario:

overflowCount = 0, TCNT1 = 0xfffc
the ANALOG_COMP interrupt fires, which automatically disables
servicing nested interrupts
while ISR(ANALOG_COMP_vect) is executing its prologue (saving the
execution context), Timer 1 overflows, which sets the TOV1 flag, but
the corresponding interrupt is for now pending
when timer1CounterValue = TCNT1; gets executed, TCNT1 is now
0x0008.

At this point, we have overflowCount = 0 and timer1CounterValue =
0x0008. If we have no provision for detecting the overflow, we will
grossly underestimate the time. This can be fixed by accounting for the
missed overflow as
// if just missed an overflow
if (TIFR1 & bit(TOV1))
    overflowCopy++;

The is still an issue however. Think of what would happen if the timer
overflows after executing timer1CounterValue = TCNT1; but before
reading the TOV1 flag. Then we would unduly increment overflowCopy.
This is why the code tests for
(TIFR1 & bit(TOV1)) && timer1CounterValue < 256. There is no reason
for choosing this particular small value, other than the test being
easier to perform in assembly. The compiler is probably smart enough to
notice it doesn't need to do a subtraction for this particular value.

34530: <p>I am trying to understand in details the (great tutorial and) code of Nick Gammon <strong>''Improved sketch using Timer 1''</strong>, available here: <a href="http://www.gammon.com.au/forum/?id=12075" rel="nofollow noreferrer">http://www.gammon.com.au/forum/?id=12075</a> . I post the whole code at the end of this in the case the web page would go down.</p>

<p>I find the code quite clear: Nick wants to estimate the value of a capacitor by measuring its characteristic discharge time. For this he uses one of the Arduino timers, together with an interrupt raised by the analog comparator. As the Arduino timer he uses is only 16 bits and he uses a pre-factor of 1 at 16MHz, he expects overflow of the timer to occur so he keeps track of the number of overflows that happened:</p>

<pre><code>ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER1_OVF_vect
</code></pre>

<p>However, what I do not understand is why he tries to find a 'missed overflow' in the ISR raised by the analog comparator (this is in the <code>ISR (ANALOG_COMP_vect)</code> function body):</p>

<pre><code>// if just missed an overflow
    if ((TIFR1 &amp; bit (TOV1)) &amp;&amp; timer1CounterValue &lt; 256)
      overflowCopy++;
</code></pre>

<p>So my questions are:</p>

<ul>
<li><p>How could a missed overflow happen? 'Naively' I would guess that, as soon as the analog comparator ISR is called, the timer stops incrementing so that it should not overflow after the comparator ISR fires, am I wrong?</p></li>
<li><p>If there is a timer overflow happening, I understand why one wants to check TIFR1 at TOV1 (this is the overflow flag, set automatically at timer overflow, which should be cleared as a side-effect of execution of <code>ISR(TIMER1_0VF_vect)</code> according to datasheet), why add also the <code>&amp;&amp; timer1CounterValue &lt; 256</code> in the if condition? I understand that <code>256</code> is a 'small' value, any reason for this exact numerical value?</p></li>
</ul>

<h1>Copy of the whole code:</h1>

<pre><code>/*
Capacitance meter

Author: Nick Gammon
Date:   27 June 2013

Pulse pin (D2): Connect to capacitor via 10K resistor.

Reference voltage of 0.632 of output pin (pulsePin) connected to D7.
In my case I used 3.06V because I measured 4.84 on the 5V pin.

Measure pin (D6) connected to first leg of capacitor, other leg connected to Gnd.

Like this:

Capacitor to test:

D2  ----&gt; 10K ----&gt; D6 ----&gt; capacitor_under_test ----&gt; Gnd

Reference voltage:

+5V ----&gt; 1.8K ---&gt; D7 ---&gt; 3.1K ----&gt; Gnd

*/

const byte pulsePin = 2;
const float resistance = 10000.0;

volatile boolean triggered;
volatile boolean active;

volatile unsigned long timerCounts;
volatile unsigned long overflowCount;

ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows  
}  // end of TIMER1_OVF_vect

ISR (ANALOG_COMP_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  if (active)
    {
    // if just missed an overflow
    if ((TIFR1 &amp; bit (TOV1)) &amp;&amp; timer1CounterValue &lt; 256)
      overflowCopy++;
    // calculate total count
    timerCounts = (overflowCopy &lt;&lt; 16) + timer1CounterValue;  // each overflow is 65536 more
    triggered = true;
    digitalWrite (pulsePin, LOW);  // start discharging capacitor
    }
  }  // end of ANALOG_COMP_vect

void setup ()
  {
  pinMode (pulsePin, OUTPUT);
  digitalWrite (pulsePin, LOW);

  Serial.begin (115200);
  Serial.println ("Started.");
  ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
  ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
        | bit (ACIE)    // Analog Comparator Interrupt Enable
        | bit (ACIS0) | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on rising edge)
   }  // end of setup

void startTiming ()
  {
  active = true;
  triggered = false;

  // prepare timer
  overflowCount = 0;            // no overflows yet
  // reset Timer 1
  TCCR1A = 0;             
  TCCR1B = 0;   
  TCNT1 = 0;      // Counter to zero
  TIFR1 = bit (TOV1);  // clear overflow bit
  // Timer 1 - counts clock pulses
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // get on with it
  digitalWrite (pulsePin, HIGH);  // start charging capacitor
  // start Timer 1, no prescaler
  TCCR1B =  bit (CS10);

  } // end of startTiming

void finishTiming ()
  {
  active = false;
  Serial.print ("Capacitance = ");
  float capacitance = (float) timerCounts * 1000.0 / 16.0 / resistance;
  Serial.print (capacitance);
  Serial.println (" nF");
  triggered = false;
  delay (3000);
  }  // end of finishTiming

void loop ()
  {
  // start another test?
  if (!active)
    startTiming ();

  // if the ISR noted the time interval is up, display results
  if (active &amp;&amp; triggered)
    finishTiming ();

  }  // end of loop
</code></pre>
 7508: <blockquote>
  <p>'Naively' I would guess that, as soon as the analog comparator ISR is
   called, the timer stops incrementing</p>
</blockquote>

<p>It doesn't. The timer stops only when you ask it to stop.</p>

<p>Now, consider this scenario:</p>

<ul>
<li><code>overflowCount</code> = 0, <code>TCNT1</code> = 0xfffc</li>
<li>the <code>ANALOG_COMP</code> interrupt fires, which automatically disables
servicing nested interrupts</li>
<li>while <code>ISR(ANALOG_COMP_vect)</code> is executing its prologue (saving the
execution context), Timer 1 overflows, which sets the <code>TOV1</code> flag, but
the corresponding interrupt is for now pending</li>
<li>when <code>timer1CounterValue = TCNT1;</code> gets executed, <code>TCNT1</code> is now
0x0008.</li>
</ul>

<p>At this point, we have <code>overflowCount</code> = 0 and <code>timer1CounterValue</code> =
0x0008. If we have no provision for detecting the overflow, we will
grossly underestimate the time. This can be fixed by accounting for the
missed overflow as</p>

<pre class="lang-c++ prettyprint-override"><code>// if just missed an overflow
if (TIFR1 &amp; bit(TOV1))
    overflowCopy++;
</code></pre>

<p>The is still an issue however. Think of what would happen if the timer
overflows after executing <code>timer1CounterValue = TCNT1;</code> but before
reading the <code>TOV1</code> flag. Then we would unduly increment <code>overflowCopy</code>.
This is why the code tests for
<code>(TIFR1 &amp; bit(TOV1)) &amp;&amp; timer1CounterValue &lt; 256</code>. There is no reason
for choosing this particular small value, other than the test being
easier to perform in assembly. The compiler is probably smart enough to
notice it doesn't need to do a subtraction for this particular value.</p>
