123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- //
- // FILE: dht.cpp
- // AUTHOR: Rob Tillaart
- // VERSION: 0.1.14
- // PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
- // URL: http://arduino.cc/playground/Main/DHTLib
- //
- // HISTORY:
- // 0.1.14 replace digital read with faster (~3x) code => more robust low MHz machines.
- // 0.1.13 fix negative dht_temperature
- // 0.1.12 support DHT33 and DHT44 initial version
- // 0.1.11 renamed DHTLIB_TIMEOUT
- // 0.1.10 optimized faster WAKEUP + TIMEOUT
- // 0.1.09 optimize size: timeout check + use of mask
- // 0.1.08 added formula for timeout based upon clockspeed
- // 0.1.07 added support for DHT21
- // 0.1.06 minimize footprint (2012-12-27)
- // 0.1.05 fixed negative dht_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 dht_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.00 by Rob Tillaart (01/04/2011)
- //
- // inspired by DHT11 library
- //
- // Released to the public domain
- //
- #include "user_interface.h"
- #include "platform.h"
- #include "c_stdio.h"
- #include "dht.h"
- #ifndef LOW
- #define LOW 0
- #endif /* ifndef LOW */
- #ifndef HIGH
- #define HIGH 1
- #endif /* ifndef HIGH */
- #define COMBINE_HIGH_AND_LOW_BYTE(byte_high, byte_low) (((byte_high) << 8) | (byte_low))
- static double dht_humidity;
- static double dht_temperature;
- static uint8_t dht_bytes[5]; // buffer to receive data
- static int dht_readSensor(uint8_t pin, uint8_t wakeupDelay);
- /////////////////////////////////////////////////////
- //
- // PUBLIC
- //
- // return values:
- // Humidity
- double dht_getHumidity(void)
- {
- return dht_humidity;
- }
- // return values:
- // Temperature
- double dht_getTemperature(void)
- {
- return dht_temperature;
- }
- // 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;
- }
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read11(uint8_t pin)
- {
- // READ VALUES
- int rv = dht_readSensor(pin, DHTLIB_DHT11_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;
- }
- // CONVERT AND STORE
- 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) return DHTLIB_ERROR_CHECKSUM;
- return DHTLIB_OK;
- }
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read(uint8_t pin)
- {
- // READ VALUES
- int rv = dht_readSensor(pin, DHTLIB_DHT_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
- }
- // CONVERT AND STORE
- 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;
- }
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read21(uint8_t pin) __attribute__((alias("dht_read")));
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read22(uint8_t pin) __attribute__((alias("dht_read")));
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read33(uint8_t pin) __attribute__((alias("dht_read")));
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_CHECKSUM
- // DHTLIB_ERROR_TIMEOUT
- int dht_read44(uint8_t pin) __attribute__((alias("dht_read")));
- /////////////////////////////////////////////////////
- //
- // PRIVATE
- //
- // return values:
- // DHTLIB_OK
- // DHTLIB_ERROR_TIMEOUT
- int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
- {
- // INIT BUFFERVAR TO RECEIVE DATA
- uint8_t mask = 128;
- uint8_t idx = 0;
- uint8_t i = 0;
- // 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);
- // volatile uint8_t *PIR = portInputRegister(port);
- // EMPTY BUFFER
- for (i = 0; i < 5; i++) dht_bytes[i] = 0;
- // REQUEST SAMPLE
- // pinMode(pin, OUTPUT);
- platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_PULLUP);
- DIRECT_MODE_OUTPUT(pin);
- // digitalWrite(pin, LOW); // T-be
- DIRECT_WRITE_LOW(pin);
- // delay(wakeupDelay);
- for (i = 0; i < wakeupDelay; i++) os_delay_us(1000);
- // Disable interrupts
- ets_intr_lock();
- // digitalWrite(pin, HIGH); // T-go
- DIRECT_WRITE_HIGH(pin);
- os_delay_us(40);
- // pinMode(pin, INPUT);
- DIRECT_MODE_INPUT(pin);
- // GET ACKNOWLEDGE or TIMEOUT
- uint16_t loopCntLOW = DHTLIB_TIMEOUT;
- while (DIRECT_READ(pin) == LOW ) // T-rel
- {
- os_delay_us(1);
- if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
- }
- uint16_t loopCntHIGH = DHTLIB_TIMEOUT;
- while (DIRECT_READ(pin) != LOW ) // T-reh
- {
- os_delay_us(1);
- if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
- }
- // READ THE OUTPUT - 40 BITS => 5 BYTES
- for (i = 40; i != 0; i--)
- {
- loopCntLOW = DHTLIB_TIMEOUT;
- while (DIRECT_READ(pin) == LOW )
- {
- os_delay_us(1);
- if (--loopCntLOW == 0) return DHTLIB_ERROR_TIMEOUT;
- }
- uint32_t t = system_get_time();
- loopCntHIGH = DHTLIB_TIMEOUT;
- while (DIRECT_READ(pin) != LOW )
- {
- os_delay_us(1);
- if (--loopCntHIGH == 0) return DHTLIB_ERROR_TIMEOUT;
- }
- if ((system_get_time() - t) > 40)
- {
- dht_bytes[idx] |= mask;
- }
- mask >>= 1;
- if (mask == 0) // next byte?
- {
- mask = 128;
- idx++;
- }
- }
- // Enable interrupts
- ets_intr_unlock();
- // pinMode(pin, OUTPUT);
- DIRECT_MODE_OUTPUT(pin);
- // digitalWrite(pin, HIGH);
- DIRECT_WRITE_HIGH(pin);
- return DHTLIB_OK;
- }
- //
- // END OF FILE
- //
|