Beispiel #1
0
unsigned long Ping::pulseIn(uint8_t pin, uint8_t state, unsigned long timeout, unsigned long timeoutstop)
{
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0;

	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
	unsigned long maxloopsstop = microsecondsToClockCycles(timeoutstop) / 16 ;

	// wait for any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask)
                if (width++ == maxloopsstop)
                        return 5000 ;

	return clockCyclesToMicroseconds(width * 20 + 16);
}
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse.
 *
 * ATTENTION:
 * this function relies on micros() so cannot be used in noInterrupt() context
 */
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);

	// 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);

	// wait for any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;

	unsigned long start = micros();
	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask) {
		if (numloops++ == maxloops)
			return 0;
	}
	return micros() - start;
}
Beispiel #3
0
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
extern uint32_t
pulseIn(uint32_t pin, bool state, uint32_t timeout)
{
	uint32_t numloops = 0;
	uint32_t maxloops = microsecondsToClockCycles(timeout) / 16;
	uint32_t start, end;
	
	// wait for any previous pulse to end
	while (digitalRead(pin) == state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while (digitalRead(pin) != state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	start = micros();
	while (digitalRead(pin) == state)
		if (numloops++ == maxloops)
			return 0;
	end  = micros();

	return (end - start);
}
Beispiel #4
0
DHT::DHT(void) {
    _maxCycles = microsecondsToClockCycles(DHT_MAX_CYCLES);
    _lastTemperature = _lastHumidity = 0;
    ADD_BIT(_status, STATUS_TEMP_GOOD | STATUS_HUMI_GOOD);

    DEBUG_PRINTLN("DHT loaded.");
}
Beispiel #5
0
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
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
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	volatile uint8_t *reg = portInputRegister(digitalPinToPort(pin));
	uint8_t stateMask = (state ? bit : 0);
	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 any previous pulse to end
	while ((*reg & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ((*reg & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ((*reg & bit) == stateMask)
		width++;

	// convert the reading to microseconds. The loop has been determined
	// 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
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 10 + 16); 
}
unsigned int pulseIn(int pin, int state, unsigned int timeout)
{
    const LPC_GPIO_TypeDef* port = gpioPorts[digitalPinToPort(pin)];
    const unsigned int bitMask = digitalPinToBitMask(pin);
    const unsigned int stateMask = state ? bitMask : 0;

    unsigned long width = 0, numloops = 0;
    const unsigned int maxloops = microsecondsToClockCycles(timeout);

    // Wait for any previous pulse to end
    while (port->MASKED_ACCESS[bitMask] == stateMask)
        if (numloops++ == maxloops) return 0;

    // Wait for the pulse to start
    while (port->MASKED_ACCESS[bitMask] != stateMask)
        if (numloops++ == maxloops) return 0;

    // Wait for the pulse to stop
    while (port->MASKED_ACCESS[bitMask] == stateMask)
    {
        if (numloops++ == maxloops) return 0;
        width++;
    }

    // Convert the reading to microseconds. The loop has been determined to be
    // 20 clock cycles long and have about 16 clocks between the edge and the
    // start of the loop. There will be some error introduced by the interrupt
    // handlers.
    return clockCyclesToMicroseconds(width * 21 + 16);
}
Beispiel #7
0
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
    _pin = pin;
    _type = type;
    _bit = digitalPinToBitMask(pin);
    _port = digitalPinToPort(pin);
    _maxcycles = microsecondsToClockCycles(1000);  // 1 millisecond timeout for
    // reading pulses from DHT sensor.
    // Note that count is now ignored as the DHT reading algorithm adjusts itself
    // basd on the speed of the processor.
}
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
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
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	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 any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. There will be some error introduced by
	// the interrupt handlers.

	// Conversion constants are compiler-dependent, different compiler versions
	// have different levels of optimization.
#if __GNUC__==4 && __GNUC_MINOR__==3 && __GNUC_PATCHLEVEL__==2
	// avr-gcc 4.3.2
	return clockCyclesToMicroseconds(width * 21 + 16);
#elif __GNUC__==4 && __GNUC_MINOR__==8 && __GNUC_PATCHLEVEL__==1
	// avr-gcc 4.8.1
	return clockCyclesToMicroseconds(width * 24 + 16);
#elif __GNUC__<=4 && __GNUC_MINOR__<=3
	// avr-gcc <=4.3.x
	#warning "pulseIn() results may not be accurate"
	return clockCyclesToMicroseconds(width * 21 + 16);
#else
	// avr-gcc >4.3.x
	#warning "pulseIn() results may not be accurate"
	return clockCyclesToMicroseconds(width * 24 + 16);
#endif

}
/*
 * Constructor for the sensor.  It remembers the pin number and the
 * type of sensor, and initializes internal variables.
 */
DHT_nonblocking::DHT_nonblocking( uint8_t pin, uint8_t type )
	: _pin( pin ),
	  _type( type ),
	  _bit( digitalPinToBitMask( pin ) ),
	  _port( digitalPinToPort( pin ) ),
	  _maxcycles( microsecondsToClockCycles( 1000 ) )
{
  dht_state = DHT_IDLE;

  pinMode( _pin, INPUT );
  digitalWrite( _pin, HIGH );
}
Beispiel #10
0
uint32_t DHT11::pulse(uint32_t state, uint32_t timeout)
{
  uint32_t maxloops = microsecondsToClockCycles(timeout) / 16;
  uint32_t numloops = 0;

  while (digitalRead(_pin) == state) {
		if (numloops++ == maxloops)
			return 0;
  }

  return numloops;
}
Beispiel #11
0
DHT::DHT(uint8_t pin) : _sensorID(-1)
{
  _pin = pin;
  
  #ifdef __AVR
    _bit = digitalPinToBitMask(pin);
    _port = digitalPinToPort(pin);
  #endif
  
  // 1 millisecond timeout for reading pulses from DHT sensor.
  // The DHT reading algorithm adjusts itself based on the speed of the processor.
  _maxcycles = microsecondsToClockCycles(1000);
}
// max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
    const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
    if (timeout > max_timeout_us) {
        timeout = max_timeout_us;
    }
    const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
    const uint32_t start_cycle_count = xthal_get_ccount();
    WAIT_FOR_PIN_STATE(!state);
    WAIT_FOR_PIN_STATE(state);
    const uint32_t pulse_start_cycle_count = xthal_get_ccount();
    WAIT_FOR_PIN_STATE(!state);
    return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
}
Beispiel #13
0
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	uint8_t volatile& pinreg = pinno2pinreg(pin);
	uint8_t msk = 1 << pinno2bit(pin);
	uint8_t stm = state? msk : 0;

	unsigned long w = 0;
	unsigned long n = 0;
	unsigned long m = microsecondsToClockCycles(timeout) / 16;

	while ((pinreg & msk) == stm)
		if (n++ == m) return 0;
	while ((pinreg & msk) != stm)
		if (n++ == m) return 0;
	while ((pinreg & msk) == stm)
		w++;

	return clockCyclesToMicroseconds(w * 10 + 16); 
}
void DHT::begin(uint8_t pin, uint8_t type) {
    _pin = pin;
    _type = type;
    #ifdef __AVR
      _bit = digitalPinToBitMask(pin);
      _port = digitalPinToPort(pin);
    #endif
    _maxcycles = microsecondsToClockCycles(1000);  // 1 millisecond timeout for
                                                   // reading pulses from DHT sensor.
    // Note that count is now ignored as the DHT reading algorithm adjusts itself
    // based on the speed of the processor.

  // set up the pins!
  pinMode(_pin, INPUT_PULLUP);
  // Using this value makes sure that millis() - lastreadtime will be
  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
  // but so will the subtraction.
  _lastreadtime = -MIN_INTERVAL;
  DEBUG_PRINT("Max clock cycles: "); DEBUG_PRINTLN(_maxcycles, DEC);
}
Beispiel #15
0
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
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
    // pulse width measuring loop and achieve finer resolution.  calling
    // digitalRead() instead yields much coarser resolution.
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    uint32_t portBase = (uint32_t) portBASERegister(port);
	uint8_t stateMask = (state ? bit : 0);

    // convert the timeout from microseconds to a number of times through
    // the initial loop; it takes 11 clock cycles per iteration.
    unsigned long numloops = 0;
    unsigned long maxloops = microsecondsToClockCycles(timeout) / 11;

    // wait for any previous pulse to end
    while (MAP_GPIOPinRead(portBase, bit) == stateMask)
        if (numloops++ == maxloops)
            return 0;

    // wait for the pulse to start
    while (MAP_GPIOPinRead(portBase, bit) != stateMask)
        if (numloops++ == maxloops)
            return 0;

    // wait for the pulse to stop
    unsigned long start = micros();

    while (MAP_GPIOPinRead(portBase, bit) == stateMask) {
        if (numloops++ == maxloops)
            return 0;
    }
    unsigned long end = micros();
    unsigned long result = end - start;
    return(result);
    // convert the reading to microseconds. The loop has been determined
    // to be 13 clock cycles long and have about 11 clocks between the edge
    // and the start of the loop. There will be some error introduced by
    // the interrupt handlers.
    //return clockCyclesToMicroseconds(width * 13 + 11);
}
Beispiel #16
0
// Same as pulseIn, but tweaked for range 1000 - 2000 usec, and reading only HIGH phase.
// Must be compiled in .cpp file, with -Os compiler switch.
unsigned long PulseIn(uint8_t pin, unsigned long timeout){
   const uint8_t bit = digitalPinToBitMask(pin), port = digitalPinToPort(pin);
   unsigned long width = 1;
   
   unsigned long numloops = 0;
   const unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

   noInterrupts();
                              //wait for the pulse to start
   while((*portInputRegister(port) & bit) != bit){
      if(++numloops == maxloops){
         interrupts();
         return 0;
      }
   }
                              //wait for the pulse to stop
   while((*portInputRegister(port) & bit) == bit)
      width++;
   interrupts();
   return clockCyclesToMicroseconds((width*0xd00L+0x800L)/256L);
}
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse.
 *
 * This function performs better with short pulses in noInterrupt() context
 */
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
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);

	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes approximately 16 clock cycles per iteration
	unsigned long maxloops = microsecondsToClockCycles(timeout)/16;

	unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);

	// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
	if (width)
		return clockCyclesToMicroseconds(width * 16 + 16);
	else
		return 0;
}
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
extern uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
{
	//TODO  Correct clock cycle constants.

	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	//PinDescription p = g_APinDescription[pin];
	uint32_t 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 22 clock cycles per iteration.
	uint32_t numloops = 0;
	uint32_t maxloops = microsecondsToClockCycles(timeout) / 22;
	
	// wait for any previous pulse to end
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) == state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) != state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) == state) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 52 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 52 + 16);
}
Beispiel #19
0
/* 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 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
extern uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )

{
	uint32_t width = 0; // keep initialization out of time critical area

	if(pin > 7)
		pin = pin + 4;
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 2 clock cycles per iteration.
	uint32_t numloops = 0;
	uint32_t maxloops = microsecondsToClockCycles(timeout) / 2;

	// wait for any previous pulse to end
  while (((NRF_GPIO->IN >> pin) & 1UL) == state)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to start
  while (((NRF_GPIO->IN >> pin) & 1UL) != state)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to stop
  while (((NRF_GPIO->IN >> pin) & 1UL) == state) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 17 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 17 + 16);
}