From fa681d5322a7f362bda70cb487a708736e367cd2 Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Wed, 8 Oct 2014 16:37:30 +0200 Subject: [PATCH] + reduced # micros calls 2->1 in inner loop. => footprint -18 detection of the zero/one is doen by measuring the whole bit LOW+HIGH + improved wait for acknowledge + merged two loopCounters into one. + layout + dht22_test sketch collects statistics (every 20 reads) --- libraries/DHTlib/dht.cpp | 91 +++++++++++-------- libraries/DHTlib/dht.h | 4 +- .../DHTlib/examples/dht22_test/dht22_test.ino | 36 +++++++- 3 files changed, 90 insertions(+), 41 deletions(-) diff --git a/libraries/DHTlib/dht.cpp b/libraries/DHTlib/dht.cpp index 7bb368e2..bafede31 100644 --- a/libraries/DHTlib/dht.cpp +++ b/libraries/DHTlib/dht.cpp @@ -1,11 +1,12 @@ // // FILE: dht.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.14 +// VERSION: 0.1.15 // PURPOSE: DHT Temperature & Humidity Sensor library for Arduino // URL: http://arduino.cc/playground/Main/DHTLib // // HISTORY: +// 0.1.15 reduced # micros calls 2->1 in inner loop. // 0.1.14 replace digital read with faster (~3x) code => more robust low MHz machines. // 0.1.13 fix negative temperature // 0.1.12 support DHT33 and DHT44 initial version @@ -44,8 +45,8 @@ int dht::read11(uint8_t pin) int rv = _readSensor(pin, DHTLIB_DHT11_WAKEUP); if (rv != DHTLIB_OK) { - humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered? - temperature = DHTLIB_INVALID_VALUE; // invalid value + humidity = DHTLIB_INVALID_VALUE; + temperature = DHTLIB_INVALID_VALUE; return rv; } @@ -56,8 +57,10 @@ int dht::read11(uint8_t pin) // TEST CHECKSUM // bits[1] && bits[3] both 0 uint8_t sum = bits[0] + bits[2]; - if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM; - + if (bits[4] != sum) + { + return DHTLIB_ERROR_CHECKSUM; + } return DHTLIB_OK; } @@ -111,8 +114,8 @@ int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay) // replace digitalRead() with Direct Port Reads. // reduces footprint ~100 bytes => portability issue? // direct port read is about 3x faster - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); + uint8_t bit = digitalPinToBitMask(pin); + uint8_t port = digitalPinToPort(pin); volatile uint8_t *PIR = portInputRegister(port); // EMPTY BUFFER @@ -120,52 +123,66 @@ int dht::_readSensor(uint8_t pin, uint8_t wakeupDelay) // REQUEST SAMPLE pinMode(pin, OUTPUT); - digitalWrite(pin, LOW); // T-be + digitalWrite(pin, LOW); // T-be delay(wakeupDelay); - digitalWrite(pin, HIGH); // T-go - delayMicroseconds(40); + digitalWrite(pin, HIGH); // T-go pinMode(pin, INPUT); + uint16_t loopCount = DHTLIB_TIMEOUT*2; // 200uSec max + // while(digitalRead(pin) == HIGH) + while ((*PIR & bit) != LOW ) + { + if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT; + } + // GET ACKNOWLEDGE or TIMEOUT - uint16_t loopCntLOW = DHTLIB_TIMEOUT; + loopCount = DHTLIB_TIMEOUT; + // while(digitalRead(pin) == LOW) while ((*PIR & bit) == LOW ) // T-rel { - if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT; + if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT; } - uint16_t loopCntHIGH = DHTLIB_TIMEOUT; + loopCount = DHTLIB_TIMEOUT; + // while(digitalRead(pin) == HIGH) while ((*PIR & bit) != LOW ) // T-reh { - if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT; + if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT; } + uint8_t state = LOW; + uint8_t pstate = LOW; + loopCount = DHTLIB_TIMEOUT; + uint32_t t1 = micros(); + // READ THE OUTPUT - 40 BITS => 5 BYTES - for (uint8_t i = 40; i != 0; i--) + for (uint8_t i = 40; i != 0; ) { - loopCntLOW = DHTLIB_TIMEOUT; - while ((*PIR & bit) == LOW ) + // WAIT FOR FALLING EDGE + state = (*PIR & bit); + if (state == LOW && pstate != LOW) { - if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT; - } - - uint32_t t = micros(); - - loopCntHIGH = DHTLIB_TIMEOUT; - while ((*PIR & bit) != LOW ) - { - if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT; - } - - if ((micros() - t) > 40) - { - bits[idx] |= mask; - } - mask >>= 1; - if (mask == 0) // next byte? - { - mask = 128; - idx++; + uint32_t t2 = micros(); + if ((t2-t1) > 100 ) // long -> one + { + bits[idx] |= mask; + } + mask >>= 1; + if (mask == 0) // next byte + { + mask = 128; + idx++; + } + // next bit + --i; + // update time admin + t1 = t2; + // reset timeout flag + loopCount = DHTLIB_TIMEOUT; } + pstate = state; + // Check timeout + if (--loopCount == 0) return DHTLIB_ERROR_TIMEOUT; } pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); diff --git a/libraries/DHTlib/dht.h b/libraries/DHTlib/dht.h index 31d552f2..cff6d8e4 100644 --- a/libraries/DHTlib/dht.h +++ b/libraries/DHTlib/dht.h @@ -1,7 +1,7 @@ // // FILE: dht.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.14 +// VERSION: 0.1.15 // PURPOSE: DHT Temperature & Humidity Sensor library for Arduino // URL: http://arduino.cc/playground/Main/DHTLib // @@ -18,7 +18,7 @@ #include #endif -#define DHT_LIB_VERSION "0.1.14" +#define DHT_LIB_VERSION "0.1.15" #define DHTLIB_OK 0 #define DHTLIB_ERROR_CHECKSUM -1 diff --git a/libraries/DHTlib/examples/dht22_test/dht22_test.ino b/libraries/DHTlib/examples/dht22_test/dht22_test.ino index ebd45d82..26f8307b 100644 --- a/libraries/DHTlib/examples/dht22_test/dht22_test.ino +++ b/libraries/DHTlib/examples/dht22_test/dht22_test.ino @@ -1,9 +1,13 @@ // // FILE: dht22_test.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.01 +// VERSION: 0.1.02 // PURPOSE: DHT library test sketch for DHT22 && Arduino // URL: +// HISTORY: +// 0.1.02 added counters for error-regression testing. +// 0.1.01 +// 0.1.00 initial version // // Released to the public domain // @@ -14,10 +18,19 @@ dht DHT; #define DHT22_PIN 5 +struct +{ + uint32_t total; + uint32_t ok; + uint32_t crc_error; + uint32_t time_out; + uint32_t unknown; +} stat = { 0,0,0,0,0 }; + void setup() { Serial.begin(115200); - Serial.println("DHT TEST PROGRAM "); + Serial.println("dht22_test.ino"); Serial.print("LIBRARY VERSION: "); Serial.println(DHT_LIB_VERSION); Serial.println(); @@ -33,18 +46,23 @@ void loop() int chk = DHT.read22(DHT22_PIN); uint32_t stop = micros(); + stat.total++; switch (chk) { case DHTLIB_OK: + stat.ok++; Serial.print("OK,\t"); break; case DHTLIB_ERROR_CHECKSUM: + stat.crc_error++; Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: + stat.time_out++; Serial.print("Time out error,\t"); break; default: + stat.unknown++; Serial.print("Unknown error,\t"); break; } @@ -56,6 +74,20 @@ void loop() Serial.print(stop - start); Serial.println(); + if (stat.total % 20 == 0) + { + Serial.println("\nTOT\tOK\tCRC\tTO\tUNK"); + Serial.print(stat.total); + Serial.print("\t"); + Serial.print(stat.ok); + Serial.print("\t"); + Serial.print(stat.crc_error); + Serial.print("\t"); + Serial.print(stat.time_out); + Serial.print("\t"); + Serial.print(stat.unknown); + Serial.println("\n"); + } delay(2000); } //