From f92231dbffcfcb67508ab44fca4b11eef90519eb Mon Sep 17 00:00:00 2001 From: Roald Batts Date: Wed, 28 Dec 2022 22:38:38 -0500 Subject: [PATCH] adding the adafruit DHT library --- Adafruit_Unified_Sensor/Adafruit_Sensor.cpp | 87 ++++ Adafruit_Unified_Sensor/Adafruit_Sensor.h | 196 +++++++++ Adafruit_Unified_Sensor/LICENSE.txt | 202 +++++++++ Adafruit_Unified_Sensor/README.md | 239 +++++++++++ .../examples/sensortest/sensortest.ino | 153 +++++++ Adafruit_Unified_Sensor/library.properties | 11 + DHT_sensor_library/CONTRIBUTING.md | 13 + DHT_sensor_library/DHT.cpp | 390 ++++++++++++++++++ DHT_sensor_library/DHT.h | 109 +++++ DHT_sensor_library/DHT_U.cpp | 239 +++++++++++ DHT_sensor_library/DHT_U.h | 101 +++++ DHT_sensor_library/README.md | 58 +++ DHT_sensor_library/code-of-conduct.md | 127 ++++++ .../DHT_Unified_Sensor/DHT_Unified_Sensor.ino | 85 ++++ .../examples/DHTtester/DHTtester.ino | 74 ++++ DHT_sensor_library/keywords.txt | 22 + DHT_sensor_library/library.properties | 10 + DHT_sensor_library/license.txt | 20 + 18 files changed, 2136 insertions(+) create mode 100644 Adafruit_Unified_Sensor/Adafruit_Sensor.cpp create mode 100644 Adafruit_Unified_Sensor/Adafruit_Sensor.h create mode 100644 Adafruit_Unified_Sensor/LICENSE.txt create mode 100644 Adafruit_Unified_Sensor/README.md create mode 100644 Adafruit_Unified_Sensor/examples/sensortest/sensortest.ino create mode 100644 Adafruit_Unified_Sensor/library.properties create mode 100644 DHT_sensor_library/CONTRIBUTING.md create mode 100644 DHT_sensor_library/DHT.cpp create mode 100644 DHT_sensor_library/DHT.h create mode 100644 DHT_sensor_library/DHT_U.cpp create mode 100644 DHT_sensor_library/DHT_U.h create mode 100644 DHT_sensor_library/README.md create mode 100644 DHT_sensor_library/code-of-conduct.md create mode 100644 DHT_sensor_library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino create mode 100644 DHT_sensor_library/examples/DHTtester/DHTtester.ino create mode 100644 DHT_sensor_library/keywords.txt create mode 100644 DHT_sensor_library/library.properties create mode 100644 DHT_sensor_library/license.txt diff --git a/Adafruit_Unified_Sensor/Adafruit_Sensor.cpp b/Adafruit_Unified_Sensor/Adafruit_Sensor.cpp new file mode 100644 index 0000000..a5a6d4e --- /dev/null +++ b/Adafruit_Unified_Sensor/Adafruit_Sensor.cpp @@ -0,0 +1,87 @@ +#include "Adafruit_Sensor.h" + +/**************************************************************************/ +/*! + @brief Prints sensor information to serial console +*/ +/**************************************************************************/ +void Adafruit_Sensor::printSensorDetails(void) { + sensor_t sensor; + getSensor(&sensor); + Serial.println(F("------------------------------------")); + Serial.print(F("Sensor: ")); + Serial.println(sensor.name); + Serial.print(F("Type: ")); + switch ((sensors_type_t)sensor.type) { + case SENSOR_TYPE_ACCELEROMETER: + Serial.print(F("Acceleration (m/s2)")); + break; + case SENSOR_TYPE_MAGNETIC_FIELD: + Serial.print(F("Magnetic (uT)")); + break; + case SENSOR_TYPE_ORIENTATION: + Serial.print(F("Orientation (degrees)")); + break; + case SENSOR_TYPE_GYROSCOPE: + Serial.print(F("Gyroscopic (rad/s)")); + break; + case SENSOR_TYPE_LIGHT: + Serial.print(F("Light (lux)")); + break; + case SENSOR_TYPE_PRESSURE: + Serial.print(F("Pressure (hPa)")); + break; + case SENSOR_TYPE_PROXIMITY: + Serial.print(F("Distance (cm)")); + break; + case SENSOR_TYPE_GRAVITY: + Serial.print(F("Gravity (m/s2)")); + break; + case SENSOR_TYPE_LINEAR_ACCELERATION: + Serial.print(F("Linear Acceleration (m/s2)")); + break; + case SENSOR_TYPE_ROTATION_VECTOR: + Serial.print(F("Rotation vector")); + break; + case SENSOR_TYPE_RELATIVE_HUMIDITY: + Serial.print(F("Relative Humidity (%)")); + break; + case SENSOR_TYPE_AMBIENT_TEMPERATURE: + Serial.print(F("Ambient Temp (C)")); + break; + case SENSOR_TYPE_OBJECT_TEMPERATURE: + Serial.print(F("Object Temp (C)")); + break; + case SENSOR_TYPE_VOLTAGE: + Serial.print(F("Voltage (V)")); + break; + case SENSOR_TYPE_CURRENT: + Serial.print(F("Current (mA)")); + break; + case SENSOR_TYPE_COLOR: + Serial.print(F("Color (RGBA)")); + break; + case SENSOR_TYPE_TVOC: + Serial.print(F("Total Volatile Organic Compounds (ppb)")); + break; + case SENSOR_TYPE_VOC_INDEX: + Serial.print(F("Volatile Organic Compounds (Index)")); + break; + case SENSOR_TYPE_NOX_INDEX: + Serial.print(F("Nitrogen Oxides (Index)")); + break; + } + + Serial.println(); + Serial.print(F("Driver Ver: ")); + Serial.println(sensor.version); + Serial.print(F("Unique ID: ")); + Serial.println(sensor.sensor_id); + Serial.print(F("Min Value: ")); + Serial.println(sensor.min_value); + Serial.print(F("Max Value: ")); + Serial.println(sensor.max_value); + Serial.print(F("Resolution: ")); + Serial.println(sensor.resolution); + Serial.println(F("------------------------------------\n")); +} diff --git a/Adafruit_Unified_Sensor/Adafruit_Sensor.h b/Adafruit_Unified_Sensor/Adafruit_Sensor.h new file mode 100644 index 0000000..b0169d8 --- /dev/null +++ b/Adafruit_Unified_Sensor/Adafruit_Sensor.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software< /span> + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and + * extended sensor support to include color, voltage and current */ + +#ifndef _ADAFRUIT_SENSOR_H +#define _ADAFRUIT_SENSOR_H + +#ifndef ARDUINO +#include +#elif ARDUINO >= 100 +#include "Arduino.h" +#include "Print.h" +#else +#include "WProgram.h" +#endif + +/* Constants */ +#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */ +#define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */ +#define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */ +#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH) +#define SENSORS_MAGFIELD_EARTH_MAX \ + (60.0F) /**< Maximum magnetic field on Earth's surface */ +#define SENSORS_MAGFIELD_EARTH_MIN \ + (30.0F) /**< Minimum magnetic field on Earth's surface */ +#define SENSORS_PRESSURE_SEALEVELHPA \ + (1013.25F) /**< Average sea level pressure is 1013.25 hPa */ +#define SENSORS_DPS_TO_RADS \ + (0.017453293F) /**< Degrees/s to rad/s multiplier \ + */ +#define SENSORS_RADS_TO_DPS \ + (57.29577793F) /**< Rad/s to degrees/s multiplier */ +#define SENSORS_GAUSS_TO_MICROTESLA \ + (100) /**< Gauss to micro-Tesla multiplier */ + +/** Sensor types */ +typedef enum { + SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */ + SENSOR_TYPE_MAGNETIC_FIELD = (2), + SENSOR_TYPE_ORIENTATION = (3), + SENSOR_TYPE_GYROSCOPE = (4), + SENSOR_TYPE_LIGHT = (5), + SENSOR_TYPE_PRESSURE = (6), + SENSOR_TYPE_PROXIMITY = (8), + SENSOR_TYPE_GRAVITY = (9), + SENSOR_TYPE_LINEAR_ACCELERATION = + (10), /**< Acceleration not including gravity */ + SENSOR_TYPE_ROTATION_VECTOR = (11), + SENSOR_TYPE_RELATIVE_HUMIDITY = (12), + SENSOR_TYPE_AMBIENT_TEMPERATURE = (13), + SENSOR_TYPE_OBJECT_TEMPERATURE = (14), + SENSOR_TYPE_VOLTAGE = (15), + SENSOR_TYPE_CURRENT = (16), + SENSOR_TYPE_COLOR = (17), + SENSOR_TYPE_TVOC = (18), + SENSOR_TYPE_VOC_INDEX = (19), + SENSOR_TYPE_NOX_INDEX = (20) +} sensors_type_t; + +/** struct sensors_vec_s is used to return a vector in a common format. */ +typedef struct { + union { + float v[3]; ///< 3D vector elements + struct { + float x; ///< X component of vector + float y; ///< Y component of vector + float z; ///< Z component of vector + }; ///< Struct for holding XYZ component + /* Orientation sensors */ + struct { + float roll; /**< Rotation around the longitudinal axis (the plane body, 'X + axis'). Roll is positive and increasing when moving + downward. -90 degrees <= roll <= 90 degrees */ + float pitch; /**< Rotation around the lateral axis (the wing span, 'Y + axis'). Pitch is positive and increasing when moving + upwards. -180 degrees <= pitch <= 180 degrees) */ + float heading; /**< Angle between the longitudinal axis (the plane body) + and magnetic north, measured clockwise when viewing from + the top of the device. 0-359 degrees */ + }; ///< Struct for holding roll/pitch/heading + }; ///< Union that can hold 3D vector array, XYZ components or + ///< roll/pitch/heading + int8_t status; ///< Status byte + uint8_t reserved[3]; ///< Reserved +} sensors_vec_t; + +/** struct sensors_color_s is used to return color data in a common format. */ +typedef struct { + union { + float c[3]; ///< Raw 3-element data + /* RGB color space */ + struct { + float r; /**< Red component */ + float g; /**< Green component */ + float b; /**< Blue component */ + }; ///< RGB data in floating point notation + }; ///< Union of various ways to describe RGB colorspace + uint32_t rgba; /**< 24-bit RGBA value */ +} sensors_color_t; + +/* Sensor event (36 bytes) */ +/** struct sensor_event_s is used to provide a single sensor event in a common + * format. */ +typedef struct { + int32_t version; /**< must be sizeof(struct sensors_event_t) */ + int32_t sensor_id; /**< unique sensor identifier */ + int32_t type; /**< sensor type */ + int32_t reserved0; /**< reserved */ + int32_t timestamp; /**< time is in milliseconds */ + union { + float data[4]; ///< Raw data + sensors_vec_t acceleration; /**< acceleration values are in meter per second + per second (m/s^2) */ + sensors_vec_t + magnetic; /**< magnetic vector values are in micro-Tesla (uT) */ + sensors_vec_t orientation; /**< orientation values are in degrees */ + sensors_vec_t gyro; /**< gyroscope values are in rad/s */ + float temperature; /**< temperature is in degrees centigrade (Celsius) */ + float distance; /**< distance in centimeters */ + float light; /**< light in SI lux units */ + float pressure; /**< pressure in hectopascal (hPa) */ + float relative_humidity; /**< relative humidity in percent */ + float current; /**< current in milliamps (mA) */ + float voltage; /**< voltage in volts (V) */ + float tvoc; /**< Total Volatile Organic Compounds, in ppb */ + float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is + normal (unitless) */ + float nox_index; /**< NOx (Nitrogen Oxides) index where 100 is normal + (unitless) */ + sensors_color_t color; /**< color in RGB component values */ + }; ///< Union for the wide ranges of data we can carry +} sensors_event_t; + +/* Sensor details (40 bytes) */ +/** struct sensor_s is used to describe basic information about a specific + * sensor. */ +typedef struct { + char name[12]; /**< sensor name */ + int32_t version; /**< version of the hardware + driver */ + int32_t sensor_id; /**< unique sensor identifier */ + int32_t type; /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */ + float max_value; /**< maximum value of this sensor's value in SI units */ + float min_value; /**< minimum value of this sensor's value in SI units */ + float resolution; /**< smallest difference between two values reported by this + sensor */ + int32_t min_delay; /**< min delay in microseconds between events. zero = not a + constant rate */ +} sensor_t; + +/** @brief Common sensor interface to unify various sensors. + * Intentionally modeled after sensors.h in the Android API: + * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h + */ +class Adafruit_Sensor { +public: + // Constructor(s) + Adafruit_Sensor() {} + virtual ~Adafruit_Sensor() {} + + // These must be defined by the subclass + + /*! @brief Whether we should automatically change the range (if possible) for + higher precision + @param enabled True if we will try to autorange */ + virtual void enableAutoRange(bool enabled) { + (void)enabled; /* suppress unused warning */ + }; + + /*! @brief Get the latest sensor event + @returns True if able to fetch an event */ + virtual bool getEvent(sensors_event_t *) = 0; + /*! @brief Get info about the sensor itself */ + virtual void getSensor(sensor_t *) = 0; + + void printSensorDetails(void); + +private: + bool _autoRange; +}; + +#endif diff --git a/Adafruit_Unified_Sensor/LICENSE.txt b/Adafruit_Unified_Sensor/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Adafruit_Unified_Sensor/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Adafruit_Unified_Sensor/README.md b/Adafruit_Unified_Sensor/README.md new file mode 100644 index 0000000..1e87bed --- /dev/null +++ b/Adafruit_Unified_Sensor/README.md @@ -0,0 +1,239 @@ +# Adafruit Unified Sensor Driver # + +Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing. + +One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tomorrow, or system requirements may change and you may need to choose a different sensor down the road. + +Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement. + +By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor. This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse. + +The unified sensor abstraction layer is also useful for data-logging and data-transmission since you only have one well-known type to log or transmit over the air or wire. + +## Unified Sensor Drivers ## + +The following drivers are based on the Adafruit Unified Sensor Driver: + +**Accelerometers** + - [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345) + - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC) + - [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library) + +**Gyroscope** + - [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U) + +**Light** + - [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561) + - [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library) + +**Magnetometers** + - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC) + - [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified) + +**Barometric Pressure** + - [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified) + - [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library) + +**Humidity & Temperature** + - [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library) + +**Humidity, Temperature, & Barometric Pressure** + - [Adafruit_BME280_Library](https://github.com/adafruit/Adafruit_BME280_Library/) + +**Orientation** + - [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055) + +**All in one device** +- [Adafruit_LSM9DS0](https://github.com/adafruit/Adafruit_LSM9DS0_Library) (accelerometer, gyroscope, magnetometer) +- [Adafruit_LSM9DS1](https://github.com/adafruit/Adafruit_LSM9DS1/) (accelerometer, gyroscope, magnetometer) + + +## How Does it Work? ## + +Any driver that supports the Adafruit unified sensor abstraction layer will implement the Adafruit\_Sensor base class. There are two main typedefs and one enum defined in Adafruit_Sensor.h that are used to 'abstract' away the sensor details and values: + +## Sensor Types (`sensors_type_t`) + +These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc. + +```c++ +/** Sensor types */ +typedef enum +{ + SENSOR_TYPE_ACCELEROMETER = (1), + SENSOR_TYPE_MAGNETIC_FIELD = (2), + SENSOR_TYPE_ORIENTATION = (3), + SENSOR_TYPE_GYROSCOPE = (4), + SENSOR_TYPE_LIGHT = (5), + SENSOR_TYPE_PRESSURE = (6), + SENSOR_TYPE_PROXIMITY = (8), + SENSOR_TYPE_GRAVITY = (9), + SENSOR_TYPE_LINEAR_ACCELERATION = (10), + SENSOR_TYPE_ROTATION_VECTOR = (11), + SENSOR_TYPE_RELATIVE_HUMIDITY = (12), + SENSOR_TYPE_AMBIENT_TEMPERATURE = (13), + SENSOR_TYPE_VOLTAGE = (15), + SENSOR_TYPE_CURRENT = (16), + SENSOR_TYPE_COLOR = (17), + SENSOR_TYPE_TVOC = (18), + SENSOR_TYPE_VOC_INDEX = (19), + SENSOR_TYPE_NOX_INDEX = (20) +} sensors_type_t; +``` + +## Sensor Details (`sensor_t`) + +This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer. + +```c++ +/* Sensor details (40 bytes) */ +/** struct sensor_s is used to describe basic information about a specific sensor. */ +typedef struct +{ + char name[12]; + int32_t version; + int32_t sensor_id; + int32_t type; + float max_value; + float min_value; + float resolution; + int32_t min_delay; +} sensor_t; +``` + +The individual fields are intended to be used as follows: + +- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2") +- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver +- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network +- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h +- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit) +- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit) +- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit) +- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate + +## Sensor Data/Events (`sensors_event_t`) + +This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales. + +```c++ +/* Sensor event (36 bytes) */ +/** struct sensor_event_s is used to provide a single sensor event in a common format. */ +typedef struct +{ + int32_t version; + int32_t sensor_id; + int32_t type; + int32_t reserved0; + int32_t timestamp; + union + { + float data[4]; + sensors_vec_t acceleration; + sensors_vec_t magnetic; + sensors_vec_t orientation; + sensors_vec_t gyro; + float temperature; + float distance; + float light; + float pressure; + float relative_humidity; + float current; + float voltage; + float tvoc; + float voc_index; + float nox_index; + sensors_color_t color; + }; +} sensors_event_t; +``` +It includes the following fields: + +- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future +- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!) +- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h +- **timestamp**: time in milliseconds when the sensor value was read +- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below) + +## Required Functions + +In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions: + +```c++ +bool getEvent(sensors_event_t*); +``` +Calling this function will populate the supplied sensors\_event\_t reference with the latest available sensor data. You should call this function as often as you want to update your data. + +```c++ +void getSensor(sensor_t*); +``` +Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc. + +## Standardised SI values for `sensors_event_t` + +A key part of the abstraction layer is the standardisation of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above. This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales: + +- **acceleration**: values are in **meter per second per second** (m/s^2) +- **magnetic**: values are in **micro-Tesla** (uT) +- **orientation**: values are in **degrees** +- **gyro**: values are in **rad/s** +- **temperature**: values in **degrees centigrade** (Celsius) +- **distance**: values are in **centimeters** +- **light**: values are in **SI lux** units +- **pressure**: values are in **hectopascal** (hPa) +- **relative\_humidity**: values are in **percent** +- **current**: values are in **milliamps** (mA) +- **voltage**: values are in **volts** (V) +- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format +- **tvoc**: values are in **parts per billion** (ppb) +- **voc_index**: values are an **index** from 1-500 with 100 being normal +- **nox_index**: values are an **index** from 1-500 with 100 being normal + + +## The Unified Driver Abstraction Layer in Practice ## + +Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created. + +Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardised way of interrogating a sensor about its specific capabilities (via sensor\_t). + +An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below: + +```c++ + Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345); + ... + /* Get a new sensor event */ + sensors_event_t event; + tsl.getEvent(&event); + + /* Display the results (light is measured in lux) */ + if (event.light) + { + Serial.print(event.light); Serial.println(" lux"); + } + else + { + /* If event.light = 0 lux the sensor is probably saturated + and no reliable data could be generated! */ + Serial.println("Sensor overload"); + } +``` + +Similarly, we can get the basic technical capabilities of this sensor with the following code: + +```c++ + sensor_t sensor; + + sensor_t sensor; + tsl.getSensor(&sensor); + + /* Display the sensor details */ + Serial.println("------------------------------------"); + Serial.print ("Sensor: "); Serial.println(sensor.name); + Serial.print ("Driver Ver: "); Serial.println(sensor.version); + Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); + Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux"); + Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux"); + Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux"); + Serial.println("------------------------------------"); + Serial.println(""); +``` diff --git a/Adafruit_Unified_Sensor/examples/sensortest/sensortest.ino b/Adafruit_Unified_Sensor/examples/sensortest/sensortest.ino new file mode 100644 index 0000000..d87f60d --- /dev/null +++ b/Adafruit_Unified_Sensor/examples/sensortest/sensortest.ino @@ -0,0 +1,153 @@ +#include +#include +#include + +/* Assign a unique ID to this sensor at the same time */ +/* Uncomment following line for default Wire bus */ +Adafruit_ADXL343 accel = Adafruit_ADXL343(12345); + +/* NeoTrellis M4, etc. */ +/* Uncomment following line for Wire1 bus */ +//Adafruit_ADXL343 accel = Adafruit_ADXL343(12345, &Wire1); + +void displaySensorDetails(void) +{ + sensor_t sensor; + accel.getSensor(&sensor); + Serial.println("------------------------------------"); + Serial.print ("Sensor: "); Serial.println(sensor.name); + Serial.print ("Driver Ver: "); Serial.println(sensor.version); + Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); + Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" m/s^2"); + Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" m/s^2"); + Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" m/s^2"); + Serial.println("------------------------------------"); + Serial.println(""); + delay(500); +} + +void displayDataRate(void) +{ + Serial.print ("Data Rate: "); + + switch(accel.getDataRate()) + { + case ADXL343_DATARATE_3200_HZ: + Serial.print ("3200 "); + break; + case ADXL343_DATARATE_1600_HZ: + Serial.print ("1600 "); + break; + case ADXL343_DATARATE_800_HZ: + Serial.print ("800 "); + break; + case ADXL343_DATARATE_400_HZ: + Serial.print ("400 "); + break; + case ADXL343_DATARATE_200_HZ: + Serial.print ("200 "); + break; + case ADXL343_DATARATE_100_HZ: + Serial.print ("100 "); + break; + case ADXL343_DATARATE_50_HZ: + Serial.print ("50 "); + break; + case ADXL343_DATARATE_25_HZ: + Serial.print ("25 "); + break; + case ADXL343_DATARATE_12_5_HZ: + Serial.print ("12.5 "); + break; + case ADXL343_DATARATE_6_25HZ: + Serial.print ("6.25 "); + break; + case ADXL343_DATARATE_3_13_HZ: + Serial.print ("3.13 "); + break; + case ADXL343_DATARATE_1_56_HZ: + Serial.print ("1.56 "); + break; + case ADXL343_DATARATE_0_78_HZ: + Serial.print ("0.78 "); + break; + case ADXL343_DATARATE_0_39_HZ: + Serial.print ("0.39 "); + break; + case ADXL343_DATARATE_0_20_HZ: + Serial.print ("0.20 "); + break; + case ADXL343_DATARATE_0_10_HZ: + Serial.print ("0.10 "); + break; + default: + Serial.print ("???? "); + break; + } + Serial.println(" Hz"); +} + +void displayRange(void) +{ + Serial.print ("Range: +/- "); + + switch(accel.getRange()) + { + case ADXL343_RANGE_16_G: + Serial.print ("16 "); + break; + case ADXL343_RANGE_8_G: + Serial.print ("8 "); + break; + case ADXL343_RANGE_4_G: + Serial.print ("4 "); + break; + case ADXL343_RANGE_2_G: + Serial.print ("2 "); + break; + default: + Serial.print ("?? "); + break; + } + Serial.println(" g"); +} + +void setup(void) +{ + Serial.begin(9600); + while (!Serial); + Serial.println("Accelerometer Test"); Serial.println(""); + + /* Initialise the sensor */ + if(!accel.begin()) + { + /* There was a problem detecting the ADXL343 ... check your connections */ + Serial.println("Ooops, no ADXL343 detected ... Check your wiring!"); + while(1); + } + + /* Set the range to whatever is appropriate for your project */ + accel.setRange(ADXL343_RANGE_16_G); + // accel.setRange(ADXL343_RANGE_8_G); + // accel.setRange(ADXL343_RANGE_4_G); + // accel.setRange(ADXL343_RANGE_2_G); + + /* Display some basic information on this sensor */ + displaySensorDetails(); + displayDataRate(); + displayRange(); + Serial.println(""); +} + +void loop(void) +{ + /* Get a new sensor event */ + sensors_event_t event; + accel.getEvent(&event); + + /* Display the results (acceleration is measured in m/s^2) */ + Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" "); + Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" "); + Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(" ");Serial.println("m/s^2 "); + delay(500); +} diff --git a/Adafruit_Unified_Sensor/library.properties b/Adafruit_Unified_Sensor/library.properties new file mode 100644 index 0000000..019fd7a --- /dev/null +++ b/Adafruit_Unified_Sensor/library.properties @@ -0,0 +1,11 @@ +name=Adafruit Unified Sensor +version=1.1.7 +author=Adafruit +maintainer=Adafruit +sentence=Required for all Adafruit Unified Sensor based libraries. +paragraph=A unified sensor abstraction layer used by many Adafruit sensor libraries. +category=Sensors +url=https://github.com/adafruit/Adafruit_Sensor +architectures=* +includes=Adafruit_Sensor.h + diff --git a/DHT_sensor_library/CONTRIBUTING.md b/DHT_sensor_library/CONTRIBUTING.md new file mode 100644 index 0000000..3227bf9 --- /dev/null +++ b/DHT_sensor_library/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contribution Guidlines + +This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/adafruit/DHT-sensor-library/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community. + +The following are some guidelines to observe when creating issues or PRs: + +- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas + +- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets + +- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile: + +- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library diff --git a/DHT_sensor_library/DHT.cpp b/DHT_sensor_library/DHT.cpp new file mode 100644 index 0000000..a48ac74 --- /dev/null +++ b/DHT_sensor_library/DHT.cpp @@ -0,0 +1,390 @@ +/*! + * @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 /**< min interval value */ +#define TIMEOUT \ + UINT32_MAX /**< Used programmatically for timeout. \ + Not a timeout duration. Type: uint32_t. */ + +/*! + * @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) { + (void)count; // Workaround to avoid compiler warning. + _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. + // Note that count is now ignored as the DHT reading algorithm adjusts itself + // based on the speed of the processor. +} + +/*! + * @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); + // 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; + DEBUG_PRINT("DHT max clock cycles: "); + DEBUG_PRINTLN(_maxcycles, DEC); + pullTime = usec; +} + +/*! + * @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; + + 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; + } + } + return f; +} + +/*! + * @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; } + +/*! + * @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)) { + 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; + } + } + return f; +} + +/*! + * @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); + return hi; +} + +/*! + * @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) { + float hi; + + if (!isFahrenheit) + temperature = convertCtoF(temperature); + + 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); + + 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)) + 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. + uint32_t currenttime = millis(); + if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) { + return _lastresult; // return last correct measurement + } + _lastreadtime = currenttime; + + // Reset 40 bits of received data to zero. + data[0] = data[1] = data[2] = data[3] = data[4] = 0; + +#if defined(ESP8266) + yield(); // Handle WiFi / reset software watchdog +#endif + + // 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. + pinMode(_pin, INPUT_PULLUP); + delay(1); + + // 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; + } + + uint32_t cycles[80]; + { + // End the start signal by setting data line high for 40 microseconds. + pinMode(_pin, INPUT_PULLUP); + + // Delay a moment to let sensor pull data line low. + delayMicroseconds(pullTime); + + // Now start reading the data line to get the value from the DHT sensor. + + // Turn off interrupts temporarily because the next sections + // are timing critical and we don't want any interruptions. + InterruptLock lock; + + // First expect a low signal for ~80 microseconds followed by a high signal + // for ~80 microseconds again. + if (expectPulse(LOW) == TIMEOUT) { + DEBUG_PRINTLN(F("DHT timeout waiting for start signal low pulse.")); + _lastresult = false; + return _lastresult; + } + if (expectPulse(HIGH) == TIMEOUT) { + DEBUG_PRINTLN(F("DHT timeout waiting for start signal high pulse.")); + _lastresult = false; + return _lastresult; + } + + // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 + // microsecond low pulse followed by a variable length high pulse. If the + // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds + // 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); + } + } // 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]; + if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) { + DEBUG_PRINTLN(F("DHT timeout waiting for pulse.")); + _lastresult = false; + return _lastresult; + } + 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; + } + // 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 + // stored data. + } + + 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_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 { + DEBUG_PRINTLN(F("DHT checksum failure!")); + _lastresult = false; + return _lastresult; + } +} + +// Expect the signal line to be at the specified level for a period of time and +// return a count of loop cycles spent at that level (this cycle count can be +// used to compare the relative time of two pulses). If more than a millisecond +// ellapses without the level changing then the call fails with a 0 response. +// This is adapted from Arduino's pulseInLong function (which is only available +// in the very latest IDE versions): +// https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c +uint32_t DHT::expectPulse(bool level) { +// F_CPU is not be known at compile time on platforms such as STM32F103. +// The preprocessor seems to evaluate it to zero in that case. +#if (F_CPU > 16000000L) || (F_CPU == 0L) + uint32_t count = 0; +#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. + } + } +// 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 + + return count; +} diff --git a/DHT_sensor_library/DHT.h b/DHT_sensor_library/DHT.h new file mode 100644 index 0000000..95570e1 --- /dev/null +++ b/DHT_sensor_library/DHT.h @@ -0,0 +1,109 @@ +/*! + * @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 + */ + +#ifndef DHT_H +#define DHT_H + +#include "Arduino.h" + +/* Uncomment to enable printing out nice debug messages. */ +//#define DHT_DEBUG + +#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(...) \ + {} /**< Debug Print Placeholder if Debug is disabled */ +#define DEBUG_PRINTLN(...) \ + {} /**< Debug Print Line Placeholder if Debug is disabled */ +#endif + +/* Define types of sensors. */ +static const uint8_t DHT11{11}; /**< DHT TYPE 11 */ +static const uint8_t DHT12{12}; /**< DHY TYPE 12 */ +static const uint8_t DHT21{21}; /**< DHT TYPE 21 */ +static const uint8_t DHT22{22}; /**< DHT TYPE 22 */ +static const uint8_t AM2301{21}; /**< AM2301 */ + +#if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE) +#ifndef microsecondsToClockCycles +/*! + * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have + * microsecondsToClockCycles defined. + */ +#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L)) +#endif +#endif + +/*! + * @brief Class that stores state and functions for DHT + */ +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); + float convertCtoF(float); + float convertFtoC(float); + float computeHeatIndex(bool isFahrenheit = true); + float computeHeatIndex(float temperature, float percentHumidity, + bool isFahrenheit = true); + float readHumidity(bool force = false); + bool read(bool force = false); + +private: + uint8_t data[5]; + uint8_t _pin, _type; +#ifdef __AVR + // Use direct GPIO access on an 8-bit AVR so keep track of the port and + // bitmask for the digital pin connected to the DHT. Other platforms will use + // digitalRead. + uint8_t _bit, _port; +#endif + uint32_t _lastreadtime, _maxcycles; + bool _lastresult; + uint8_t pullTime; // Time (in usec) to pull up data line before reading + + uint32_t expectPulse(bool level); +}; + +/*! + * @brief Class that defines Interrupt Lock Avaiability + */ +class InterruptLock { +public: + InterruptLock() { +#if !defined(ARDUINO_ARCH_NRF52) + noInterrupts(); +#endif + } + ~InterruptLock() { +#if !defined(ARDUINO_ARCH_NRF52) + interrupts(); +#endif + } +}; + +#endif diff --git a/DHT_sensor_library/DHT_U.cpp b/DHT_sensor_library/DHT_U.cpp new file mode 100644 index 0000000..4182ed9 --- /dev/null +++ b/DHT_sensor_library/DHT_U.cpp @@ -0,0 +1,239 @@ +/*! + * @file DHT_U.cpp + * + * Temperature & Humidity Unified Sensor Library + * + * 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! + */ +#include "DHT_U.h" + +/*! + * @brief Instantiates a new DHT_Unified class + * @param pin + * pin number that sensor is connected + * @param type + * type of sensor + * @param count + * number of sensors + * @param tempSensorId + * temperature sensor id + * @param humiditySensorId + * humidity sensor id + */ +DHT_Unified::DHT_Unified(uint8_t pin, uint8_t type, uint8_t count, + int32_t tempSensorId, int32_t humiditySensorId) + : _dht(pin, type, count), _type(type), _temp(this, tempSensorId), + _humidity(this, humiditySensorId) {} + +/*! + * @brief Setup sensor (calls begin on It) + */ +void DHT_Unified::begin() { _dht.begin(); } + +/*! + * @brief Sets sensor name + * @param sensor + * Sensor that will be set + */ +void DHT_Unified::setName(sensor_t *sensor) { + switch (_type) { + case DHT11: + strncpy(sensor->name, "DHT11", sizeof(sensor->name) - 1); + break; + case DHT12: + strncpy(sensor->name, "DHT12", sizeof(sensor->name) - 1); + break; + case DHT21: + strncpy(sensor->name, "DHT21", sizeof(sensor->name) - 1); + break; + case DHT22: + strncpy(sensor->name, "DHT22", sizeof(sensor->name) - 1); + break; + default: + // TODO: Perhaps this should be an error? However main DHT library doesn't + // enforce restrictions on the sensor type value. Pick a generic name for + // now. + strncpy(sensor->name, "DHT?", sizeof(sensor->name) - 1); + break; + } + sensor->name[sizeof(sensor->name) - 1] = 0; +} + +/*! + * @brief Sets Minimum Delay Value + * @param sensor + * Sensor that will be set + */ +void DHT_Unified::setMinDelay(sensor_t *sensor) { + switch (_type) { + case DHT11: + sensor->min_delay = 1000000L; // 1 second (in microseconds) + break; + case DHT12: + sensor->min_delay = 2000000L; // 2 second (in microseconds) + break; + case DHT21: + sensor->min_delay = 2000000L; // 2 seconds (in microseconds) + break; + case DHT22: + sensor->min_delay = 2000000L; // 2 seconds (in microseconds) + break; + default: + // Default to slowest sample rate in case of unknown type. + sensor->min_delay = 2000000L; // 2 seconds (in microseconds) + break; + } +} + +/*! + * @brief Instantiates a new DHT_Unified Temperature Class + * @param parent + * Parent Sensor + * @param id + * Sensor id + */ +DHT_Unified::Temperature::Temperature(DHT_Unified *parent, int32_t id) + : _parent(parent), _id(id) {} + +/*! + * @brief Reads the sensor and returns the data as a sensors_event_t + * @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(); + + return true; +} + +/*! + * @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)); + // Set sensor name. + _parent->setName(sensor); + // Set version and ID + sensor->version = DHT_SENSOR_VERSION; + sensor->sensor_id = _id; + // Set type and characteristics. + 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; + break; + case DHT12: + 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; + break; + case DHT22: + 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; + break; + } +} + +/*! + * @brief Instantiates a new DHT_Unified Humidity Class + * @param parent + * Parent Sensor + * @param id + * Sensor id + */ +DHT_Unified::Humidity::Humidity(DHT_Unified *parent, int32_t id) + : _parent(parent), _id(id) {} + +/*! + * @brief Reads the sensor and returns the data as a sensors_event_t + * @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(); + + return true; +} + +/*! + * @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)); + // Set sensor name. + _parent->setName(sensor); + // Set version and ID + sensor->version = DHT_SENSOR_VERSION; + sensor->sensor_id = _id; + // Set type and characteristics. + 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; + break; + case DHT12: + 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; + break; + case DHT22: + 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; + break; + } +} diff --git a/DHT_sensor_library/DHT_U.h b/DHT_sensor_library/DHT_U.h new file mode 100644 index 0000000..3d4ba83 --- /dev/null +++ b/DHT_sensor_library/DHT_U.h @@ -0,0 +1,101 @@ +/*! + * @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. + */ + +#ifndef DHT_U_H +#define DHT_U_H + +#include +#include + +#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); + 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); + + private: + 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); + + private: + DHT_Unified *_parent; + int32_t _id; + }; + + /*! + * @brief Returns temperature stored in _temp + * @return Temperature value + */ + Temperature temperature() { return _temp; } + + /*! + * @brief Returns humidity stored in _humidity + * @return Humidity value + */ + Humidity humidity() { return _humidity; } + +private: + DHT _dht; + uint8_t _type; + Temperature _temp; + Humidity _humidity; + + void setName(sensor_t *sensor); + void setMinDelay(sensor_t *sensor); +}; + +#endif diff --git a/DHT_sensor_library/README.md b/DHT_sensor_library/README.md new file mode 100644 index 0000000..ba87187 --- /dev/null +++ b/DHT_sensor_library/README.md @@ -0,0 +1,58 @@ +# DHT sensor library [![Build Status](https://github.com/adafruit/DHT-sensor-library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/DHT-sensor-library/actions) + +## Description + +An Arduino library for the DHT series of low-cost temperature/humidity sensors. + +You can find DHT tutorials [here](https://learn.adafruit.com/dht). + +# Dependencies + * [Adafruit Unified Sensor Driver](https://github.com/adafruit/Adafruit_Sensor) + +# Contributing + +Contributions are welcome! Not only you’ll encourage the development of the library, but you’ll also learn how to best use the library and probably some C++ too + +Please read our [Code of Conduct](https://github.com/adafruit/DHT-sensor-library/blob/master/CODE_OF_CONDUCT.md>) +before contributing to help this project stay welcoming. + +## Documentation and doxygen +Documentation is produced by doxygen. Contributions should include documentation for any new code added. + +Some examples of how to use doxygen can be found in these guide pages: + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips + +Written by Adafruit Industries based on work by: + + * T. DiCola + * P. Y. Dragon + * L. Fried + * J. Hoffmann + * M. Kooijman + * J. M. Dana + * S. Conaway + * S. IJskes + * T. Forbes + * B. C + * T. J Myers + * L. Sørup + * per1234 + * O. Duffy + * matthiasdanner + * J. Lim + * G. Ambrozio + * chelmi + * adams13x13 + * Spacefish + * I. Scheller + * C. Miller + * 7eggert + + +MIT license, check license.txt for more information +All text above must be included in any redistribution + +To install, use the Arduino Library Manager and search for "DHT sensor library" and install the library. diff --git a/DHT_sensor_library/code-of-conduct.md b/DHT_sensor_library/code-of-conduct.md new file mode 100644 index 0000000..8ee6e44 --- /dev/null +++ b/DHT_sensor_library/code-of-conduct.md @@ -0,0 +1,127 @@ +# Adafruit Community Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and leaders pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level or type of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +We are committed to providing a friendly, safe and welcoming environment for +all. + +Examples of behavior that contributes to creating a positive environment +include: + +* Be kind and courteous to others +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Collaborating with other community members +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and sexual attention or advances +* The use of inappropriate images, including in a community member's avatar +* The use of inappropriate language, including in a community member's nickname +* Any spamming, flaming, baiting or other attention-stealing behavior +* Excessive or unwelcome helping; answering outside the scope of the question + asked +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate + +The goal of the standards and moderation guidelines outlined here is to build +and maintain a respectful community. We ask that you don’t just aim to be +"technically unimpeachable", but rather try to be your best self. + +We value many things beyond technical expertise, including collaboration and +supporting others within our community. Providing a positive experience for +other community members can have a much more significant impact than simply +providing the correct answer. + +## Our Responsibilities + +Project leaders are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project leaders have the right and responsibility to remove, edit, or +reject messages, comments, commits, code, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any community member for other behaviors that they deem +inappropriate, threatening, offensive, or harmful. + +## Moderation + +Instances of behaviors that violate the Adafruit Community Code of Conduct +may be reported by any member of the community. Community members are +encouraged to report these situations, including situations they witness +involving other community members. + +You may report in the following ways: + +In any situation, you may send an email to . + +On the Adafruit Discord, you may send an open message from any channel +to all Community Helpers by tagging @community helpers. You may also send an +open message from any channel, or a direct message to @kattni#1507, +@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or +@Andon#8175. + +Email and direct message reports will be kept confidential. + +In situations on Discord where the issue is particularly egregious, possibly +illegal, requires immediate action, or violates the Discord terms of service, +you should also report the message directly to Discord. + +These are the steps for upholding our community’s standards of conduct. + +1. Any member of the community may report any situation that violates the +Adafruit Community Code of Conduct. All reports will be reviewed and +investigated. +2. If the behavior is an egregious violation, the community member who +committed the violation may be banned immediately, without warning. +3. Otherwise, moderators will first respond to such behavior with a warning. +4. Moderators follow a soft "three strikes" policy - the community member may +be given another chance, if they are receptive to the warning and change their +behavior. +5. If the community member is unreceptive or unreasonable when warned by a +moderator, or the warning goes unheeded, they may be banned for a first or +second offense. Repeated offenses will result in the community member being +banned. + +## Scope + +This Code of Conduct and the enforcement policies listed above apply to all +Adafruit Community venues. This includes but is not limited to any community +spaces (both public and private), the entire Adafruit Discord server, and +Adafruit GitHub repositories. Examples of Adafruit Community spaces include +but are not limited to meet-ups, audio chats on the Adafruit Discord, or +interaction at a conference. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. As a community +member, you are representing our community, and are expected to behave +accordingly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +, +and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). + +For other projects adopting the Adafruit Community Code of +Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider +explicitly mentioning your moderation policy or making a copy with your +own moderation policy so as to avoid confusion. diff --git a/DHT_sensor_library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino b/DHT_sensor_library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino new file mode 100644 index 0000000..0f70347 --- /dev/null +++ b/DHT_sensor_library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino @@ -0,0 +1,85 @@ +// DHT Temperature & Humidity Sensor +// Unified Sensor Library Example +// Written by Tony DiCola for Adafruit Industries +// Released under an MIT license. + +// REQUIRES the following Arduino libraries: +// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library +// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor + +#include +#include +#include + +#define DHTPIN 2 // Digital pin connected to the DHT sensor +// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 -- +// Pin 15 can work but DHT must be disconnected during program upload. + +// Uncomment the type of sensor in use: +//#define DHTTYPE DHT11 // DHT 11 +#define DHTTYPE DHT22 // DHT 22 (AM2302) +//#define DHTTYPE DHT21 // DHT 21 (AM2301) + +// See guide for details on sensor wiring and usage: +// https://learn.adafruit.com/dht/overview + +DHT_Unified dht(DHTPIN, DHTTYPE); + +uint32_t delayMS; + +void setup() { + Serial.begin(9600); + // Initialize device. + dht.begin(); + Serial.println(F("DHTxx Unified Sensor Example")); + // Print temperature sensor details. + sensor_t sensor; + dht.temperature().getSensor(&sensor); + Serial.println(F("------------------------------------")); + Serial.println(F("Temperature Sensor")); + Serial.print (F("Sensor Type: ")); Serial.println(sensor.name); + Serial.print (F("Driver Ver: ")); Serial.println(sensor.version); + Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id); + Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("°C")); + Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("°C")); + Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("°C")); + Serial.println(F("------------------------------------")); + // Print humidity sensor details. + dht.humidity().getSensor(&sensor); + Serial.println(F("Humidity Sensor")); + Serial.print (F("Sensor Type: ")); Serial.println(sensor.name); + Serial.print (F("Driver Ver: ")); Serial.println(sensor.version); + Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id); + Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("%")); + Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("%")); + Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("%")); + Serial.println(F("------------------------------------")); + // Set delay between sensor readings based on sensor details. + delayMS = sensor.min_delay / 1000; +} + +void 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(F("Error reading temperature!")); + } + else { + Serial.print(F("Temperature: ")); + Serial.print(event.temperature); + Serial.println(F("°C")); + } + // Get humidity event and print its value. + dht.humidity().getEvent(&event); + if (isnan(event.relative_humidity)) { + Serial.println(F("Error reading humidity!")); + } + else { + Serial.print(F("Humidity: ")); + Serial.print(event.relative_humidity); + Serial.println(F("%")); + } +} diff --git a/DHT_sensor_library/examples/DHTtester/DHTtester.ino b/DHT_sensor_library/examples/DHTtester/DHTtester.ino new file mode 100644 index 0000000..d13507b --- /dev/null +++ b/DHT_sensor_library/examples/DHTtester/DHTtester.ino @@ -0,0 +1,74 @@ +// Example testing sketch for various DHT humidity/temperature sensors +// Written by ladyada, public domain + +// REQUIRES the following Arduino libraries: +// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library +// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor + +#include "DHT.h" + +#define DHTPIN 2 // Digital pin connected to the DHT sensor +// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 -- +// Pin 15 can work but DHT must be disconnected during program upload. + +// Uncomment whatever type you're using! +//#define DHTTYPE DHT11 // DHT 11 +#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 +//#define DHTTYPE DHT21 // DHT 21 (AM2301) + +// Connect pin 1 (on the left) of the sensor to +5V +// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1 +// to 3.3V instead of 5V! +// Connect pin 2 of the sensor to whatever your DHTPIN is +// Connect pin 3 (on the right) of the sensor to GROUND (if your sensor has 3 pins) +// Connect pin 4 (on the right) of the sensor to GROUND and leave the pin 3 EMPTY (if your sensor has 4 pins) +// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor + +// Initialize DHT sensor. +// Note that older versions of this library took an optional third parameter to +// 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); + +void setup() { + Serial.begin(9600); + Serial.println(F("DHTxx test!")); + + dht.begin(); +} + +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(F("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(F("Humidity: ")); + Serial.print(h); + Serial.print(F("% Temperature: ")); + Serial.print(t); + Serial.print(F("°C ")); + Serial.print(f); + Serial.print(F("°F Heat index: ")); + Serial.print(hic); + Serial.print(F("°C ")); + Serial.print(hif); + Serial.println(F("°F")); +} diff --git a/DHT_sensor_library/keywords.txt b/DHT_sensor_library/keywords.txt new file mode 100644 index 0000000..3b0280f --- /dev/null +++ b/DHT_sensor_library/keywords.txt @@ -0,0 +1,22 @@ +########################################### +# Syntax Coloring Map For DHT-sensor-library +########################################### + +########################################### +# Datatypes (KEYWORD1) +########################################### + +DHT KEYWORD1 + +########################################### +# Methods and Functions (KEYWORD2) +########################################### + +begin KEYWORD2 +readTemperature KEYWORD2 +convertCtoF KEYWORD2 +convertFtoC KEYWORD2 +computeHeatIndex KEYWORD2 +readHumidity KEYWORD2 +read KEYWORD2 + diff --git a/DHT_sensor_library/library.properties b/DHT_sensor_library/library.properties new file mode 100644 index 0000000..56f2b42 --- /dev/null +++ b/DHT_sensor_library/library.properties @@ -0,0 +1,10 @@ +name=DHT sensor library +version=1.4.4 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors +paragraph=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors +category=Sensors +url=https://github.com/adafruit/DHT-sensor-library +architectures=* +depends=Adafruit Unified Sensor diff --git a/DHT_sensor_library/license.txt b/DHT_sensor_library/license.txt new file mode 100644 index 0000000..f06f843 --- /dev/null +++ b/DHT_sensor_library/license.txt @@ -0,0 +1,20 @@ +Copyright (c) 2020 Adafruit Industries + + +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.