From 542161d1f013a2a2ced8bce14a350dca93212f65 Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Tue, 19 Sep 2023 11:02:49 +0530 Subject: [PATCH 1/6] v2.0.0: Enhanced docs, error handling & examples --- CODE_OF_CONDUCT.md | 39 ++++ CONTRIBUTING.md | 48 ++++ README.md | 217 +++++++++++++++++- assets/communication.png | Bin 0 -> 38657 bytes examples/ReadHumidity/ReadHumidity.ino | 35 ++- examples/ReadPlot/ReadPlot.ino | 41 ++++ .../ReadTempAndHumidity.ino | 51 ++-- examples/ReadTemperature/ReadTemperature.ino | 37 ++- library.properties | 10 +- src/DHT11.cpp | 101 ++++++-- src/DHT11.h | 69 +++++- 11 files changed, 570 insertions(+), 78 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 assets/communication.png create mode 100644 examples/ReadPlot/ReadPlot.ino diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c4f87e9 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,39 @@ +# Code of Conduct for DHT11 Arduino Library + +## Our Pledge + +In the interest of fostering an open and welcoming environment, I, as the author and maintainer of this project, pledge to make participation in this project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contribute to creating a positive environment include: + +- Using welcoming and inclusive language. +- Being respectful of differing viewpoints and experiences. +- Gracefully accepting constructive criticism. +- Focusing on what is best for the community and users. +- Showing empathy towards other community members. + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances. +- 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 in a professional setting. + +## My Responsibilities + +As the sole developer and maintainer, I am responsible for clarifying the standards of acceptable behavior and am expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior can be reported by contacting me directly at dhrubasaha@outlook.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. I am obligated to maintain confidentiality with regard to the reporter of an incident. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) + +## Familiarization + +All community members, contributors, and participants are encouraged to familiarize themselves with this code of conduct. Adherence to these guidelines helps maintain a positive and respectful environment for everyone involved. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8ce9ee2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Contributing to DHT11 Arduino Library + +Thank you for considering contributing to the DHT11 Arduino Library. It's community members like you that enhance the usefulness of this library. + +## Code of Conduct + +I'm committed to fostering a welcoming and open environment. All contributors are expected to adhere to the [DHT11 Arduino Library Code of Conduct](CODE_OF_CONDUCT.md). If you encounter unacceptable behavior, please report it to dhrubasaha@outlook.com. + +## How Can I Contribute? + +### Reporting Bugs + +- **Ensure the bug wasn't previously reported** by searching on GitHub under [Issues](https://github.com/dhrubasaha08/DHT11/issues). +- If you can't find an existing issue addressing the problem, [open a new one](https://github.com/dhrubasaha08/DHT11/issues/new). + +### Suggesting Enhancements + +Have an idea for an enhancement or a new feature? Please create an issue labeled `enhancement`. + +### Pull Requests + +1. Fork the repository. +2. Create a new branch (`git checkout -b new-feature`). +3. Commit your changes (`git commit -am 'Add a new feature'`). +4. Push the branch (`git push origin new-feature`). +5. Submit a Pull Request. + +## Styleguides + +### Git Commit Messages + +- Use present tense ("Add feature" not "Added feature"). +- Start with a capital letter. +- Limit the first line to 72 characters or fewer. + +### Code Styleguide + +Stick to the coding conventions evident in the project. + +## Additional Notes + +### Issue and Pull Request Labels + +Possible labels for issues or PRs include: + +- `bug` - For bug-related issues. +- `enhancement` - For enhancements or new features. +- `documentation` - For documentation-related issues. diff --git a/README.md b/README.md index 56e20c0..059f999 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,228 @@ -# DHT11 +# DHT11 Arduino Library -This is an Arduino library for the DHT11 temperature and humidity sensor. The library provides an easy-to-use interface for reading temperature and humidity data from the DHT11 sensor. +## Table of Contents + +- [Introduction](#introduction) +- [Version 2.0.0 Updates](#version-200-updates) +- [How It Works](#how-it-works) + - [Internal Protocol Handling](#internal-protocol-handling) +- [Features](#features) +- [Installation](#installation) + - [Arduino IDE Library Manager](#arduino-ide-library-manager) + - [Installing Manually from GitHub](#installing-manually-from-github) +- [Usage](#usage) + - [Basic Usage](#basic-usage) + - [New Methods in Version 2.0.0](#new-methods-in-version-200) + - [Wiring Details](#wiring-details) +- [Examples](#examples) +- [Error Handling](#error-handling) +- [Troubleshooting](#troubleshooting) +- [FAQ](#faq) +- [Compatibility](#compatibility) + - [Contribute by Testing](#contribute-by-testing) +- [Contributing](#contributing) +- [Code of Conduct](#code-of-conduct) +- [License](#license) +- [External References](#external-references) + +## Introduction + +This Arduino library is designed for the DHT11 temperature and humidity sensor. It simplifies the process of reading temperature and humidity data, making it easy to integrate the DHT11 sensor into your Arduino projects. + +**Author:** [Dhruba Saha](https://github.com/dhrubasaha08) + +**Version:** 2.0.0 + +**License:** [MIT](/LICENSE) + +## Version 2.0.0 Updates + +- Changed the return type of `readTemperature()` and `readHumidity()` methods from `float` to `int`. This aligns with the DHT11 sensor's 1-degree resolution. +- Enhanced code documentation for easier maintenance and better readability. +- Added the `getErrorString` method to return human-readable error messages based on error codes. +- Major code refactoring for better maintainability and robustness. +- Introduced the [`CONTRIBUTING.md`](CONTRIBUTING.md) file to guide contributors on how to effectively contribute to the library. +- Added a [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) to establish community guidelines and expectations for behavior. +- Introduced the [`ReadPlot`](/examples/ReadPlot/ReadPlot.ino) example which uses the Arduino Serial Plotter to display temperature and humidity data. This example provides a visual representation of the sensor's readings, making it easier to monitor environmental conditions in real-time. ## How It Works -The DHT11 sensor provides temperature and humidity data over a single-wire interface. This library handles the low-level communication protocol with the sensor, allowing you to read the temperature and humidity data with simple function calls. +The DHT11 sensor uses a custom single-wire protocol for communication. The basic process for reading data involves: + +1. Sending a start signal to the DHT11 sensor. +2. Reading a series of pulses from the sensor representing data bits. +3. Interpreting the received bits to extract temperature and humidity values. +4. Validating the data using a checksum. + +The library handles these steps internally, providing the user with a simple interface for reading temperature and humidity. + +### Internal Protocol Handling + +The library initiates the data request to the DHT11 sensor and then reads a 40-bit data stream in response. The data stream is parsed to obtain accurate temperature and humidity readings. The process of reading data from the DHT11 involves multiple steps: + +![](/assets/communication.png) +**Source & Credit :** [Mouser DHT11 Datasheet](https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf) + +1. **Initialization and Request**: + - The MCU (like an Arduino) sends a start signal by pulling the data line low for at least 18ms. + - The MCU then pulls the line high for 20-40us to indicate that it's ready to receive a response. + +2. **DHT11 Response**: + - Upon detecting the start signal from the MCU, the DHT11 sends a response signal. + - This response consists of a 80us low voltage level followed by an 80us high voltage level. + +3. **Data Transmission**: + - The DHT11 transmits its data in a series of pulses. Each bit of data is represented by a specific combination of high and low voltage durations. + - A '0' is represented by 50us of low voltage followed by 26-28us of high voltage. + - A '1' is represented by 50us of low voltage followed by 70us of high voltage. + - The DHT11 sends 40 bits of data in total: 16 bits for humidity, 16 bits for temperature, and 8 bits for checksum. + - The checksum is the last 8 bits of the sum of the first 32 bits. It's used to verify data integrity. + +4. **Data Interpretation**: + - After reading the 40 bits, the MCU processes the data to extract temperature and humidity values. + - The bits are grouped to form the integral and decimal parts of the temperature and humidity readings, though the DHT11 provides only integer values. + +5. **Completion**: + - After data transmission, the DHT11 pulls the data line low for 50us, marking the end of the communication. The MCU then pulls the line high, putting the DHT11 in a low-power standby mode. + +This library abstracts these complexities, allowing users to easily read temperature and humidity values with simple function calls. Behind the scenes, it manages the signaling, data reading, and interpretation based on the DHT11's protocol. -When you create an instance of the DHT11 class, you specify the pin that the sensor is connected to. Then, you can call the `readTemperature()` and `readHumidity()` methods to read the temperature and humidity data, respectively. These methods return the temperature in degrees Celsius and the relative humidity in percent, or `-1` if there was an error reading the data. ## Features -- **Easy to use**: Just create an instance of the DHT11 class and call the `readTemperature()` and `readHumidity()` methods. -- **No dependencies**: This library does not depend on any other libraries, so it's easy to install and use. -- **Examples included**: The library comes with example sketches that show you how to use it. +- **Easy to Use**: Easy to use interface for reading temperature and humidity from the DHT11 sensor. +- **No External Dependencies**: The library is standalone and doesn't require any external libraries. +- **Example Sketches**: The library package includes example Arduino sketches to get you started quickly. +- **Error Handling**: The library package includes Error handling mechanisms to ensure robustness. ## Installation -To install the library, download the latest release from this repository and install it using the Arduino IDE's Library Manager. +### Arduino IDE Library Manager +1. Open the Arduino IDE. +2. Go to `Sketch` > `Include Library` > `Manage Libraries...`. +3. In the Library Manager, enter "DHT11" into the search box. +4. Find the DHT11 library in the list and install it. + +### Installing Manually from GitHub +1. Download the latest release of the library from this GitHub repository as a ZIP file. +2. Open the Arduino IDE. +3. Go to `Sketch` > `Include Library` > `Add .ZIP Library...`. +4. Navigate to the downloaded ZIP file and select it to install. ## Usage -To use the library, include the `DHT11.h` header file in your sketch, create an instance of the DHT11 class, and call the `readTemperature()` and `readHumidity()` methods. See the example sketches included in the `examples` directory for more details. +### Basic Usage + +- Include the `DHT11.h` header file. +- Create an instance of the DHT11 class, specifying the digital pin connected to the sensor's data pin. +- Use `readTemperature()` and `readHumidity()` methods to read the data. + +### New Methods in Version 2.0.0 + +- `getErrorString(int errorCode)`: Returns a human-readable error message based on the provided error code. + +### Wiring Details + +The DHT11 sensor has three or four pins, depending on the variant: + +- **VCC**: Connect to 3.3V or 5V on your MCU (based on your sensor's specification). +- **Data**: Connect to a digital I/O pin on your MCU (not an analog pin). For the provided examples, we use digital pin 2 by default. +- **Ground (GND)**: Connect to the ground of your MCU. +- **NC (No Connect)**: Some variants have this pin. It is not used and can be left unconnected. + +Remember to use a pull-up resistor (typically 10kΩ) between the VCC and Data pins for reliable communication. + +## Examples + +All examples provided use Arduino UNO's digital pin 2 as the default connection to the DHT11 sensor's data pin. Modify this in the code if using a different pin. + +- **[Read Humidity](examples/ReadHumidity)** + This example demonstrates how to simply read the humidity value from the DHT11 sensor and display it on the Arduino Serial Monitor. It's a basic introduction to using the library to get humidity data. + +- **[Read Temperature and Humidity](examples/ReadTempAndHumidity)** + A more comprehensive example that shows how to read both temperature and humidity values from the DHT11 sensor. Results are displayed on the Arduino Serial Monitor, giving users a complete view of the environment. + +- **[Read Temperature](examples/ReadTemperature)** + Similar to the 'Read Humidity' example, but focused solely on reading and displaying the temperature value from the DHT11 sensor. It provides a straightforward way to monitor temperature using the library. + +- **[Read Plot](examples/ReadPlot/)** + A visually interactive example that uses the Arduino Serial Plotter to graphically display temperature and humidity data in real-time. This is perfect for those who want a visual representation and trend analysis of the sensor's readings. + +## Error Handling + +The library provides clear error handling mechanisms. When reading data: + +- If there's a timeout while waiting for a response from the sensor, the methods `readTemperature()` and `readHumidity()` return the value `DHT11::ERROR_TIMEOUT`. +- If there's a checksum mismatch indicating data corruption, the methods return the value `DHT11::ERROR_CHECKSUM`. + +For translating these error codes to human-readable strings, the library offers the `DHT11::getErrorString(int errorCode)` method. + +## Troubleshooting + +- **Sensor Not Responding or Constant Timeouts:** + - Ensure the sensor receives the proper voltage (3.3V or 5V). + - Double-check the data pin connection to the Arduino board. + - Restart the Arduino IDE after any changes. + +- **Checksum Errors:** + - Ensure minimal distance between the sensor and the Arduino board. + - Check the surrounding environment for electrical noise sources. + +- **Inaccurate or Unstable Readings:** + - Give the sensor time to stabilize after powering on. + - Position the sensor away from direct sources of temperature or humidity changes. + +- **Library Not Found in Arduino IDE:** + - Confirm the library's correct installation. + - Restart the Arduino IDE. + +## FAQ + +1. **Is this library designed for the DHT22 sensor as well?** + No. The library caters exclusively to the DHT11 sensor. The DHT22 uses a different data format, necessitating a separate library. + +2. **What's the recommended frequency for sensor readings?** + It's best to allow at least 1 second between readings for accurate and stable results. + +3. **I'm experiencing persistent timeout errors. What can I do?** + Ensure proper wiring, verify the sensor's power source, and check if the specified data pin in the Arduino code matches your hardware setup. + +4. **Has this library been tested on platforms other than the Arduino IDE?** + While it's been primarily tested on the Arduino IDE and Arduino Uno R3 board, it might work on other platforms or boards. However, results may vary. + +5. **Is the library compatible with third-party platforms?** + Although tailored for the Arduino IDE, the library might function on other platforms. Still, I don't guarantee compatibility or consistent outcomes on third-party platforms. + +## Compatibility + +The library has been tested and confirmed to work on the following boards: + +- Arduino Uno R3 (ATmega328P - AVR architecture) + +I understand that there are many boards and architectures out there, and it's challenging for a single developer to test on all of them. + +### Contribute by Testing + +If you've successfully used this library on a board not listed above, please consider contributing by letting me know. This will help the community to have a broader understanding of the library's compatibility. + +1. Fork the [repository](https://github.com/dhrubasaha08/DHT11). +2. Update the README with the board you've tested. +3. Create a pull request with your changes. + +Your contribution will be greatly appreciated, and it will benefit the entire Arduino community. ## Contributing -Contributions to this library are welcome. Please open an issue if you find a bug or have a feature request, and feel free to submit pull requests if you've implemented a new feature or bug fix. +For guidelines on contributing to this project, please see the [`CONTRIBUTING.md`](CONTRIBUTING.md) file. + +## Code of Conduct + +To understand the community guidelines and expected behavior, please refer to the [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) file. ## License -This library is licensed under the MIT License. Please see the `LICENSE` file for more details. +This library is licensed under the `MIT` License. See the [`LICENSE`](LICENSE) file for more details. ## External References -- [DHT11 Datasheet](https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf) +- [`DHT11 Datasheet`](https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf) diff --git a/assets/communication.png b/assets/communication.png new file mode 100644 index 0000000000000000000000000000000000000000..2d625e4704611bdf7c9bfef891f14c0dea33e704 GIT binary patch literal 38657 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 `nm&Z9TD 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 -// Create an instance of the DHT11 class and set the digital I/O pin. +// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. DHT11 dht11(2); void setup() { - // Initialize serial communication at 115200 baud. - Serial.begin(115200); + // Initialize serial communication to allow debugging and data readout. + // Using a baud rate of 9600 bps. + Serial.begin(9600); } void loop() { - // Read the humidity from the sensor. - float humidity = dht11.readHumidity(); + // Attempt to read the humidity value from the DHT11 sensor. + int humidity = dht11.readHumidity(); - // If the humidity reading was successful, print it to the serial monitor. - if (humidity != -1) + // Check the result of the reading. + // If there's no error, print the humidity value. + // If there's an error, print the appropriate error message. + if (humidity != DHT11::ERROR_CHECKSUM && humidity != DHT11::ERROR_TIMEOUT) { Serial.print("Humidity: "); Serial.print(humidity); @@ -23,10 +37,9 @@ void loop() } else { - // If the humidity reading failed, print an error message. - Serial.println("Error reading humidity"); + Serial.println(DHT11::getErrorString(humidity)); } - // Wait for 2 seconds before the next reading. - delay(2000); + // Wait for 1 seconds before the next reading. + delay(1000); } diff --git a/examples/ReadPlot/ReadPlot.ino b/examples/ReadPlot/ReadPlot.ino new file mode 100644 index 0000000..193aa38 --- /dev/null +++ b/examples/ReadPlot/ReadPlot.ino @@ -0,0 +1,41 @@ +/** + * DHT11 Sensor Reader for Arduino + * This sketch reads temperature and humidity data from the DHT11 sensor and prints the values to the serial plotter. + * + * Author: Dhruba Saha + * Version: 2.0.0 + * License: MIT + */ + +// Include the DHT11 library for interfacing with the sensor. +#include + +// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. +DHT11 dht11(2); + +void setup() +{ + // Initialize serial communication to allow debugging and data readout. + // Using a baud rate of 9600 bps. + Serial.begin(9600); +} + +void loop() +{ + // Attempt to read the temperature and humidity values from the DHT11 sensor. + int temperature = dht11.readTemperature(); + int humidity = dht11.readHumidity(); + + // Check the results of the readings. + // If there are no errors, print the temperature and humidity values in CSV format. + if (temperature != DHT11::ERROR_CHECKSUM && temperature != DHT11::ERROR_TIMEOUT && humidity != DHT11::ERROR_CHECKSUM && humidity != DHT11::ERROR_TIMEOUT) + { + Serial.print("Temperature:"); + Serial.print(temperature); + Serial.print(",Humidity:"); + Serial.println(humidity); + } + + // Wait for 1 seconds before the next reading. + delay(1000); +} \ No newline at end of file diff --git a/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino b/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino index f3a0bd7..d3fed26 100644 --- a/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino +++ b/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino @@ -1,28 +1,41 @@ +/** + * DHT11 Sensor Reader for Arduino + * This sketch reads temperature and humidity data from the DHT11 sensor and prints the values to the serial port. + * It also handles potential error states that might occur during reading. + * + * Author: Dhruba Saha + * Version: 2.0.0 + * License: MIT + */ + +// Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class and set the digital I/O pin. +// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. DHT11 dht11(2); void setup() { - // Initialize serial communication at 115200 baud. - Serial.begin(115200); + // Initialize serial communication to allow debugging and data readout. + // Using a baud rate of 9600 bps. + Serial.begin(9600); } void loop() { - // Read the humidity from the sensor. - float humidity = dht11.readHumidity(); + // Attempt to read the temperature and humidity values from the DHT11 sensor. + int temperature = dht11.readTemperature(); + int humidity = dht11.readHumidity(); - // Read the temperature from the sensor. - float temperature = dht11.readTemperature(); - - // If the temperature and humidity readings were successful, print them to the serial monitor. - if (temperature != -1 && humidity != -1) + // Check the results of the readings. + // If there are no errors, print the temperature and humidity values. + // If there are errors, print the appropriate error messages. + if (temperature != DHT11::ERROR_CHECKSUM && temperature != DHT11::ERROR_TIMEOUT && + humidity != DHT11::ERROR_CHECKSUM && humidity != DHT11::ERROR_TIMEOUT) { Serial.print("Temperature: "); Serial.print(temperature); - Serial.println(" C"); + Serial.println(" °C"); Serial.print("Humidity: "); Serial.print(humidity); @@ -30,10 +43,18 @@ void loop() } else { - // If the temperature or humidity reading failed, print an error message. - Serial.println("Error reading data"); + if (temperature == DHT11::ERROR_TIMEOUT || temperature == DHT11::ERROR_CHECKSUM) + { + Serial.print("Temperature Reading Error: "); + Serial.println(DHT11::getErrorString(temperature)); + } + if (humidity == DHT11::ERROR_TIMEOUT || humidity == DHT11::ERROR_CHECKSUM) + { + Serial.print("Humidity Reading Error: "); + Serial.println(DHT11::getErrorString(humidity)); + } } - // Wait for 2 seconds before the next reading. - delay(2000); + // Wait for 1 seconds before the next reading. + delay(1000); } diff --git a/examples/ReadTemperature/ReadTemperature.ino b/examples/ReadTemperature/ReadTemperature.ino index 3adde37..451cb3c 100644 --- a/examples/ReadTemperature/ReadTemperature.ino +++ b/examples/ReadTemperature/ReadTemperature.ino @@ -1,32 +1,45 @@ +/** + * DHT11 Temperature Reader for Arduino + * This sketch reads temperature data from the DHT11 sensor and prints the value to the serial port. + * It also handles potential error states that might occur during reading. + * + * Author: Dhruba Saha + * Version: 2.0.0 + * License: MIT + */ + +// Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class and set the digital I/O pin. +// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. DHT11 dht11(2); void setup() { - // Initialize serial communication at 115200 baud. - Serial.begin(115200); + // Initialize serial communication to allow debugging and data readout. + // Using a baud rate of 9600 bps. + Serial.begin(9600); } void loop() { - // Read the temperature from the sensor. - float temperature = dht11.readTemperature(); + // Attempt to read the temperature value from the DHT11 sensor. + int temperature = dht11.readTemperature(); - // If the temperature reading was successful, print it to the serial monitor. - if (temperature != -1) + // Check the result of the reading. + // If there's no error, print the temperature value. + // If there's an error, print the appropriate error message. + if (temperature != DHT11::ERROR_CHECKSUM && temperature != DHT11::ERROR_TIMEOUT) { Serial.print("Temperature: "); Serial.print(temperature); - Serial.println(" C"); + Serial.println(" °C"); } else { - // If the temperature reading failed, print an error message. - Serial.println("Error reading temperature"); + Serial.println(DHT11::getErrorString(temperature)); } - // Wait for 2 seconds before the next reading. - delay(2000); + // Wait for 1 seconds before the next reading. + delay(1000); } diff --git a/library.properties b/library.properties index 2a14df9..94cfdcf 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=DHT11 -version=1.0.0 -author=Dhruba Saha +version=2.0.0 +author=Dhruba Saha maintainer=Dhruba Saha -sentence=A library for the DHT11 temperature and humidity sensor. -paragraph=This library provides an easy-to-use interface for reading temperature and humidity data from a DHT11 sensor. It does not depend on any other libraries. +sentence=An Arduino library for the DHT11 temperature and humidity sensor. +paragraph=This library provides a simple and easy-to-use interface to read temperature and humidity data from a DHT11 sensor. category=Sensors -url=http://github.com/dhrubasaha08/DHT11 +url=https://github.com/dhrubasaha08/DHT11 architectures=* diff --git a/src/DHT11.cpp b/src/DHT11.cpp index 1a32d36..cfcb3e2 100644 --- a/src/DHT11.cpp +++ b/src/DHT11.cpp @@ -1,6 +1,20 @@ +/** + * DHT11.cpp + * Library for reading temperature and humidity from the DHT11 sensor. + * + * Author: Dhruba Saha + * Version: 2.0.0 + * License: MIT + */ + #include "DHT11.h" -// Initializes the pin and sets it to output mode. +/** + * Constructor for the DHT11 class. + * Initializes the pin to be used for communication and sets it to output mode. + * + * @param pin: Digital pin number on the Arduino board to which the DHT11 sensor is connected. + */ DHT11::DHT11(int pin) { _pin = pin; @@ -8,12 +22,26 @@ DHT11::DHT11(int pin) digitalWrite(_pin, HIGH); } -// Reads and returns the temperature from the sensor. Returns -1 if the checksum is incorrect. -float DHT11::readTemperature() +/** + * Reads and returns the temperature from the DHT11 sensor. + * + * @return: Temperature value in Celsius. Returns DHT11::ERROR_TIMEOUT if reading times out. + * Returns DHT11::ERROR_CHECKSUM if checksum validation fails. + */ +int DHT11::readTemperature() { delay(150); byte data[5] = {0, 0, 0, 0, 0}; startSignal(); + unsigned long timeout_start = millis(); + + while (digitalRead(_pin) == HIGH) + { + if (millis() - timeout_start > DHT11::TIMEOUT_DURATION) + { + return DHT11::ERROR_TIMEOUT; + } + } if (digitalRead(_pin) == LOW) { @@ -21,27 +49,43 @@ float DHT11::readTemperature() if (digitalRead(_pin) == HIGH) { delayMicroseconds(80); - for (int i = 0; i < 5; i++) { data[i] = readByte(); + if (data[i] == DHT11::ERROR_TIMEOUT) + { + return DHT11::ERROR_TIMEOUT; + } } - if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { return data[2]; } } } - return -1; + return DHT11::ERROR_CHECKSUM; } -// Reads and returns the humidity from the sensor. Returns -1 if the checksum is incorrect. -float DHT11::readHumidity() +/** + * Reads and returns the humidity from the DHT11 sensor. + * + * @return: Humidity value in percentage. Returns DHT11::ERROR_TIMEOUT if reading times out. + * Returns DHT11::ERROR_CHECKSUM if checksum validation fails. + */ +int DHT11::readHumidity() { delay(150); byte data[5] = {0, 0, 0, 0, 0}; startSignal(); + unsigned long timeout_start = millis(); + + while (digitalRead(_pin) == HIGH) + { + if (millis() - timeout_start > DHT11::TIMEOUT_DURATION) + { + return DHT11::ERROR_TIMEOUT; + } + } if (digitalRead(_pin) == LOW) { @@ -49,22 +93,28 @@ float DHT11::readHumidity() if (digitalRead(_pin) == HIGH) { delayMicroseconds(80); - for (int i = 0; i < 5; i++) { data[i] = readByte(); + if (data[i] == DHT11::ERROR_TIMEOUT) + { + return DHT11::ERROR_TIMEOUT; + } } - if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { return data[0]; } } } - return -1; + return DHT11::ERROR_CHECKSUM; } -// Reads a byte of data from the sensor. +/** + * Reads a byte of data from the DHT11 sensor during the communication process. + * + * @return: A byte of data read from the sensor. + */ byte DHT11::readByte() { byte value = 0; @@ -84,7 +134,11 @@ byte DHT11::readByte() return value; } -// Sends the start signal to the sensor. +/** + * Sends a start signal to the DHT11 sensor to initiate a data read. + * This involves setting the data pin low for a specific duration, then high, + * and finally setting it to input mode to read the data. + */ void DHT11::startSignal() { pinMode(_pin, OUTPUT); @@ -94,3 +148,24 @@ void DHT11::startSignal() delayMicroseconds(40); pinMode(_pin, INPUT); } + +/** + * Returns a human-readable error message based on the provided error code. + * This method facilitates easier debugging and user feedback by translating + * numeric error codes into descriptive strings. + * + * @param errorCode The error code for which the description is required. + * @return A descriptive string explaining the error. + */ +String DHT11::getErrorString(int errorCode) +{ + switch (errorCode) + { + case DHT11::ERROR_TIMEOUT: + return "Error: Reading from DHT11 timed out."; + case DHT11::ERROR_CHECKSUM: + return "Error: Checksum mismatch while reading from DHT11."; + default: + return "Error: Unknown error code."; + } +} diff --git a/src/DHT11.h b/src/DHT11.h index bffec9e..7387d06 100644 --- a/src/DHT11.h +++ b/src/DHT11.h @@ -1,29 +1,78 @@ +/** + * DHT11.h + * Header file for the DHT11 library, providing functionalities to interface with + * the DHT11 temperature and humidity sensor. + * + * Author: Dhruba Saha + * Version: 2.0.0 + * License: MIT + */ + #ifndef DHT11_h #define DHT11_h #include "Arduino.h" -// DHT11 class for reading temperature and humidity data from a DHT11 sensor. +/** + * DHT11 Class + * Provides methods to read temperature and humidity data from the DHT11 sensor. + */ class DHT11 { public: - // Takes the pin number as an argument. + /** + * Constructor + * Initializes the data pin to be used for communication with the DHT11 sensor. + * + * @param pin: Digital pin number on the Arduino board to which the DHT11 sensor is connected. + */ DHT11(int pin); - // Reads and returns the humidity from the sensor. Returns -1 if the checksum is incorrect. - float readHumidity(); + /** + * Reads and returns the humidity from the DHT11 sensor. + * + * @return: Humidity value in percentage. Returns DHT11_ERROR_TIMEOUT if reading times out. + * Returns DHT11_ERROR_CHECKSUM if checksum validation fails. + */ + int readHumidity(); - // Reads and returns the temperature from the sensor. Returns -1 if the checksum is incorrect. - float readTemperature(); + /** + * Reads and returns the temperature from the DHT11 sensor. + * + * @return: Temperature value in Celsius. Returns DHT11_ERROR_TIMEOUT if reading times out. + * Returns DHT11_ERROR_CHECKSUM if checksum validation fails. + */ + int readTemperature(); + + // Constants to represent error codes. + static const int ERROR_CHECKSUM = 254; // Error code indicating checksum mismatch. + static const int ERROR_TIMEOUT = 253; // Error code indicating a timeout occurred during reading. + static const int TIMEOUT_DURATION = 300; // Duration (in milliseconds) to wait before timing out. + + /** + * Returns a human-readable error message based on the provided error code. + * + * @param errorCode: The error code for which the message is required. + * @return: A string describing the error. + */ + static String getErrorString(int errorCode); private: - int _pin; + int _pin; // Pin number used for communication with the DHT11 sensor. - // Reads a byte of data from the sensor. + /** + * Reads a byte of data from the DHT11 sensor. + * + * @return: A byte of data read from the sensor. + */ byte readByte(); - // Sends the start signal to the sensor. + /** + * Sends a start signal to the DHT11 sensor to initiate a data read. + * This involves setting the data pin low for a specific duration, then high, + * and finally setting it to input mode to read the data. + */ void startSignal(); }; -#endif \ No newline at end of file +#endif From d22667ca21ec7bde9a332a7a5925fc92933c329d Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Wed, 20 Sep 2023 06:33:23 +0530 Subject: [PATCH 2/6] Added ESP32, ESP8266 to the compatibility list --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 059f999..34a8fbf 100644 --- a/README.md +++ b/README.md @@ -198,8 +198,12 @@ For translating these error codes to human-readable strings, the library offers The library has been tested and confirmed to work on the following boards: - Arduino Uno R3 (ATmega328P - AVR architecture) +- `*` NodeMCU ESP32S v1.1 **`ESP-WROOM-32`** (Tensilica Xtensa LX6 - xtensa architecture) +- `*` NodeMCU ESP8266 v1.0 **`ESP8266MOD`** (Tensilica Xtensa LX106 - xtensa architecture) -I understand that there are many boards and architectures out there, and it's challenging for a single developer to test on all of them. +`*` For xtensa-based boards (ESP32 and ESP8266), a delay is required between consecutive method calls for optimal performance. Check [Examples](/examples/) for the implementation details. + +Given the vast number of boards and architectures available, it's a challenge for a solo developer to test on all. Community contributions in terms of compatibility testing are highly encouraged. ### Contribute by Testing From 833a45c6abd2b71211cb45f24432878aaa78c350 Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Wed, 20 Sep 2023 06:35:09 +0530 Subject: [PATCH 3/6] Added ESP32, ESP8266 to the compatibility list --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 34a8fbf..a5a9a6d 100644 --- a/README.md +++ b/README.md @@ -198,8 +198,8 @@ For translating these error codes to human-readable strings, the library offers The library has been tested and confirmed to work on the following boards: - Arduino Uno R3 (ATmega328P - AVR architecture) -- `*` NodeMCU ESP32S v1.1 **`ESP-WROOM-32`** (Tensilica Xtensa LX6 - xtensa architecture) -- `*` NodeMCU ESP8266 v1.0 **`ESP8266MOD`** (Tensilica Xtensa LX106 - xtensa architecture) +- NodeMCU ESP32S v1.1 **`ESP-WROOM-32`** (Tensilica Xtensa LX6 - xtensa architecture) `*` +- NodeMCU ESP8266 v1.0 **`ESP8266MOD`** (Tensilica Xtensa LX106 - xtensa architecture) `*` `*` For xtensa-based boards (ESP32 and ESP8266), a delay is required between consecutive method calls for optimal performance. Check [Examples](/examples/) for the implementation details. From e69a910c92a4876566c78abf8e6cfe0d34d35e1c Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Wed, 20 Sep 2023 06:45:14 +0530 Subject: [PATCH 4/6] Added ESP32, ESP8266 compatibility --- examples/ReadHumidity/ReadHumidity.ino | 5 ++++- examples/ReadPlot/ReadPlot.ino | 10 +++++++++- examples/ReadTempAndHumidity/ReadTempAndHumidity.ino | 10 +++++++++- examples/ReadTemperature/ReadTemperature.ino | 5 ++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/examples/ReadHumidity/ReadHumidity.ino b/examples/ReadHumidity/ReadHumidity.ino index 949e6f9..8d814c4 100644 --- a/examples/ReadHumidity/ReadHumidity.ino +++ b/examples/ReadHumidity/ReadHumidity.ino @@ -11,7 +11,10 @@ // Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. +// Create an instance of the DHT11 class. +// - For Arduino: Connect the sensor to Digital I/O Pin 2. +// - For ESP32: Connect the sensor to pin GPIO2 or P2. +// - For ESP8266: Connect the sensor to GPIO2 or D4. DHT11 dht11(2); void setup() diff --git a/examples/ReadPlot/ReadPlot.ino b/examples/ReadPlot/ReadPlot.ino index 193aa38..cdbf93f 100644 --- a/examples/ReadPlot/ReadPlot.ino +++ b/examples/ReadPlot/ReadPlot.ino @@ -10,7 +10,10 @@ // Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. +// Create an instance of the DHT11 class. +// - For Arduino: Connect the sensor to Digital I/O Pin 2. +// - For ESP32: Connect the sensor to pin GPIO2 or P2. +// - For ESP8266: Connect the sensor to GPIO2 or D4. DHT11 dht11(2); void setup() @@ -24,6 +27,11 @@ void loop() { // Attempt to read the temperature and humidity values from the DHT11 sensor. int temperature = dht11.readTemperature(); + + // If using ESP32 or ESP8266 (xtensa architecture), uncomment the delay below. + // This ensures stable readings when calling methods consecutively. + // delay(50); + int humidity = dht11.readHumidity(); // Check the results of the readings. diff --git a/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino b/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino index d3fed26..949272b 100644 --- a/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino +++ b/examples/ReadTempAndHumidity/ReadTempAndHumidity.ino @@ -11,7 +11,10 @@ // Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. +// Create an instance of the DHT11 class. +// - For Arduino: Connect the sensor to Digital I/O Pin 2. +// - For ESP32: Connect the sensor to pin GPIO2 or P2. +// - For ESP8266: Connect the sensor to GPIO2 or D4. DHT11 dht11(2); void setup() @@ -25,6 +28,11 @@ void loop() { // Attempt to read the temperature and humidity values from the DHT11 sensor. int temperature = dht11.readTemperature(); + + // If using ESP32 or ESP8266 (xtensa architecture), uncomment the delay below. + // This ensures stable readings when calling methods consecutively. + // delay(50); + int humidity = dht11.readHumidity(); // Check the results of the readings. diff --git a/examples/ReadTemperature/ReadTemperature.ino b/examples/ReadTemperature/ReadTemperature.ino index 451cb3c..07cf2f5 100644 --- a/examples/ReadTemperature/ReadTemperature.ino +++ b/examples/ReadTemperature/ReadTemperature.ino @@ -11,7 +11,10 @@ // Include the DHT11 library for interfacing with the sensor. #include -// Create an instance of the DHT11 class. The sensor is connected to digital I/O pin 2. +// Create an instance of the DHT11 class. +// - For Arduino: Connect the sensor to Digital I/O Pin 2. +// - For ESP32: Connect the sensor to pin GPIO2 or P2. +// - For ESP8266: Connect the sensor to GPIO2 or D4. DHT11 dht11(2); void setup() From 780107d7cf2bf3dae4d13b69a336f7bdcd788788 Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Wed, 20 Sep 2023 08:34:43 +0530 Subject: [PATCH 5/6] Added ESP32, ESP8266 to the compatibility list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a5a9a6d..69e4e07 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ This Arduino library is designed for the DHT11 temperature and humidity sensor. - Introduced the [`CONTRIBUTING.md`](CONTRIBUTING.md) file to guide contributors on how to effectively contribute to the library. - Added a [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) to establish community guidelines and expectations for behavior. - Introduced the [`ReadPlot`](/examples/ReadPlot/ReadPlot.ino) example which uses the Arduino Serial Plotter to display temperature and humidity data. This example provides a visual representation of the sensor's readings, making it easier to monitor environmental conditions in real-time. +- Added ESP32/ESP8266 compatibility. ## How It Works From 3333e152e06c9a61ca4453a5ab16e06aba38b818 Mon Sep 17 00:00:00 2001 From: Dhruba Saha Date: Wed, 20 Sep 2023 08:43:07 +0530 Subject: [PATCH 6/6] Enhanced readability --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 69e4e07..6b968d7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Table of Contents - [Introduction](#introduction) -- [Version 2.0.0 Updates](#version-200-updates) +- [v2.0.0 Updates](#v200-updates) - [How It Works](#how-it-works) - [Internal Protocol Handling](#internal-protocol-handling) - [Features](#features) @@ -12,7 +12,7 @@ - [Installing Manually from GitHub](#installing-manually-from-github) - [Usage](#usage) - [Basic Usage](#basic-usage) - - [New Methods in Version 2.0.0](#new-methods-in-version-200) + - [New Methods in v2.0.0](#new-methods-in-v200) - [Wiring Details](#wiring-details) - [Examples](#examples) - [Error Handling](#error-handling) @@ -35,7 +35,7 @@ This Arduino library is designed for the DHT11 temperature and humidity sensor. **License:** [MIT](/LICENSE) -## Version 2.0.0 Updates +## v2.0.0 Updates - Changed the return type of `readTemperature()` and `readHumidity()` methods from `float` to `int`. This aligns with the DHT11 sensor's 1-degree resolution. - Enhanced code documentation for easier maintenance and better readability. @@ -118,7 +118,7 @@ This library abstracts these complexities, allowing users to easily read tempera - Create an instance of the DHT11 class, specifying the digital pin connected to the sensor's data pin. - Use `readTemperature()` and `readHumidity()` methods to read the data. -### New Methods in Version 2.0.0 +### New Methods in v2.0.0 - `getErrorString(int errorCode)`: Returns a human-readable error message based on the provided error code.