@@ -79,3 +79,45 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
79
79
width = countPulseASM (* portInputRegister (port ), bit , maxloops , stateMask );
80
80
return clockCyclesToMicroseconds (width * 11 + 16 );
81
81
}
82
+
83
+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
84
+ * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
85
+ * to 3 minutes in length, but must be called at least a few dozen microseconds
86
+ * before the start of the pulse.
87
+ *
88
+ * ATTENTION:
89
+ * this function relies on micros() so cannot be used in noInterrupt() context
90
+ */
91
+ unsigned long pulseInLong (uint8_t pin , uint8_t state , unsigned long timeout )
92
+ {
93
+ // cache the port and bit of the pin in order to speed up the
94
+ // pulse width measuring loop and achieve finer resolution. calling
95
+ // digitalRead() instead yields much coarser resolution.
96
+ uint8_t bit = digitalPinToBitMask (pin );
97
+ uint8_t port = digitalPinToPort (pin );
98
+ uint8_t stateMask = (state ? bit : 0 );
99
+ unsigned long width = 0 ; // keep initialization out of time critical area
100
+
101
+ // convert the timeout from microseconds to a number of times through
102
+ // the initial loop; it takes 16 clock cycles per iteration.
103
+ unsigned long numloops = 0 ;
104
+ unsigned long maxloops = microsecondsToClockCycles (timeout );
105
+
106
+ // wait for any previous pulse to end
107
+ while ((* portInputRegister (port ) & bit ) == stateMask )
108
+ if (numloops ++ == maxloops )
109
+ return 0 ;
110
+
111
+ // wait for the pulse to start
112
+ while ((* portInputRegister (port ) & bit ) != stateMask )
113
+ if (numloops ++ == maxloops )
114
+ return 0 ;
115
+
116
+ unsigned long start = micros ();
117
+ // wait for the pulse to stop
118
+ while ((* portInputRegister (port ) & bit ) == stateMask ) {
119
+ if (numloops ++ == maxloops )
120
+ return 0 ;
121
+ }
122
+ return micros () - start ;
123
+ }
0 commit comments