I'd like to use Timer1 to measure the time between rising edges of two input signals. Specifically, use Tn to start the timer counter and IPCn to latch the elapsed time since the rising edge of the Tn input signal. The goal is to measure the time between the rising edges of two input signals. Is there a Timer1 library out there that alread does this? Code suggestions welcomed.

  • 1
    What is the minimal expected duration between two consecutive rising edges of your signal? – jfpoilpret Feb 21 '15 at 6:55
  • // ICNC1: Enable Input Capture Noise Canceler // ICES1: =1 for trigger on rising edge // CS10: =1 set prescaler to 1x system clock (F_CPU) TCCR1A = 0; TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<CS10); If I read this correctly (questionable), it looks like the everything is set backwards from what the text says it is supposed to be. Am I reading it wrong? Doesn't "(0<<ICNC1)" put a 0 into the ICNC1 bit? Doesn't that disable the noise canceler? This should be what you WANT for the purposes of catching every rising edge, but the explanation doesn't match the code. Also, doesn't "(0<<ICES1)" catch t – mypgp May 21 at 13:29

It is not perfect for your simpler task, but here is a link to a sketch that I have used to record pulses, using the Timer1 Input Capture.

In short setup the Interrupt

void initTimer(void) {

  // Input Capture setup
  // ICNC1: Enable Input Capture Noise Canceler
  // ICES1: =1 for trigger on rising edge
  // CS10: =1 set prescaler to 1x system clock (F_CPU)
  TCCR1A = 0;
  TCCR1B = (0<<ICNC1) | (0<<ICES1) | (1<<CS10);
  TCCR1C = 0;

  //catchFallingEdge(); // initialize to catch
  { TCCR1B &= ~(1<<ICES1); TIFR1 |= (1<<ICF1); rising = 0; }

  // Interrupt setup
  // ICIE1: Input capture
  // TOIE1: Timer1 overflow
  TIFR1 = (1<<ICF1) | (1<<TOV1);        // clear pending
  TIMSK1 = (1<<ICIE1) | (1<<TOIE1); // and enable

  // Set up the Input Capture pin, ICP1, which corresponds to Arduino D8
  pinMode(8, INPUT);
  digitalWrite(8, 0);       // leave floating to count 60 Hz etc.
  //digitalWrite(8, 1);         // or enable the pullup

Then service it

  union twobyte {
    uint32_t word;
    uint8_t  byte[2];
  } timevalue;

  timevalue.byte[0] = ICR1L;        // grab captured timer value
  timevalue.byte[1] = ICR1H;        // grab captured timer value

  // watch for the other edge to catch the half-pulse width
  //rising ? catchFallingEdge() : catchRisingEdge();
  if (rising) {
    TCCR1B &= ~(1<<ICES1);
    TIFR1 |= (1<<ICF1);
    rising = 0;
  else {
    TCCR1B |= (1<<ICES1);
    TIFR1 |= (1<<ICF1);
    rising = 1;

For more help and info, and many examples of various detailed aspects of timers, check out Nick Gammon's articles here: http://www.gammon.com.au/interrupts and here: http://www.gammon.com.au/timers

Under the first link, do a search for "The sketch below times intervals between RISING interrupts," for example, to find one code segment.

Now, important question: what is the minimum time you need to measure between events? Are we talking milliseconds, microseconds, or nanoseconds? For the former, you can use pin polling, external interrupts, or pin change interrupts, and the millis() or micros() Arduino functions to grab timestamps. For microseconds resolution, it depends. Even the micros() function only has a 4us resolution, so you'd have to custom-configure the timer if you want better than 4us resolution time-stamps, or you could use the timer2_counter library (http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precise-Arduino-micros-function.html), or your own custom timer solution, for 0.5us resolution timestamps.

For nanosecond resolution (down to 62.5ns time steps), youd prob. need to use Timer1's input capture, as the other answer shows. You can also do a search for "Timing an interval using the input capture unit" under the 2nd link above, for another code segment on that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.