diff --git a/DHT.cpp b/DHT.cpp index 713abac..79e9027 100644 --- a/DHT.cpp +++ b/DHT.cpp @@ -3,3 +3,148 @@ MIT license written by Adafruit Industries */ + +#include "DHT.h" + +DHT::DHT(uint8_t pin, uint8_t type) { + _pin = pin; + _type = type; + firstreading = true; +} + +void DHT::begin(void) { + // set up the pins! + pinMode(_pin, INPUT); + digitalWrite(_pin, HIGH); + _lastreadtime = 0; +} + +float DHT::readTemperature(void) { + float f; + + if (read()) { + switch (_type) { + case DHT11: + f = data[2]; + return f; + case DHT22: + case DHT21: + f = data[2] & 0x7F; + f *= 256; + f += data[3]; + f /= 10; + if (data[2] & 0x80) + f *= -1; + + return f; + } + } + Serial.print("Read fail"); + return NAN; +} + +float DHT::readHumidity(void) { + float f; + if (read()) { + switch (_type) { + case DHT11: + f = data[0]; + return f; + case DHT22: + case DHT21: + f = data[0]; + f *= 256; + f += data[1]; + f /= 10; + return f; + } + } + Serial.print("Read fail"); + return NAN; +} + + +boolean DHT::read(void) { + uint8_t laststate = HIGH; + uint8_t counter = 0; + uint8_t j = 0, i; + unsigned long currenttime; + + // pull the pin high and wait 250 milliseconds + digitalWrite(_pin, HIGH); + delay(250); + + currenttime = millis(); + if (currenttime < _lastreadtime) { + // ie there was a rollover + _lastreadtime = 0; + } + if (!firstreading && ((currenttime - _lastreadtime) < 2000)) { + return true; // return last correct measurement + //delay(2000 - (currenttime - _lastreadtime)); + } + firstreading = false; + /* + Serial.print("Currtime: "); Serial.print(currenttime); + Serial.print(" Lasttime: "); Serial.print(_lastreadtime); + */ + _lastreadtime = millis(); + + data[0] = data[1] = data[2] = data[3] = data[4] = 0; + + // now pull it low for ~20 milliseconds + pinMode(_pin, OUTPUT); + digitalWrite(_pin, LOW); + delay(20); + cli(); + digitalWrite(_pin, HIGH); + delayMicroseconds(40); + pinMode(_pin, INPUT); + + // read in timings + for ( i=0; i< MAXTIMINGS; i++) { + counter = 0; + while (digitalRead(_pin) == laststate) { + counter++; + delayMicroseconds(1); + if (counter == 255) { + break; + } + } + laststate = digitalRead(_pin); + + if (counter == 255) break; + + // ignore first 3 transitions + if ((i >= 4) && (i%2 == 0)) { + // shove each bit into the storage bytes + data[j/8] <<= 1; + if (counter > 6) + data[j/8] |= 1; + j++; + } + + } + + sei(); + + /* + Serial.println(j, DEC); + Serial.print(data[0], HEX); Serial.print(", "); + Serial.print(data[1], HEX); Serial.print(", "); + Serial.print(data[2], HEX); Serial.print(", "); + Serial.print(data[3], HEX); Serial.print(", "); + Serial.print(data[4], HEX); Serial.print(" =? "); + Serial.println(data[0] + data[1] + data[2] + data[3], HEX); + */ + + // check we read 40 bits and that the checksum matches + if ((j >= 40) && + (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) { + return true; + } + + + return false; + +} diff --git a/DHT.h b/DHT.h index 713abac..0e1d544 100644 --- a/DHT.h +++ b/DHT.h @@ -1,5 +1,32 @@ + +#include + /* DHT library MIT license written by Adafruit Industries */ + +// how many timing transitions we need to keep track of. 2 * number bits + extra +#define MAXTIMINGS 85 + +#define DHT11 11 +#define DHT22 22 +#define DHT21 21 +#define AM2301 21 + +class DHT { + private: + uint8_t data[6]; + uint8_t _pin, _type; + boolean read(void); + unsigned long _lastreadtime; + boolean firstreading; + + public: + DHT(uint8_t pin, uint8_t type); + void begin(void); + float readTemperature(void); + float readHumidity(void); + +};