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