Is it possible to measure the width of a pulse which is longer than 3 minutes? The pulseIn function can only measure duration of maximum 3 minutes accurately. I've tried using interrupts but haven't come up with a correct solution yet.

I'm measuring the duration of pulse (HIGH) generated by AND gate connected to the outputs of two comparators. AND gate output voltage is around 4.9 volts.

Any logical solution or idea would be appreciated. Thanks!

2 Answers 2


The concept is actually quite simple.

You need to record the time when the signal goes high, and record the time when it goes low. The pulse width is the difference between the two times.

Yes, you can do it with interrupts, but you don't need to if you're not trying to do anything else at the same time.

A simple polling code could be something like this:

while (digitalRead(pin) == LOW); // Wait for input to go high
unsigned long startTime = millis(); // Record start time
while (digitalRead(pin) == HIGH); // Wait for input to go low
unsigned long endTime = millis(); // Record end time
unsigned long pulseDuration = endTime - startTime;

You basically sit doing nothing until the leading rising edge of your pulse. You then record the time, and again sit doing nothing - this time while looking for the trailing falling edge of the pulse. Then record the end time and subtract the two.

  • I understand the concept but can you please suggest some ways to do it? I'm not an expert in Arduino programming. I'm helping my teacher in her project. Please suggest the simplest method as no other processing has to be done when the pulse duration is being calculated. Sep 10, 2015 at 17:36
  • I am on my phone at the moment. I can post some sample code later on.
    – Majenko
    Sep 10, 2015 at 17:51
  • Thank you very much. I'll try this code and let you know if it works. Sep 11, 2015 at 0:58
  • Problem solved! My professor is satisfied with the result. You're the best! Thanks. Sep 11, 2015 at 12:08

Here is some code I used to time a ball running down a ramp:

const byte LED = 12;
const byte photoTransistor = 2;

unsigned long startTime;
volatile unsigned long elapsedTime;
volatile boolean done;

void ballPasses ()
  // if high, start timing
  if (digitalRead (photoTransistor) == HIGH)
    startTime = micros (); 
    elapsedTime = micros () - startTime;  
    done = true;

  digitalWrite (LED, !digitalRead (LED));  

void setup ()
  Serial.begin (115200);
  Serial.println ("Timer sketch started.");  
  pinMode (LED, OUTPUT);
  attachInterrupt (0, ballPasses, CHANGE);

void loop ()
  if (!done)

  Serial.print ("Time taken = ");
  Serial.print (elapsedTime);
  Serial.println (" uS");
  done = false;

Using micros() here is probably overkill, but that should be good for an interval up to 71 minutes.

  • An interesting code. Nice use of the flag 'done'. Thank you very much! Sep 11, 2015 at 1:03
  • Hi @Nick-Gammon. I'm not sure it is important to mention but without timer rollover detection this code should only be used to measure events less than 70 minutes. (Did I do the math right on the rollover frequency?)
    – linhartr22
    Sep 17, 2015 at 19:42
  • Well, I mentioned above that should be good for an interval up to 71 minutes. Yes, the rollover time is 71.58 minutes.
    – Nick Gammon
    Sep 17, 2015 at 20:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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