Arduino library for I2C DHT20 temperature and humidity sensor.
The DHT20 is a humidity and temperature sensor.
The sensor has a fixed address of 0x38. It is not known if the address can be changed.
The library must be initiated by calling the begin() function.
Thereafter one has to call the read() function to do the actual reading, and call getTemperature() and getHumidity() to get the measured values. Calling these latter again will return the same values until a new read() is done.
The read() call of this sensor is blocking for 80+ milliseconds (datasheet 7.4) so the library also has a asynchronous interface. See below.
Since 0.1.3 and 0.1.4 the performance of read() has been optimized, still blocking but less long for about 45 milliseconds.
In #8 a bug is described that the sensor "freezes". Cause is not well understood.
Two solutions / workarounds are found:
Note: setting the I2C clock possibly interferes with other devices on the I2C bus, so it is not a solution in the end.
The 0.2.0 version embeds the resetSensor() into requestData() to reset the sensor if needed in both synchronous and asynchronous calls. This keeps the API simple. The reads are 1-2 ms slower than 0.1.4. (< 50 ms). Still far below the 80 ms mentioned in the datasheet.
Version 0.3.0 introduced a breaking change. You cannot set the pins in begin() any more. This reduces the dependency of processor dependent Wire implementations. The user has to call Wire.begin() and can optionally set the Wire pins before calling begin().
Verified to work with Arduino UNO and ESP32 and ESP8266 (see #8) Please let me know if other platforms work (or not).
The sensor has a fixed address of 0x38. It is not known if the address can be changed.
Sometimes you need to control more devices than possible with the default address range the device provides. This is possible with an I2C multiplexer e.g. TCA9548 which creates up to eight channels (think of it as I2C subnets) which can use the complete address range of the device.
Drawback of using a multiplexer is that it takes more administration in your code e.g. which device is on which channel. This will slow down the access, which must be taken into account when deciding which devices are on which channel. Also note that switching between channels will slow down other devices too if they are behind the multiplexer.
Always check datasheet!
Front view
+--------------+
VDD ----| 1 |
SDA ----| 2 DHT20 |
GND ----| 3 |
SCL ----| 4 |
+--------------+
The datasheet states 400 KHz as the maximum speed. Below the results of a small test that works well up to 800 KHz.
Speed in KHz, Time in microseconds.
read()
Speed | Time | notes |
---|---|---|
100 | 44588 | default I2C speed |
200 | 43988 | |
400 | 44040 | datasheet maximum |
600 | 43224 | |
800 | 43988 |
ASYNC: requestData()
Speed | Time | notes |
---|---|---|
100 | 1676 | default I2C speed |
200 | 1384 | |
400 | 1240 | datasheet maximum |
600 | 1188 | |
800 | 1168 |
ASYNC: readData()
Speed | Time | notes |
---|---|---|
100 | 832 | default I2C speed |
200 | 464 | |
400 | 284 | datasheet maximum |
600 | 212 | |
800 | 188 |
The numbers indicate that the conversion takes > 40 milliseconds. Requesting the measurement and fetching the data < 2.5 milliseconds.
Using the asynchronous interface frees up a lot of clock cycles. Going beyond 400 KHz (datasheet max) does not save much extra time, and should only be used if you are in a need for speed.
#include "DHT20.h"
There are two timings that need to be considered (from datasheet):
The async interface allows one to continue processing after a requestData() has been made. Note there should be at least 1000 milliseconds between subsequent requests.
With bool isMeasuring() one can check if a new measurement is ready. Alternative is to delay for up to 80 ms. If so the sensor can be read with readData().
To interpret the read bits to temperature, humidity and status one needs to call convert() as last step.
See the example DHT20_async.ino
status bit | meaning |
---|---|
7 | 1 = measurement, 0 = idle |
6 - 4 | unknown |
3 | 1 = calibrated, 0 = not |
2 - 0 | unknown |
Use with care!
The call is needed to get the read() working well so it has been embedded into the read calls. (0.2.0)
name | value | notes |
---|---|---|
DHT20_OK | 00 | OK |
DHT20_ERROR_CHECKSUM | -10 | values might be OK if they are like recent previous ones. |
DHT20_ERROR_CONNECT | -11 | check connection |
DHT20_MISSING_BYTES | -12 | check connection |
DHT20_ERROR_BYTES_ALL_ZERO | -13 | check connection |
DHT20_ERROR_READ_TIMEOUT | -14 | |
DHT20_ERROR_LASTREAD | -15 | wait 1 second between reads |
If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.
Thank you,