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!


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.

| improve this answer | |
  • 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. – Navin Sridhar Sep 10 '15 at 17:36
  • I am on my phone at the moment. I can post some sample code later on. – Majenko Sep 10 '15 at 17:51
  • Thank you very much. I'll try this code and let you know if it works. – Navin Sridhar Sep 11 '15 at 0:58
  • Problem solved! My professor is satisfied with the result. You're the best! Thanks. – Navin Sridhar Sep 11 '15 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.

| improve this answer | |
  • An interesting code. Nice use of the flag 'done'. Thank you very much! – Navin Sridhar Sep 11 '15 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 '15 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 '15 at 20:44

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.