// // FILE: dht.cpp // AUTHOR: Rob Tillaart // VERSION: 0.1.07 // PURPOSE: DHT Temperature & Humidity Sensor library for Arduino // URL: http://arduino.cc/playground/Main/DHTLib // // HISTORY: // 0.1.07 added support for DHT21 // 0.1.06 minimize footprint (2012-12-27) // 0.1.05 fixed negative temperature bug (thanks to Roseman) // 0.1.04 improved readability of code using DHTLIB_OK in code // 0.1.03 added error values for temp and humidity when read failed // 0.1.02 added error codes // 0.1.01 added support for Arduino 1.0, fixed typos (31/12/2011) // 0.1.0 by Rob Tillaart (01/04/2011) // // inspired by DHT11 library // // Released to the public domain // #include "dht.h" #define TIMEOUT (F_CPU/1600) // unsigned int in code, for higher CPU speeds this might exceed MAXINT. ///////////////////////////////////////////////////// // // PUBLIC // // return values: // DHTLIB_OK // DHTLIB_ERROR_CHECKSUM // DHTLIB_ERROR_TIMEOUT int dht::read11(uint8_t pin) { // READ VALUES int rv = read(pin); if (rv != DHTLIB_OK) { humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered? temperature = DHTLIB_INVALID_VALUE; // invalid value return rv; } // CONVERT AND STORE humidity = bits[0]; // bit[1] == 0; temperature = bits[2]; // bits[3] == 0; // TEST CHECKSUM // bits[1] && bits[3] both 0 uint8_t sum = bits[0] + bits[2]; if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM; return DHTLIB_OK; } // return values: // DHTLIB_OK // DHTLIB_ERROR_CHECKSUM // DHTLIB_ERROR_TIMEOUT int dht::read21(uint8_t pin) { return read22(pin); // dataformat identical to DHT22 } // return values: // DHTLIB_OK // DHTLIB_ERROR_CHECKSUM // DHTLIB_ERROR_TIMEOUT int dht::read22(uint8_t pin) { // READ VALUES int rv = read(pin); if (rv != DHTLIB_OK) { humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered? temperature = DHTLIB_INVALID_VALUE; // invalid value return rv; // propagate error value } // CONVERT AND STORE humidity = word(bits[0], bits[1]) * 0.1; if (bits[2] & 0x80) // negative temperature { temperature = -0.1 * word(bits[2] & 0x7F, bits[3]); } else { temperature = 0.1 * word(bits[2], bits[3]); } // TEST CHECKSUM uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3]; if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM; return DHTLIB_OK; } ///////////////////////////////////////////////////// // // PRIVATE // // return values: // DHTLIB_OK // DHTLIB_ERROR_TIMEOUT int dht::read(uint8_t pin) { // INIT BUFFERVAR TO RECEIVE DATA uint8_t cnt = 7; uint8_t idx = 0; // EMPTY BUFFER for (uint8_t i=0; i< 5; i++) bits[i] = 0; // REQUEST SAMPLE pinMode(pin, OUTPUT); digitalWrite(pin, LOW); delay(20); digitalWrite(pin, HIGH); delayMicroseconds(40); pinMode(pin, INPUT); // GET ACKNOWLEDGE or TIMEOUT unsigned int loopCnt = TIMEOUT; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; loopCnt = TIMEOUT; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; // READ THE OUTPUT - 40 BITS => 5 BYTES for (uint8_t i=0; i<40; i++) { loopCnt = TIMEOUT; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; unsigned long t = micros(); loopCnt = TIMEOUT; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; if ((micros() - t) > 40) bits[idx] |= (1 << cnt); if (cnt == 0) // next byte? { cnt = 7; idx++; } else cnt--; } return DHTLIB_OK; } // // END OF FILE //