Added timeout (in microseconds) parameter to pulseIn(). Defaults to 1000000 (1 second).

This commit is contained in:
David A. Mellis 2008-03-08 21:30:00 +00:00
parent f4acc7d176
commit a50a2d888f
4 changed files with 23 additions and 10 deletions

View File

@ -10,6 +10,8 @@
#ifdef __cplusplus #ifdef __cplusplus
#include "HardwareSerial.h" #include "HardwareSerial.h"
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
// WMath prototypes // WMath prototypes
long random(long); long random(long);
long random(long, long); long random(long, long);

View File

@ -87,6 +87,7 @@ extern "C"{
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
typedef uint8_t boolean; typedef uint8_t boolean;
typedef uint8_t byte; typedef uint8_t byte;
@ -118,7 +119,7 @@ void printIntegerInBase(unsigned long n, unsigned long base);
unsigned long millis(void); unsigned long millis(void);
void delay(unsigned long); void delay(unsigned long);
void delayMicroseconds(unsigned int us); void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state); unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val); void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);

View File

@ -26,10 +26,10 @@
#include "pins_arduino.h" #include "pins_arduino.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 10 microseconds * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least N microseconds before * to 3 minutes in length, but must be called at least a few dozen microseconds
* the start of the pulse. */ * before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state) unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{ {
// cache the port and bit of the pin in order to speed up the // cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling // pulse width measuring loop and achieve finer resolution. calling
@ -39,17 +39,23 @@ unsigned long pulseIn(uint8_t pin, uint8_t state)
uint8_t stateMask = (state ? bit : 0); uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area unsigned long width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for the pulse to start // wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask) while ((*portInputRegister(port) & bit) != stateMask)
; if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop // wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) while ((*portInputRegister(port) & bit) == stateMask)
width++; width++;
// convert the reading to microseconds. The loop has been determined // convert the reading to microseconds. The loop has been determined
// to be 10 clock cycles long and have about 12 clocks between the edge // to be 10 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by // and the start of the loop. There will be some error introduced by
// the interrupt handlers. // the interrupt handlers.
return clockCyclesToMicroseconds(width * 10 + 12); return clockCyclesToMicroseconds(width * 10 + 16);
} }

View File

@ -8,9 +8,9 @@ Improve preprocessing of sketches:
- [done] Insert prototypes at a better spot in the code (after pre-processor directives). - [done] Insert prototypes at a better spot in the code (after pre-processor directives).
- [done] Don't move #include statements. - [done] Don't move #include statements.
- [done] Better determine which functions need prototypes - [done] Better determine which functions need prototypes
Update version of the FTDI drivers. Update version of the FTDI drivers (Windows).
Incorporate ladyada's new SoftwareSerial library.
Add timeout parameter to pulseIn(). Add timeout parameter to pulseIn().
[done] Update version of the FTDI drivers (Mac).
[done] Allow disabling of serial flushing before upload (for the Arduino BT). [done] Allow disabling of serial flushing before upload (for the Arduino BT).
[done] Modify parallel port programmer burning (add -F, lower or remove delay). [done] Modify parallel port programmer burning (add -F, lower or remove delay).
[done] Allow uploading using a hardware programmer. [done] Allow uploading using a hardware programmer.
@ -22,8 +22,11 @@ Add timeout parameter to pulseIn().
AVR AVR
Add parameter to shiftOut() for specifying a number of bits.
Add parameter to Serial.print[ln](x, BYTE) for specifying number of bits.
Add support for ATmega1280 (e.g. timers, external interrupts, multiple serial ports). Add support for ATmega1280 (e.g. timers, external interrupts, multiple serial ports).
Add weak attribute to signal handlers (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203798214) Add weak attribute to signal handlers (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203798214)
Incorporate ladyada's new SoftwareSerial library.
Good way to receive multiple values / complex messages over the serial port. Good way to receive multiple values / complex messages over the serial port.
Floating point support in the map() function. Floating point support in the map() function.
Consider moving millis() to timer 1, and configuring it so the interrupt is generated once a millisecond. Consider moving millis() to timer 1, and configuring it so the interrupt is generated once a millisecond.
@ -64,6 +67,7 @@ Move to ant for build process (limitations: can't build bootloader, can't build
DOCUMENTATION DOCUMENTATION
Get good top-down, well-lit, plain-white-background photos of the Arduino boards.
Electronics reference a la Wiring. Electronics reference a la Wiring.
Documentation for moving from Arduino to custom PCBs. Documentation for moving from Arduino to custom PCBs.
Examples should demonstrate use of functions. Examples should demonstrate use of functions.