user11861: Since it is not right to use millis() in an ISR to calculate duration of the input, Is it correct to use pulseIn()?

user10794: It is quite OK to use millis() or micros() inside an ISR. In fact that is an excellent time to do it, because you are recording the time of the event shortly after it happened. Make sure the variable you are saving it to is unsigned long and volatile. Eg.
volatile unsigned long whenItHappened;
volatile bool eventHappened;

void myISR ()
  {
  whenItHappened = millis ();
  eventHappened = true;
  }

Now in your main loop you can test the eventHappened flag, so you will know if this event has happened, and whenItHappened is when.
It is not a good idea to use pulseIn() because that can wait quite a long time for a pulse. The default timeout for pulseIn is 1 second, which is far too long to wait inside an ISR.
If you want to time something (eg. how long it takes a ball to cross a sensor) use the interrupt twice, once to find the first event, and again to find the second.

Example
Example code which times how long a ball passes a sensor:
const byte LED = 12;
const byte photoTransistor = 2;

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

void ballPasses ()
{
  // if low, ball is in front of light
  if (digitalRead (photoTransistor) == LOW)
    {
    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;
  }

That code used micros() for a more accurate timing.

Reference

Interrupts


11861: <p>Since it is not right to use millis() in an ISR to calculate duration of the input, Is it correct to use pulseIn()?</p>
 10794: 

<p>It is quite OK to use <code>millis()</code> or <code>micros()</code> inside an ISR. In fact that is an excellent time to do it, because you are recording the time of the event shortly after it happened. Make sure the variable you are saving it to is <code>unsigned long</code> and <code>volatile</code>. Eg.</p>

<pre class="lang-C++ prettyprint-override"><code>volatile unsigned long whenItHappened;
volatile bool eventHappened;

void myISR ()
  {
  whenItHappened = millis ();
  eventHappened = true;
  }
</code></pre>

<p>Now in your main loop you can test the <code>eventHappened</code> flag, so you will know if this event has happened, and <code>whenItHappened</code> is when.</p>

<p>It is <strong>not</strong> a good idea to use <code>pulseIn()</code> because that can wait quite a long time for a pulse. The default timeout for <code>pulseIn</code> is 1 second, which is far too long to wait inside an ISR.</p>

<p>If you want to time something (eg. how long it takes a ball to cross a sensor) use the interrupt twice, once to find the first event, and again to find the second.</p>

<hr>

<h2>Example</h2>

<p>Example code which times how long a ball passes a sensor:</p>

<pre class="lang-C++ prettyprint-override"><code>const byte LED = 12;
const byte photoTransistor = 2;

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

void ballPasses ()
{
  // if low, ball is in front of light
  if (digitalRead (photoTransistor) == LOW)
    {
    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;
  }
</code></pre>

<p>That code used <code>micros()</code> for a more accurate timing.</p>

<hr>

<h2>Reference</h2>

<ul>
<li><a href="http://www.gammon.com.au/interrupts" rel="nofollow">Interrupts</a></li>
</ul>
