diff --git a/DHT.cpp b/DHT.cpp index 390cfad..14e1d85 100644 --- a/DHT.cpp +++ b/DHT.cpp @@ -1,29 +1,62 @@ -/* DHT library - -MIT license -written by Adafruit Industries -*/ +/*! + * @file DHT.cpp + * + * @mainpage DHT series of low cost temperature/humidity sensors. + * + * @section intro_sec Introduction + * + * This is a library for DHT series of low cost temperature/humidity sensors. + * + * You must have Adafruit Unified Sensor Library library installed to use this + * class. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * @section author Author + * + * Written by Adafruit Industries. + * + * @section license License + * + * MIT license, all text above must be included in any redistribution + */ #include "DHT.h" -#define MIN_INTERVAL 2000 -#define TIMEOUT -1 +#define MIN_INTERVAL 2000 /**< min interval value */ +#define TIMEOUT -1 /**< timeout on */ +/*! + * @brief Instantiates a new DHT class + * @param pin + * pin number that sensor is connected + * @param type + * type of sensor + * @param count + * number of sensors + */ DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) { _pin = pin; _type = type; - #ifdef __AVR - _bit = digitalPinToBitMask(pin); - _port = digitalPinToPort(pin); - #endif - _maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for - // reading pulses from DHT sensor. +#ifdef __AVR + _bit = digitalPinToBitMask(pin); + _port = digitalPinToPort(pin); +#endif + _maxcycles = + microsecondsToClockCycles(1000); // 1 millisecond timeout for + // reading pulses from DHT sensor. // Note that count is now ignored as the DHT reading algorithm adjusts itself // based on the speed of the processor. } -// Optionally pass pull-up time (in microseconds) before DHT reading starts. -// Default is 55 (see function declaration in DHT.h). +/*! + * @brief Setup sensor pins and set pull timings + * @param usec + * Optionally pass pull-up time (in microseconds) before DHT reading + *starts. Default is 55 (see function declaration in DHT.h). + */ void DHT::begin(uint8_t usec) { // set up the pins! pinMode(_pin, INPUT_PULLUP); @@ -31,11 +64,21 @@ void DHT::begin(uint8_t usec) { // >= MIN_INTERVAL right away. Note that this assignment wraps around, // but so will the subtraction. _lastreadtime = millis() - MIN_INTERVAL; - DEBUG_PRINT("DHT max clock cycles: "); DEBUG_PRINTLN(_maxcycles, DEC); + DEBUG_PRINT("DHT max clock cycles: "); + DEBUG_PRINTLN(_maxcycles, DEC); pullTime = usec; } -//boolean S == Scale. True == Fahrenheit; False == Celcius +/*! + * @brief Read temperature + * @param S + * Scale. Boolean value: + * - true = Fahrenheit + * - false = Celcius + * @param force + * true if in force mode + * @return Temperature value in selected scale + */ float DHT::readTemperature(bool S, bool force) { float f = NAN; @@ -44,10 +87,10 @@ float DHT::readTemperature(bool S, bool force) { case DHT11: f = data[2]; if (data[3] & 0x80) { - f = -1 - f ; + f = -1 - f; } f += (data[3] & 0x0f) * 0.1; - if(S) { + if (S) { f = convertCtoF(f); } break; @@ -57,7 +100,7 @@ float DHT::readTemperature(bool S, bool force) { if (data[2] & 0x80) { f *= -1; } - if(S) { + if (S) { f = convertCtoF(f); } break; @@ -68,7 +111,7 @@ float DHT::readTemperature(bool S, bool force) { if (data[2] & 0x80) { f *= -1; } - if(S) { + if (S) { f = convertCtoF(f); } break; @@ -77,14 +120,28 @@ float DHT::readTemperature(bool S, bool force) { return f; } -float DHT::convertCtoF(float c) { - return c * 1.8 + 32; -} +/*! + * @brief Converts Celcius to Fahrenheit + * @param c + * value in Celcius + * @return float value in Fahrenheit + */ +float DHT::convertCtoF(float c) { return c * 1.8 + 32; } -float DHT::convertFtoC(float f) { - return (f - 32) * 0.55555; -} +/*! + * @brief Converts Fahrenheit to Celcius + * @param f + * value in Fahrenheit + * @return float value in Celcius + */ +float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; } +/*! + * @brief Read Humidity + * @param force + * force read mode + * @return float value - humidity in percent + */ float DHT::readHumidity(bool force) { float f = NAN; if (read(force)) { @@ -103,46 +160,71 @@ float DHT::readHumidity(bool force) { return f; } -//boolean isFahrenheit: True == Fahrenheit; False == Celcius +/*! + * @brief Compute Heat Index + * Simplified version that reads temp and humidity from sensor + * @param isFahrenheit + * true if fahrenheit, false if celcius (default + *true) + * @return float heat index + */ float DHT::computeHeatIndex(bool isFahrenheit) { float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(), - isFahrenheit); + isFahrenheit); return hi; } -//boolean isFahrenheit: True == Fahrenheit; False == Celcius +/*! + * @brief Compute Heat Index + * Using both Rothfusz and Steadman's equations + * (http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml) + * @param temperature + * temperature in selected scale + * @param percentHumidity + * humidity in percent + * @param isFahrenheit + * true if fahrenheit, false if celcius + * @return float heat index + */ float DHT::computeHeatIndex(float temperature, float percentHumidity, - bool isFahrenheit) { - // Using both Rothfusz and Steadman's equations - // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml + bool isFahrenheit) { float hi; if (!isFahrenheit) temperature = convertCtoF(temperature); - hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094)); + hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + + (percentHumidity * 0.094)); if (hi > 79) { - hi = -42.379 + - 2.04901523 * temperature + - 10.14333127 * percentHumidity + - -0.22475541 * temperature*percentHumidity + - -0.00683783 * pow(temperature, 2) + - -0.05481717 * pow(percentHumidity, 2) + - 0.00122874 * pow(temperature, 2) * percentHumidity + - 0.00085282 * temperature*pow(percentHumidity, 2) + - -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2); + hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity + + -0.22475541 * temperature * percentHumidity + + -0.00683783 * pow(temperature, 2) + + -0.05481717 * pow(percentHumidity, 2) + + 0.00122874 * pow(temperature, 2) * percentHumidity + + 0.00085282 * temperature * pow(percentHumidity, 2) + + -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2); - if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0)) - hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882); + if ((percentHumidity < 13) && (temperature >= 80.0) && + (temperature <= 112.0)) + hi -= ((13.0 - percentHumidity) * 0.25) * + sqrt((17.0 - abs(temperature - 95.0)) * 0.05882); - else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0)) + else if ((percentHumidity > 85.0) && (temperature >= 80.0) && + (temperature <= 87.0)) hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2); } return isFahrenheit ? hi : convertFtoC(hi); } +/*! + * @brief Read value from sensor or return last one from less than two + *seconds. + * @param force + * true if using force mode + * @return float value + */ bool DHT::read(bool force) { // Check if sensor was read less than two seconds ago and return early // to use last reading. @@ -156,7 +238,7 @@ bool DHT::read(bool force) { data[0] = data[1] = data[2] = data[3] = data[4] = 0; #if defined(ESP8266) - yield(); // Handle WiFi / reset software watchdog + yield(); // Handle WiFi / reset software watchdog #endif // Send start signal. See DHT datasheet for full signal diagram: @@ -170,15 +252,15 @@ bool DHT::read(bool force) { // First set data line low for a period according to sensor type pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW); - switch(_type) { - case DHT22: - case DHT21: - delayMicroseconds(1100); // data sheet says "at least 1ms" - break; - case DHT11: - default: - delay(20); //data sheet says at least 18ms, 20ms just to be safe - break; + switch (_type) { + case DHT22: + case DHT21: + delayMicroseconds(1100); // data sheet says "at least 1ms" + break; + case DHT11: + default: + delay(20); // data sheet says at least 18ms, 20ms just to be safe + break; } uint32_t cycles[80]; @@ -214,29 +296,29 @@ bool DHT::read(bool force) { // then it's a 1. We measure the cycle count of the initial 50us low pulse // and use that to compare to the cycle count of the high pulse to determine // if the bit is a 0 (high state cycle count < low state cycle count), or a - // 1 (high state cycle count > low state cycle count). Note that for speed all - // the pulses are read into a array and then examined in a later step. - for (int i=0; i<80; i+=2) { - cycles[i] = expectPulse(LOW); - cycles[i+1] = expectPulse(HIGH); + // 1 (high state cycle count > low state cycle count). Note that for speed + // all the pulses are read into a array and then examined in a later step. + for (int i = 0; i < 80; i += 2) { + cycles[i] = expectPulse(LOW); + cycles[i + 1] = expectPulse(HIGH); } } // Timing critical code is now complete. // Inspect pulses and determine which ones are 0 (high state cycle count < low // state cycle count), or 1 (high state cycle count > low state cycle count). - for (int i=0; i<40; ++i) { - uint32_t lowCycles = cycles[2*i]; - uint32_t highCycles = cycles[2*i+1]; + for (int i = 0; i < 40; ++i) { + uint32_t lowCycles = cycles[2 * i]; + uint32_t highCycles = cycles[2 * i + 1]; if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) { DEBUG_PRINTLN(F("DHT timeout waiting for pulse.")); _lastresult = false; return _lastresult; } - data[i/8] <<= 1; + data[i / 8] <<= 1; // Now compare the low and high cycle times to see if the bit is a 0 or 1. if (highCycles > lowCycles) { // High cycles are greater than 50us low cycle count, must be a 1. - data[i/8] |= 1; + data[i / 8] |= 1; } // Else high cycles are less than (or equal to, a weird case) the 50us low // cycle count so this must be a zero. Nothing needs to be changed in the @@ -244,19 +326,23 @@ bool DHT::read(bool force) { } DEBUG_PRINTLN(F("Received from DHT:")); - DEBUG_PRINT(data[0], HEX); DEBUG_PRINT(F(", ")); - DEBUG_PRINT(data[1], HEX); DEBUG_PRINT(F(", ")); - DEBUG_PRINT(data[2], HEX); DEBUG_PRINT(F(", ")); - DEBUG_PRINT(data[3], HEX); DEBUG_PRINT(F(", ")); - DEBUG_PRINT(data[4], HEX); DEBUG_PRINT(F(" =? ")); + DEBUG_PRINT(data[0], HEX); + DEBUG_PRINT(F(", ")); + DEBUG_PRINT(data[1], HEX); + DEBUG_PRINT(F(", ")); + DEBUG_PRINT(data[2], HEX); + DEBUG_PRINT(F(", ")); + DEBUG_PRINT(data[3], HEX); + DEBUG_PRINT(F(", ")); + DEBUG_PRINT(data[4], HEX); + DEBUG_PRINT(F(" =? ")); DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX); // Check we read 40 bits and that the checksum matches. if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { _lastresult = true; return _lastresult; - } - else { + } else { DEBUG_PRINTLN(F("DHT checksum failure!")); _lastresult = false; return _lastresult; @@ -276,24 +362,24 @@ uint32_t DHT::expectPulse(bool level) { #else uint16_t count = 0; // To work fast enough on slower AVR boards #endif - // On AVR platforms use direct GPIO port access as it's much faster and better - // for catching pulses that are 10's of microseconds in length: - #ifdef __AVR - uint8_t portState = level ? _bit : 0; - while ((*portInputRegister(_port) & _bit) == portState) { - if (count++ >= _maxcycles) { - return TIMEOUT; // Exceeded timeout, fail. - } +// On AVR platforms use direct GPIO port access as it's much faster and better +// for catching pulses that are 10's of microseconds in length: +#ifdef __AVR + uint8_t portState = level ? _bit : 0; + while ((*portInputRegister(_port) & _bit) == portState) { + if (count++ >= _maxcycles) { + return TIMEOUT; // Exceeded timeout, fail. } - // Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266 - // right now, perhaps bugs in direct port access functions?). - #else - while (digitalRead(_pin) == level) { - if (count++ >= _maxcycles) { - return TIMEOUT; // Exceeded timeout, fail. - } + } +// Otherwise fall back to using digitalRead (this seems to be necessary on +// ESP8266 right now, perhaps bugs in direct port access functions?). +#else + while (digitalRead(_pin) == level) { + if (count++ >= _maxcycles) { + return TIMEOUT; // Exceeded timeout, fail. } - #endif + } +#endif return count; } diff --git a/DHT.h b/DHT.h index bff3bf3..7e3fc34 100644 --- a/DHT.h +++ b/DHT.h @@ -1,41 +1,49 @@ -/* DHT library +/*! + * @file DHT.h + * + * This is a library for DHT series of low cost temperature/humidity sensors. + * + * You must have Adafruit Unified Sensor Library library installed to use this class. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * Written by Adafruit Industries. + * + * MIT license, all text above must be included in any redistribution + */ -MIT license -written by Adafruit Industries -*/ #ifndef DHT_H #define DHT_H -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif +#include "Arduino.h" - -// Uncomment to enable printing out nice debug messages. +/* Uncomment to enable printing out nice debug messages. */ //#define DHT_DEBUG -// Define where debug output will be printed. -#define DEBUG_PRINTER Serial -// Setup debug printing macros. +#define DEBUG_PRINTER Serial /**< Define where debug output will be printed. */ + +/* Setup debug printing macros. */ #ifdef DHT_DEBUG #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } #else - #define DEBUG_PRINT(...) {} - #define DEBUG_PRINTLN(...) {} + #define DEBUG_PRINT(...) {} /**< Debug Print Placeholder if Debug is disabled */ + #define DEBUG_PRINTLN(...) {} /**< Debug Print Line Placeholder if Debug is disabled */ #endif -// Define types of sensors. -#define DHT11 11 -#define DHT12 12 -#define DHT22 22 -#define DHT21 21 -#define AM2301 21 - +/* Define types of sensors. */ +#define DHT11 11 /**< DHT TYPE 11 */ +#define DHT12 12 /**< DHY TYPE 12 */ +#define DHT22 22 /**< DHT TYPE 22 */ +#define DHT21 21 /**< DHT TYPE 21 */ +#define AM2301 21 /**< AM2301 */ +/*! + * @brief Class that stores state and functions for DHT + */ class DHT { public: DHT(uint8_t pin, uint8_t type, uint8_t count=6); @@ -64,6 +72,9 @@ class DHT { }; +/*! + * @brief Class that defines Interrupt Lock Avaiability + */ class InterruptLock { public: InterruptLock() { diff --git a/DHT_U.h b/DHT_U.h index fcf66ad..52ca16d 100644 --- a/DHT_U.h +++ b/DHT_U.h @@ -1,68 +1,84 @@ -// DHT Temperature & Humidity Unified Sensor Library -// Copyright (c) 2014 Adafruit Industries -// Author: Tony DiCola +/*! + * @file DHT_U.h + * + * DHT Temperature & Humidity Unified Sensor Library + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * Written by Tony DiCola (Adafruit Industries) 2014. + * + * MIT license, all text above must be included in any redistribution + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. #ifndef DHT_U_H #define DHT_U_H #include #include -#define DHT_SENSOR_VERSION 1 +#define DHT_SENSOR_VERSION 1 /**< Sensor Version */ +/*! + * @brief Class that stores state and functions for interacting with + * DHT_Unified. + */ class DHT_Unified { public: - DHT_Unified(uint8_t pin, uint8_t type, uint8_t count=6, int32_t tempSensorId=-1, int32_t humiditySensorId=-1); + DHT_Unified(uint8_t pin, uint8_t type, uint8_t count = 6, + int32_t tempSensorId = -1, int32_t humiditySensorId = -1); void begin(); + /*! + * @brief Class that stores state and functions about Temperature + */ class Temperature : public Adafruit_Sensor { public: - Temperature(DHT_Unified* parent, int32_t id); - bool getEvent(sensors_event_t* event); - void getSensor(sensor_t* sensor); + Temperature(DHT_Unified *parent, int32_t id); + bool getEvent(sensors_event_t *event); + void getSensor(sensor_t *sensor); private: - DHT_Unified* _parent; + DHT_Unified *_parent; int32_t _id; - }; + /*! + * @brief Class that stores state and functions about Humidity + */ class Humidity : public Adafruit_Sensor { public: - Humidity(DHT_Unified* parent, int32_t id); - bool getEvent(sensors_event_t* event); - void getSensor(sensor_t* sensor); + Humidity(DHT_Unified *parent, int32_t id); + bool getEvent(sensors_event_t *event); + void getSensor(sensor_t *sensor); private: - DHT_Unified* _parent; + DHT_Unified *_parent; int32_t _id; - }; - Temperature temperature() { - return _temp; - } + Temperature temperature() { return _temp; } - Humidity humidity() { - return _humidity; - } + Humidity humidity() { return _humidity; } private: DHT _dht; @@ -70,9 +86,8 @@ private: Temperature _temp; Humidity _humidity; - void setName(sensor_t* sensor); - void setMinDelay(sensor_t* sensor); - + void setName(sensor_t *sensor); + void setMinDelay(sensor_t *sensor); }; #endif