2

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 Answers2

1

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.

Majenko
  • 105,851
  • 5
  • 82
  • 139
1

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 (); 
    }
  else
    {
    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)
    return;

  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.

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125