Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 41b9e05

Browse files
committed
pulseIn: add alternative implementation based on micros()
1 parent d93b18f commit 41b9e05

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

‎hardware/arduino/sam/cores/arduino/wiring_pulse.cpp‎

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
2323
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
2424
* to 3 minutes in length, but must be called at least a few dozen microseconds
25-
* before the start of the pulse. */
25+
* before the start of the pulse.
26+
*
27+
* ATTENTION:
28+
* This function performs better with short pulses in noInterrupt() context
29+
*/
2630
uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
2731
{
2832
// cache the port and bit of the pin in order to speed up the
@@ -47,3 +51,43 @@ uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
4751
else
4852
return 0;
4953
}
54+
55+
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
56+
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
57+
* to 3 minutes in length, but must be called at least a few dozen microseconds
58+
* before the start of the pulse.
59+
*
60+
* ATTENTION:
61+
* this function relies on micros() so cannot be used in noInterrupt() context
62+
*/
63+
uint32_t pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
64+
{
65+
// cache the port and bit of the pin in order to speed up the
66+
// pulse width measuring loop and achieve finer resolution. calling
67+
// digitalRead() instead yields much coarser resolution.
68+
PinDescription p = g_APinDescription[pin];
69+
uint32_t bit = p.ulPin;
70+
uint32_t stateMask = state ? bit : 0;
71+
72+
// convert the timeout from microseconds to a number of times through
73+
// the initial loop; it takes 18 clock cycles per iteration.
74+
unsigned long maxloops = microsecondsToClockCycles(timeout) / 10;
75+
76+
// wait for any previous pulse to end
77+
while ((p.pPort->PIO_PDSR & bit) == stateMask)
78+
if (--maxloops == 0)
79+
return 0;
80+
81+
// wait for the pulse to start
82+
while ((p.pPort->PIO_PDSR & bit) != stateMask)
83+
if (--maxloops == 0)
84+
return 0;
85+
86+
unsigned long start = micros();
87+
// wait for the pulse to stop
88+
while ((p.pPort->PIO_PDSR & bit) == stateMask) {
89+
if (--maxloops == 0)
90+
return 0;
91+
}
92+
return micros() - start;
93+
}

‎hardware/arduino/sam/cores/arduino/wiring_pulse.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_
3131
* before the start of the pulse.
3232
*/
3333
extern uint32_t pulseIn( uint32_t ulPin, uint32_t ulState, uint32_t ulTimeout = 1000000L ) ;
34-
34+
externuint32_tpulseInLong( uint8_tpin, uint8_tstate, unsigned long timeout=1000000L ) ;
3535

3636
#ifdef __cplusplus
3737
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /