Ejemplo n.º 1
0
bool DHTRead(DHT_Sensor *sensor, DHT_Sensor_Data* output)
{
	int counter = 0;
	int laststate = 1;
	int i = 0;
	int j = 0;
	int checksum = 0;
	int data[100];
	data[0] = data[1] = data[2] = data[3] = data[4] = 0;
	uint8_t pin = GPIO_ID_PIN(sensor->port);

	// Wake up device, 250ms of high
	GPIO_OUTPUT_SET(pin, 1);
	sleepms(250);
	// Hold low for 20ms
	GPIO_OUTPUT_SET(pin, 0);
	sleepms(20);
	// High for 40ns
	GPIO_OUTPUT_SET(pin, 1);
	os_delay_us(40);
	// Set DHT_PIN pin as an input
	GPIO_DIS_OUTPUT(pin);

	// wait for pin to drop?
	while (GPIO_INPUT_GET(pin) == 1 && i < DHT_MAXCOUNT) {
		os_delay_us(1);
		i++;
	}

	if(i == DHT_MAXCOUNT)
	{
		DHT_DEBUG("DHT: Failed to get reading from GPIO%d, dying\r\n", pin);
	    return false;
	}

	// read data
	for (i = 0; i < DHT_MAXTIMINGS; i++)
	{
		// Count high time (in approx us)
		counter = 0;
		while (GPIO_INPUT_GET(pin) == laststate)
		{
			counter++;
			os_delay_us(1);
			if (counter == 1000)
				break;
		}
		laststate = GPIO_INPUT_GET(pin);
		if (counter == 1000)
			break;
		// store data after 3 reads
		if ((i>3) && (i%2 == 0)) {
			// shove each bit into the storage bytes
			data[j/8] <<= 1;
			if (counter > DHT_BREAKTIME)
				data[j/8] |= 1;
			j++;
		}
	}

	if (j >= 39) {
		checksum = (data[0] + data[1] + data[2] + data[3]) & 0xFF;
	    DHT_DEBUG("DHT%s: %02x %02x %02x %02x [%02x] CS: %02x (GPIO%d)\r\n",
	              sensor->type==DHT11?"11":"22",
	              data[0], data[1], data[2], data[3], data[4], checksum, pin);
		if (data[4] == checksum) {
			// checksum is valid
			output->temperature = scale_temperature(sensor->type, data);
			output->humidity = scale_humidity(sensor->type, data);
			//DHT_DEBUG("DHT: Temperature =  %d *C, Humidity = %d %%\r\n", (int)(reading.temperature * 100), (int)(reading.humidity * 100));
			DHT_DEBUG("DHT: Temperature*100 =  %d *C, Humidity*100 = %d %% (GPIO%d)\n",
		          (int) (output->temperature * 100), (int) (output->humidity * 100), pin);
		} else {
			//DHT_DEBUG("Checksum was incorrect after %d bits. Expected %d but got %d\r\n", j, data[4], checksum);
			DHT_DEBUG("DHT: Checksum was incorrect after %d bits. Expected %d but got %d (GPIO%d)\r\n",
		                j, data[4], checksum, pin);
		    return false;
		}
	} else {
		//DHT_DEBUG("Got too few bits: %d should be at least 40\r\n", j);
	    DHT_DEBUG("DHT: Got too few bits: %d should be at least 40 (GPIO%d)\r\n", j, pin);
	    return false;
	}
	return true;
}
Ejemplo n.º 2
0
// return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int dht_read_universal(uint8_t pin)
{
    // READ VALUES
    int rv = dht_readSensor(pin, DHTLIB_DHT_UNI_WAKEUP);
    if (rv != DHTLIB_OK)
    {
        dht_humidity    = DHTLIB_INVALID_VALUE;  // invalid value, or is NaN prefered?
        dht_temperature = DHTLIB_INVALID_VALUE;  // invalid value
        return rv; // propagate error value
    }

#if defined(DHT_DEBUG_BYTES)
    int i;
    for (i = 0; i < 5; i++)
    {
        DHT_DEBUG("%02X\n", dht_bytes[i]);
    }
#endif // defined(DHT_DEBUG_BYTES)

    // Assume it is DHT11
    // If it is DHT11, both bit[1] and bit[3] is 0
    if ((dht_bytes[1] == 0) && (dht_bytes[3] == 0))
    {
        // It may DHT11
        // CONVERT AND STORE
        DHT_DEBUG("DHT11 method\n");
        dht_humidity    = dht_bytes[0];  // dht_bytes[1] == 0;
        dht_temperature = dht_bytes[2];  // dht_bytes[3] == 0;

        // TEST CHECKSUM
        // dht_bytes[1] && dht_bytes[3] both 0
        uint8_t sum = dht_bytes[0] + dht_bytes[2];
        if (dht_bytes[4] != sum)
        {
            // It may not DHT11
            dht_humidity    = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
            dht_temperature = DHTLIB_INVALID_VALUE; // invalid value
            // Do nothing
        }
        else
        {
            return DHTLIB_OK;
        }
    }

    // Assume it is not DHT11
    // CONVERT AND STORE
    DHT_DEBUG("DHTxx method\n");
    dht_humidity = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
    dht_temperature = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
    if (dht_bytes[2] & 0x80)  // negative dht_temperature
    {
        dht_temperature = -dht_temperature;
    }

    // TEST CHECKSUM
    uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
    if (dht_bytes[4] != sum)
    {
        return DHTLIB_ERROR_CHECKSUM;
    }
    return DHTLIB_OK;
}
Ejemplo n.º 3
0
static void
dht_read(void)
{
  PIN_SET(DHT);
  _delay_us(30);
  DDR_CONFIG_IN(DHT);

  /* Read in timingss, which takes approx. 4,5 milliseconds.
   * We do not disable interrupts, because a failed read is outweighed
   * by a non-serviced interrupt. Please never enclose the for-loop
   * with an ATOMIC_BLOCK! */

  uint8_t last_state = PIN_BV(DHT);
  uint8_t j = 0;
  uint8_t data[5];
  for (uint8_t i = 0; i < MAXTIMINGS; i++)
  {
    uint8_t counter = 0;
    uint8_t current_state;
    while (last_state == (current_state = PIN_HIGH(DHT)))
    {
      _delay_us(5);
      if (++counter == 20)
      {
        DHT_DEBUG("read timeout, edge=%u", i);
        return;                 /* timeout in conversation */
      }
    }
    last_state = current_state;

    /* ignore first three transitions */
    if ((i >= 4) && (i % 2 == 0))
    {
      /* shift each bit into the storage bytes */
      data[j / 8] <<= 1;
      if (counter > 7)          /* 7*5=35us */
        data[j / 8] |= 1;
      j++;
    }
  }

  /* check we read 40 bits and that the checksum matches */
  if ((j < 40) ||
      (data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
  {
    DHT_DEBUG("read failed, bits=%u, %02X %02X %02X %02X %02X",
              j, data[0], data[1], data[2], data[3], data[4]);
    return;
  }

  int16_t t;
#if DHT_TYPE == DHT_TYPE_11
  t = data[2];
  t *= 10;
  dht_global.temp = t;
  t = data[0];
  t *= 10;
  dht_global.humid = t;
#elif DHT_TYPE == DHT_TYPE_22
  t = data[2] << 8 | data[3];
  if (t & 0x8000)
  {
    t &= ~0x8000;
    t = -t;
  }
  dht_global.temp = t;
  t = data[0] << 8 | data[1];
  dht_global.humid = t;
#endif
  DHT_DEBUG("t=%d, h=%d%%", dht_global.temp, dht_global.humid);
}