@@ -381,21 +381,38 @@ unsigned long pulseIn(int pin, int state)
381
381
}
382
382
*/
383
383
384
+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
385
+ * or LOW, the type of pulse to measure. Works on pulses from 10 microseconds
386
+ * to 3 minutes in length, but must be called at least N microseconds before
387
+ * the start of the pulse. */
384
388
unsigned long pulseIn (int pin , int state )
385
389
{
386
- unsigned long width = 0 ;
390
+ // cache the port and bit of the pin in order to speed up the
391
+ // pulse width measuring loop and achieve finer resolution. calling
392
+ // digitalWrite() instead yields much coarser resolution.
387
393
int r = port_to_input [digitalPinToPort (pin )];
388
394
int bit = digitalPinToBit (pin );
389
395
int mask = 1 << bit ;
396
+ unsigned long width = 0 ;
390
397
398
+ // compute the desired bit pattern for the port reading (e.g. set or
399
+ // clear the bit corresponding to the pin being read). the !!state
400
+ // ensures that the function treats any non-zero value of state as HIGH.
391
401
state = (!!state ) << bit ;
392
402
403
+ // wait for the pulse to start
393
404
while ((_SFR_IO8 (r ) & mask ) != state )
394
405
;
395
-
406
+
407
+ // wait for the pulse to stop
396
408
while ((_SFR_IO8 (r ) & mask ) == state )
397
409
width ++ ;
398
-
410
+
411
+ // convert the reading to microseconds. the slower the CPU speed, the
412
+ // proportionally fewer iterations of the loop will occur (e.g. a
413
+ // 4 MHz clock will yield a width that is one-fourth of that read with
414
+ // a 16 MHz clock). each loop was empirically determined to take
415
+ // approximately 23/20 of a microsecond with a 16 MHz clock.
399
416
return width * (16000000UL / F_CPU ) * 20 / 23 ;
400
417
}
401
418
0 commit comments