diff --git a/DHT.cpp b/DHT.cpp index 86ad91c..021b15d 100644 --- a/DHT.cpp +++ b/DHT.cpp @@ -33,32 +33,11 @@ void DHT::begin(void) { //boolean S == Scale. True == Fahrenheit; False == Celcius float DHT::readTemperature(bool S, bool force) { - float f = NAN; - - if (read(force)) { - switch (_type) { - case DHT11: - f = data[2]; - if(S) { - f = convertCtoF(f); - } - break; - case DHT22: - case DHT21: - f = data[2] & 0x7F; - f *= 256; - f += data[3]; - f *= 0.1; - if (data[2] & 0x80) { - f *= -1; - } - if(S) { - f = convertCtoF(f); - } - break; - } - } - return f; + //Argument <> is kept only for back-compatibility + if(S) + return this->convertCtoF(this->_temperature); + else + return this->_temperature; } float DHT::convertCtoF(float c) { @@ -70,22 +49,8 @@ float DHT::convertFtoC(float f) { } float DHT::readHumidity(bool force) { - float f = NAN; - if (read()) { - switch (_type) { - case DHT11: - f = data[0]; - break; - case DHT22: - case DHT21: - f = data[0]; - f *= 256; - f += data[1]; - f *= 0.1; - break; - } - } - return f; + //Argument <> is kept only for back-compatibility + return this->_humidity; } //boolean isFahrenheit: True == Fahrenheit; False == Celcius @@ -120,30 +85,53 @@ float DHT::computeHeatIndex(float temperature, float percentHumidity, bool isFah return isFahrenheit ? hi : convertFtoC(hi); } -boolean DHT::read(bool force) { - // Check if sensor was read less than two seconds ago and return early - // to use last reading. + +void DHT::loop(){ uint32_t currenttime = millis(); - if (!force && ((currenttime - _lastreadtime) < 2000)) { - return _lastresult; // return last correct measurement - } - _lastreadtime = currenttime; + switch(this->state){ + case IDLE: + // Check if sensor was read less than two seconds ago and return early + // to use last reading. + if((currenttime - _lastreadtime) < 2000) + return; + this->_lastreadtime = currenttime; + this->state = WAITING; + + // Reset 40 bits of received data to zero. + data[0] = data[1] = data[2] = data[3] = data[4] = 0; + + // Send start signal. See DHT datasheet for full signal diagram: + // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf + // Go into high impedence state to let pull-up raise data line level and + // start the reading process. + digitalWrite(_pin, HIGH); + break; + + case WAITING: + if((currenttime-_lastreadtime) < 250) + return; + // First set data line low for 20 milliseconds. + pinMode(_pin, OUTPUT); + digitalWrite(_pin, LOW); - // Reset 40 bits of received data to zero. - data[0] = data[1] = data[2] = data[3] = data[4] = 0; + this->_lastreadtime = currenttime; + this->state = READING; + break; - // Send start signal. See DHT datasheet for full signal diagram: - // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf + case READING: + if((currenttime-_lastreadtime) < 20) + return; + this->read(); + this->state = IDLE; + + } +} - // Go into high impedence state to let pull-up raise data line level and - // start the reading process. - digitalWrite(_pin, HIGH); - delay(250); +boolean DHT::isValid(){ + return this->_lastresult; +} - // First set data line low for 20 milliseconds. - pinMode(_pin, OUTPUT); - digitalWrite(_pin, LOW); - delay(20); +boolean DHT::read() { uint32_t cycles[80]; { @@ -217,6 +205,20 @@ boolean DHT::read(bool force) { // Check we read 40 bits and that the checksum matches. if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { + float t,h; + switch (_type) { + case DHT11: + this->_temperature = data[2]; + this->_humidity = data[0]; + break; + case DHT22: + case DHT21: + t = (data[2] & 0x7F) * 256 + data[3]; + this->_temperature = t * 0.1 * ((data[2] & 0x80) ? -1 : 1); + h = data[0] * 256 + data[1]; + this->_humidity = h * 0.1; + break; + } _lastresult = true; return _lastresult; } diff --git a/DHT.h b/DHT.h index d81f6db..9370d4d 100644 --- a/DHT.h +++ b/DHT.h @@ -44,7 +44,9 @@ class DHT { float convertFtoC(float); float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true); float readHumidity(bool force=false); - boolean read(bool force=false); + boolean read(); + boolean isValid(); + void loop(); private: uint8_t data[5]; @@ -57,7 +59,17 @@ class DHT { uint32_t _lastreadtime, _maxcycles; bool _lastresult; + float _temperature, _humidity; + + enum readingStatus{ + IDLE, + WAITING, + READING + }; + uint32_t expectPulse(bool level); + + readingStatus state = IDLE; }; diff --git a/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino b/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino index 4820f2e..c9e9596 100644 --- a/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino +++ b/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino @@ -5,7 +5,7 @@ // Depends on the following Arduino libraries: // - Adafruit Unified Sensor Library: https://github.com/adafruit/Adafruit_Sensor -// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library +// - DHT Sensor Library: https://github.com/nos86/DHT-sensor-library#async #include #include @@ -24,6 +24,7 @@ DHT_Unified dht(DHTPIN, DHTTYPE); uint32_t delayMS; +float lastReading = 0; void setup() { Serial.begin(9600); @@ -58,27 +59,30 @@ void setup() { } void loop() { + dht.loop(); // Delay between measurements. - delay(delayMS); - // Get temperature event and print its value. - sensors_event_t event; - dht.temperature().getEvent(&event); - if (isnan(event.temperature)) { - Serial.println("Error reading temperature!"); - } - else { - Serial.print("Temperature: "); - Serial.print(event.temperature); - Serial.println(" *C"); - } - // Get humidity event and print its value. - dht.humidity().getEvent(&event); - if (isnan(event.relative_humidity)) { - Serial.println("Error reading humidity!"); - } - else { - Serial.print("Humidity: "); - Serial.print(event.relative_humidity); - Serial.println("%"); + if(mills()-lastReading>delayMS){ + lastReading = millis(); + // Get temperature event and print its value. + sensors_event_t event; + dht.temperature().getEvent(&event); + if (isnan(event.temperature)) { + Serial.println("Error reading temperature!"); + } + else { + Serial.print("Temperature: "); + Serial.print(event.temperature); + Serial.println(" *C"); + } + // Get humidity event and print its value. + dht.humidity().getEvent(&event); + if (isnan(event.relative_humidity)) { + Serial.println("Error reading humidity!"); + } + else { + Serial.print("Humidity: "); + Serial.print(event.relative_humidity); + Serial.println("%"); + } } } diff --git a/examples/DHTtester/DHTtester.ino b/examples/DHTtester/DHTtester.ino index ae6c41a..3a3fcf7 100644 --- a/examples/DHTtester/DHTtester.ino +++ b/examples/DHTtester/DHTtester.ino @@ -1,5 +1,5 @@ // Example testing sketch for various DHT humidity/temperature sensors -// Written by ladyada, public domain +// Written by nos86, public domain #include "DHT.h" @@ -22,6 +22,7 @@ // tweak the timings for faster processors. This parameter is no longer needed // as the current DHT reading algorithm adjusts itself to work on faster procs. DHT dht(DHTPIN, DHTTYPE); +float lastReading = 0; void setup() { Serial.begin(9600); @@ -32,38 +33,40 @@ void setup() { void loop() { // Wait a few seconds between measurements. - delay(2000); - - // Reading temperature or humidity takes about 250 milliseconds! - // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) - float h = dht.readHumidity(); - // Read temperature as Celsius (the default) - float t = dht.readTemperature(); - // Read temperature as Fahrenheit (isFahrenheit = true) - float f = dht.readTemperature(true); - - // Check if any reads failed and exit early (to try again). - if (isnan(h) || isnan(t) || isnan(f)) { - Serial.println("Failed to read from DHT sensor!"); - return; + dht.loop(); + if(millis()-lastReading>2000){ + lastReading = millis(); + // Reading temperature or humidity takes about 250 milliseconds! + // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) + float h = dht.readHumidity(); + // Read temperature as Celsius (the default) + float t = dht.readTemperature(); + // Read temperature as Fahrenheit (isFahrenheit = true) + float f = dht.readTemperature(true); + + // Check if any reads failed and exit early (to try again). + if (isnan(h) || isnan(t) || isnan(f)) { + Serial.println("Failed to read from DHT sensor!"); + return; + } + + // Compute heat index in Fahrenheit (the default) + float hif = dht.computeHeatIndex(f, h); + // Compute heat index in Celsius (isFahreheit = false) + float hic = dht.computeHeatIndex(t, h, false); + + Serial.print("Humidity: "); + Serial.print(h); + Serial.print(" %\t"); + Serial.print("Temperature: "); + Serial.print(t); + Serial.print(" *C "); + Serial.print(f); + Serial.print(" *F\t"); + Serial.print("Heat index: "); + Serial.print(hic); + Serial.print(" *C "); + Serial.print(hif); + Serial.println(" *F"); } - - // Compute heat index in Fahrenheit (the default) - float hif = dht.computeHeatIndex(f, h); - // Compute heat index in Celsius (isFahreheit = false) - float hic = dht.computeHeatIndex(t, h, false); - - Serial.print("Humidity: "); - Serial.print(h); - Serial.print(" %\t"); - Serial.print("Temperature: "); - Serial.print(t); - Serial.print(" *C "); - Serial.print(f); - Serial.print(" *F\t"); - Serial.print("Heat index: "); - Serial.print(hic); - Serial.print(" *C "); - Serial.print(hif); - Serial.println(" *F"); } diff --git a/keywords.txt b/keywords.txt index 146d4fa..b4d9cd5 100644 --- a/keywords.txt +++ b/keywords.txt @@ -19,4 +19,5 @@ convertFtoC KEYWORD2 computeHeatIndex KEYWORD2 readHumidity KEYWORD2 read KEYWORD2 - +loop KEYWORD2 +isValid KEYWORD2