From 57ebd8cbd371d493f1cd420a519e2f9b5b629b2e Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 13 Jul 2021 16:25:32 +0200 Subject: [PATCH] Converted to C++ and esp-idf --- CMakeLists.txt | 34 ++++++++++++ DHT.cpp | 120 +++++++++++++++++++++++------------------- DHT.h | 13 +++-- DHT_U.cpp | 140 ++++++++++++++++++++++++++----------------------- DHT_U.h | 8 +-- 5 files changed, 188 insertions(+), 127 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2067b9a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,34 @@ +set(headers + DHT.h + DHT_U.h +) + +set(sources + DHT.cpp + DHT_U.cpp +) + +set(dependencies + arduino-esp32 + Adafruit_Sensor +) + +idf_component_register( + INCLUDE_DIRS + . + SRCS + ${headers} + ${sources} + REQUIRES + ${dependencies} +) + +target_compile_options(${COMPONENT_TARGET} + PRIVATE + -fstack-reuse=all + -fstack-protector-all + -Wno-unused-function + -Wno-deprecated-declarations + -Wno-missing-field-initializers + -Wno-parentheses +) diff --git a/DHT.cpp b/DHT.cpp index b364612..6143a83 100644 --- a/DHT.cpp +++ b/DHT.cpp @@ -66,7 +66,7 @@ void DHT::begin(uint8_t usec) { // Using this value makes sure that millis() - lastreadtime will be // >= MIN_INTERVAL right away. Note that this assignment wraps around, // but so will the subtraction. - _lastreadtime = millis() - MIN_INTERVAL; + _lastreadtime = espchrono::millis_clock::now() - std::chrono::milliseconds{MIN_INTERVAL}; DEBUG_PRINT("DHT max clock cycles: "); DEBUG_PRINTLN(_maxcycles, DEC); pullTime = usec; @@ -82,44 +82,48 @@ void DHT::begin(uint8_t usec) { * true if in force mode * @return Temperature value in selected scale */ -float DHT::readTemperature(bool S, bool force) { +std::optional DHT::readTemperature(bool S, bool force) { + if (!read(force)) + return std::nullopt; + float f = NAN; - if (read(force)) { - switch (_type) { - case DHT11: - f = data[2]; - if (data[3] & 0x80) { - f = -1 - f; - } - f += (data[3] & 0x0f) * 0.1; - if (S) { - f = convertCtoF(f); - } - break; - case DHT12: - f = data[2]; - f += (data[3] & 0x0f) * 0.1; - if (data[2] & 0x80) { - f *= -1; - } - if (S) { - f = convertCtoF(f); - } - break; - case DHT22: - case DHT21: - f = ((word)(data[2] & 0x7F)) << 8 | data[3]; - f *= 0.1; - if (data[2] & 0x80) { - f *= -1; - } - if (S) { - f = convertCtoF(f); - } - break; + switch (_type) { + case DHT11: + f = data[2]; + if (data[3] & 0x80) { + f = -1 - f; } + f += (data[3] & 0x0f) * 0.1; + if (S) { + f = convertCtoF(f); + } + break; + case DHT12: + f = data[2]; + f += (data[3] & 0x0f) * 0.1; + if (data[2] & 0x80) { + f *= -1; + } + if (S) { + f = convertCtoF(f); + } + break; + case DHT22: + case DHT21: + f = ((word)(data[2] & 0x7F)) << 8 | data[3]; + f *= 0.1; + if (data[2] & 0x80) { + f *= -1; + } + if (S) { + f = convertCtoF(f); + } + break; + default: + return std::nullopt; } + return f; } @@ -145,20 +149,23 @@ float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; } * force read mode * @return float value - humidity in percent */ -float DHT::readHumidity(bool force) { +std::optional DHT::readHumidity(bool force) { + if (!read(force)) + return std::nullopt; + float f = NAN; - if (read(force)) { - switch (_type) { - case DHT11: - case DHT12: - f = data[0] + data[1] * 0.1; - break; - case DHT22: - case DHT21: - f = ((word)data[0]) << 8 | data[1]; - f *= 0.1; - break; - } + switch (_type) { + case DHT11: + case DHT12: + f = data[0] + data[1] * 0.1; + break; + case DHT22: + case DHT21: + f = ((word)data[0]) << 8 | data[1]; + f *= 0.1; + break; + default: + return std::nullopt; } return f; } @@ -171,9 +178,16 @@ float DHT::readHumidity(bool force) { *(default true) * @return float heat index */ -float DHT::computeHeatIndex(bool isFahrenheit) { - float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(), - isFahrenheit); +std::optional DHT::computeHeatIndex(bool isFahrenheit) { + const auto temperature = readTemperature(isFahrenheit); + if (!temperature) + return std::nullopt; + + const auto humidity = readHumidity(); + if (!humidity) + return std::nullopt; + + float hi = computeHeatIndex(*temperature, *humidity, isFahrenheit); return hi; } @@ -231,8 +245,8 @@ float DHT::computeHeatIndex(float temperature, float percentHumidity, bool DHT::read(bool force) { // Check if sensor was read less than two seconds ago and return early // to use last reading. - uint32_t currenttime = millis(); - if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) { + espchrono::millis_clock::time_point currenttime = espchrono::millis_clock::now(); + if (!force && ((currenttime - _lastreadtime) < std::chrono::milliseconds{MIN_INTERVAL})) { return _lastresult; // return last correct measurement } _lastreadtime = currenttime; diff --git a/DHT.h b/DHT.h index d22c276..40f620c 100644 --- a/DHT.h +++ b/DHT.h @@ -20,6 +20,10 @@ #include "Arduino.h" +#include + +#include + /* Uncomment to enable printing out nice debug messages. */ //#define DHT_DEBUG @@ -64,13 +68,13 @@ class DHT { public: DHT(uint8_t pin, uint8_t type, uint8_t count = 6); void begin(uint8_t usec = 55); - float readTemperature(bool S = false, bool force = false); + std::optional readTemperature(bool S = false, bool force = false); float convertCtoF(float); float convertFtoC(float); - float computeHeatIndex(bool isFahrenheit = true); + std::optional computeHeatIndex(bool isFahrenheit = true); float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true); - float readHumidity(bool force = false); + std::optional readHumidity(bool force = false); bool read(bool force = false); private: @@ -82,7 +86,8 @@ private: // digitalRead. uint8_t _bit, _port; #endif - uint32_t _lastreadtime, _maxcycles; + espchrono::millis_clock::time_point _lastreadtime; + uint32_t _maxcycles; bool _lastresult; uint8_t pullTime; // Time (in usec) to pull up data line before reading diff --git a/DHT_U.cpp b/DHT_U.cpp index 4182ed9..2770247 100644 --- a/DHT_U.cpp +++ b/DHT_U.cpp @@ -14,6 +14,8 @@ */ #include "DHT_U.h" +#include + /*! * @brief Instantiates a new DHT_Unified class * @param pin @@ -107,62 +109,65 @@ DHT_Unified::Temperature::Temperature(DHT_Unified *parent, int32_t id) * @param event * @return always returns true */ -bool DHT_Unified::Temperature::getEvent(sensors_event_t *event) { - // Clear event definition. - memset(event, 0, sizeof(sensors_event_t)); - // Populate sensor reading values. - event->version = sizeof(sensors_event_t); - event->sensor_id = _id; - event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; - event->timestamp = millis(); - event->temperature = _parent->_dht.readTemperature(); +std::optional DHT_Unified::Temperature::getEvent() { + const auto temperature = _parent->_dht.readTemperature(); + if (!temperature) + return std::nullopt; - return true; + sensors_event_t event; + // Populate sensor reading values. + event.version = sizeof(sensors_event_t); + event.sensor_id = _id; + event.type = SENSOR_TYPE_AMBIENT_TEMPERATURE; + event.timestamp = espchrono::millis_clock::now(); + event.temperature = *temperature; + + return event; } /*! * @brief Provides the sensor_t data for this sensor * @param sensor */ -void DHT_Unified::Temperature::getSensor(sensor_t *sensor) { - // Clear sensor definition. - memset(sensor, 0, sizeof(sensor_t)); +sensor_t DHT_Unified::Temperature::getSensor() { + sensor_t sensor; // Set sensor name. - _parent->setName(sensor); + _parent->setName(&sensor); // Set version and ID - sensor->version = DHT_SENSOR_VERSION; - sensor->sensor_id = _id; + sensor.version = DHT_SENSOR_VERSION; + sensor.sensor_id = _id; // Set type and characteristics. - sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; - _parent->setMinDelay(sensor); + sensor.type = SENSOR_TYPE_AMBIENT_TEMPERATURE; + _parent->setMinDelay(&sensor); switch (_parent->_type) { case DHT11: - sensor->max_value = 50.0F; - sensor->min_value = 0.0F; - sensor->resolution = 2.0F; + sensor.max_value = 50.0F; + sensor.min_value = 0.0F; + sensor.resolution = 2.0F; break; case DHT12: - sensor->max_value = 60.0F; - sensor->min_value = -20.0F; - sensor->resolution = 0.5F; + sensor.max_value = 60.0F; + sensor.min_value = -20.0F; + sensor.resolution = 0.5F; break; case DHT21: - sensor->max_value = 80.0F; - sensor->min_value = -40.0F; - sensor->resolution = 0.1F; + sensor.max_value = 80.0F; + sensor.min_value = -40.0F; + sensor.resolution = 0.1F; break; case DHT22: - sensor->max_value = 125.0F; - sensor->min_value = -40.0F; - sensor->resolution = 0.1F; + sensor.max_value = 125.0F; + sensor.min_value = -40.0F; + sensor.resolution = 0.1F; break; default: // Unknown type, default to 0. - sensor->max_value = 0.0F; - sensor->min_value = 0.0F; - sensor->resolution = 0.0F; + sensor.max_value = 0.0F; + sensor.min_value = 0.0F; + sensor.resolution = 0.0F; break; } + return sensor; } /*! @@ -180,60 +185,63 @@ DHT_Unified::Humidity::Humidity(DHT_Unified *parent, int32_t id) * @param event * @return always returns true */ -bool DHT_Unified::Humidity::getEvent(sensors_event_t *event) { - // Clear event definition. - memset(event, 0, sizeof(sensors_event_t)); - // Populate sensor reading values. - event->version = sizeof(sensors_event_t); - event->sensor_id = _id; - event->type = SENSOR_TYPE_RELATIVE_HUMIDITY; - event->timestamp = millis(); - event->relative_humidity = _parent->_dht.readHumidity(); +std::optional DHT_Unified::Humidity::getEvent() { + const auto humidity = _parent->_dht.readHumidity(); + if (!humidity) + return std::nullopt; - return true; + sensors_event_t event; + // Populate sensor reading values. + event.version = sizeof(sensors_event_t); + event.sensor_id = _id; + event.type = SENSOR_TYPE_RELATIVE_HUMIDITY; + event.timestamp = espchrono::millis_clock::now(); + event.relative_humidity = *humidity; + + return event; } /*! * @brief Provides the sensor_t data for this sensor * @param sensor */ -void DHT_Unified::Humidity::getSensor(sensor_t *sensor) { - // Clear sensor definition. - memset(sensor, 0, sizeof(sensor_t)); +sensor_t DHT_Unified::Humidity::getSensor() { + sensor_t sensor; // Set sensor name. - _parent->setName(sensor); + _parent->setName(&sensor); // Set version and ID - sensor->version = DHT_SENSOR_VERSION; - sensor->sensor_id = _id; + sensor.version = DHT_SENSOR_VERSION; + sensor.sensor_id = _id; // Set type and characteristics. - sensor->type = SENSOR_TYPE_RELATIVE_HUMIDITY; - _parent->setMinDelay(sensor); + sensor.type = SENSOR_TYPE_RELATIVE_HUMIDITY; + _parent->setMinDelay(&sensor); switch (_parent->_type) { case DHT11: - sensor->max_value = 80.0F; - sensor->min_value = 20.0F; - sensor->resolution = 5.0F; + sensor.max_value = 80.0F; + sensor.min_value = 20.0F; + sensor.resolution = 5.0F; break; case DHT12: - sensor->max_value = 95.0F; - sensor->min_value = 20.0F; - sensor->resolution = 5.0F; + sensor.max_value = 95.0F; + sensor.min_value = 20.0F; + sensor.resolution = 5.0F; break; case DHT21: - sensor->max_value = 100.0F; - sensor->min_value = 0.0F; - sensor->resolution = 0.1F; + sensor.max_value = 100.0F; + sensor.min_value = 0.0F; + sensor.resolution = 0.1F; break; case DHT22: - sensor->max_value = 100.0F; - sensor->min_value = 0.0F; - sensor->resolution = 0.1F; + sensor.max_value = 100.0F; + sensor.min_value = 0.0F; + sensor.resolution = 0.1F; break; default: // Unknown type, default to 0. - sensor->max_value = 0.0F; - sensor->min_value = 0.0F; - sensor->resolution = 0.0F; + sensor.max_value = 0.0F; + sensor.min_value = 0.0F; + sensor.resolution = 0.0F; break; } + return sensor; } diff --git a/DHT_U.h b/DHT_U.h index 3d4ba83..47b71dd 100644 --- a/DHT_U.h +++ b/DHT_U.h @@ -54,8 +54,8 @@ public: class Temperature : public Adafruit_Sensor { public: Temperature(DHT_Unified *parent, int32_t id); - bool getEvent(sensors_event_t *event); - void getSensor(sensor_t *sensor); + std::optional getEvent() override; + sensor_t getSensor() override; private: DHT_Unified *_parent; @@ -68,8 +68,8 @@ public: class Humidity : public Adafruit_Sensor { public: Humidity(DHT_Unified *parent, int32_t id); - bool getEvent(sensors_event_t *event); - void getSensor(sensor_t *sensor); + std::optional getEvent() override; + sensor_t getSensor() override; private: DHT_Unified *_parent;