0.1.4 DHT20

This commit is contained in:
rob tillaart 2022-09-18 19:13:39 +02:00
parent 813f47d39f
commit ebb638e2b6
11 changed files with 269 additions and 42 deletions

View File

@ -1,7 +1,7 @@
//
// FILE: DHT20.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// VERSION: 0.1.4
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
//
// HISTORY:
@ -12,15 +12,21 @@
// fix keywords
// add readStatus() fix _readStatus()
// add setWireTimeout(250000, true); // in comments
// 0.1.3 2022-09-xx add wrapper status functions
// 0.1.3 2022-09-17 add wrapper status functions
// improve performance read()
// refactor, update readme.md
// 0.1.4 2022-09-18 add resetSensor() code.
// add comments in .h file
// add examples
// stabilize readStatus()
// update readme.md
#include "DHT20.h"
// set DHT20_WIRE_TIME_OUT to 0 to disable.
// note this timeout is commented in code below.
#define DHT20_WIRE_TIME_OUT 250000 // microseconds
const uint8_t DHT20_ADDRESS = 0x38;
@ -71,6 +77,23 @@ bool DHT20::isConnected()
}
// See datasheet 7.4 Sensor Reading Process, point 1
// use with care.
uint8_t DHT20::resetSensor()
{
uint8_t count = 255;
if ((readStatus() & 0x18) != 0x18)
{
count++;
if (_resetRegister(0x1B)) count++;
if (_resetRegister(0x1C)) count++;
if (_resetRegister(0x1E)) count++;
delay(10);
}
return count;
}
////////////////////////////////////////////////
//
// READ THE SENSOR
@ -89,7 +112,6 @@ int DHT20::read()
while (isMeasuring())
{
yield();
delay(1);
}
// read the measurement
status = readData();
@ -218,7 +240,9 @@ uint8_t DHT20::readStatus()
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0x71);
_wire->endTransmission();
delay(1); // needed to stabilize timing
_wire->requestFrom(DHT20_ADDRESS, (uint8_t)1);
delay(1); // needed to stabilize timing
return (uint8_t) _wire->read();
}
@ -249,7 +273,7 @@ int DHT20::internalStatus()
////////////////////////////////////////////////
//
// OTHER
// TIMING
//
uint32_t DHT20::lastRead()
{
@ -290,5 +314,40 @@ uint8_t DHT20::_crc8(uint8_t *ptr, uint8_t len)
}
// Code based on demo code sent by www.aosong.com
// no further documentation.
// 0x1B returned 18, 0, 4
// 0x1C returned 18, 65, 0
// 0x1E returned 18, 8, 0
// 18 seems to be status register
// other values unknown.
bool DHT20::_resetRegister(uint8_t reg)
{
uint8_t value[3];
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(reg);
_wire->write(0x00);
_wire->write(0x00);
if (_wire->endTransmission() != 0) return false;
delay(5);
int bytes = _wire->requestFrom(DHT20_ADDRESS, 3);
for (int i = 0; i < bytes; i++)
{
value[i] = _wire->read();
// Serial.println(value[i], HEX);
}
delay(10);
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0xB0 | reg);
_wire->write(value[1]);
_wire->write(value[2]);
if (_wire->endTransmission() != 0) return false;
delay(5);
return true;
}
// -- END OF FILE --

View File

@ -3,7 +3,7 @@
// FILE: DHT20.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
// VERSION: 0.1.3
// VERSION: 0.1.4
// HISTORY: See DHT20.cpp
// URL: https://github.com/RobTillaart/DHT20
//
@ -21,7 +21,7 @@
#include "Arduino.h"
#include "Wire.h"
#define DHT20_LIB_VERSION (F("0.1.3"))
#define DHT20_LIB_VERSION (F("0.1.4"))
#define DHT20_OK 0
#define DHT20_ERROR_CHECKSUM -10
@ -32,48 +32,71 @@
#define DHT20_ERROR_LASTREAD -15
#define DHT20_ACQUISITION_TIME 85
class DHT20
{
public:
DHT20(TwoWire *wire = &Wire); // to be tested explicitly
// CONSTRUCTOR
// fixed address 0x38
DHT20(TwoWire *wire = &Wire);
// start the I2C
#if defined(ESP8266) || defined(ESP32)
bool begin(const uint8_t dataPin, const uint8_t clockPin);
#endif
bool begin();
bool isConnected();
// ASYNCHRONUOUS CALL
// trigger acquisition.
int requestData();
// read the raw data.
int readData();
// converts raw databits to temperature and humidity.
int convert();
// SYNCHRONUOUS CALL
// blocking read call to read + convert data
int read();
// access the converted temperature & humidity
float getHumidity();
float getTemperature();
// CALIBRATION 1st order
// OFFSET 1st order adjustments
void setHumOffset(float offset);
void setTempOffset(float offset);
float getHumOffset();
float getTempOffset();
// READ STATUS
uint8_t readStatus();
// 3 wrapper functions around readStatus()
bool isCalibrated();
bool isMeasuring();
bool isIdle();
// status from last read()
int internalStatus();
// OTHER
// TIMING
uint32_t lastRead();
uint32_t lastRequest();
// RESET (new since 0.1.4)
// use with care
// returns number of registers reset => must be 3
// 3 = OK
// 0,1,2 = error.
// 255 = no reset needed.
// See datasheet 7.4 Sensor Reading Process, point 1
// use with care
uint8_t resetSensor();
private:
float _humidity;
float _temperature;
@ -87,6 +110,9 @@ private:
uint8_t _crc8(uint8_t *ptr, uint8_t len);
// use with care
bool _resetRegister(uint8_t reg);
TwoWire* _wire;
};

View File

@ -23,10 +23,11 @@ Calling these latter again will return the same values until a new **read()** is
The **read()** call of this sensor is blocking for 80+ milliseconds (datasheet 7.4)
so the library also has a asynchronous interface. See below.
Verified to work with Arduino UNO and ESP32.
Since 0.1.3 and 0.1.4 the performance of **read()** has been optimized,
still blocking but less long for about 45 milliseconds.
## Connection
### Connection
Always check datasheet
@ -40,9 +41,10 @@ Front view
+--------------+
```
## Tested
### Tested
Examples verified to work with Arduino UNO and ESP32.
Verified to work with Arduino UNO and ESP32.
Please let me know if other platforms work (or not).
## Interface
@ -74,17 +76,15 @@ It returns the status of the read which should be 0.
### Asynchronous interface
Note the async interface is not 100% functional yet.
Expect functional complete in 0.2.0.
There are two timings that need to be considdered,
- time between requests = 1000 ms
- time between request and data ready.
- time between request and data ready = 80 ms
The async interface allows one to continue processing whatever after a **requestData()** has been made. Note that there should be at least **1000 milliseconds** between subsequent requests.
The async interface allows one to continue processing after a **requestData()** has been made.
Note that there should be at least **1000 milliseconds** between subsequent requests.
After **DHT20_ACQUISITION_TIME == 85 ms** enough time after the request has
passed to read the data of the measurement. So the sensor can be read with **readData()**.
With **bool isMeasuring()** one can check if a new measurement is ready.
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.
@ -100,19 +100,31 @@ See the example **DHT20_async.ino**
### Status
- **uint8_t readStatus()** forced read of the status only.
This function blocks a few milliseconds to optimize communication.
- **bool isCalibrated()** idem, wrapper around **readStatus()**
- **bool isMeasuring()** idem, wrapper around **readStatus()**
- **bool isIdle()** idem, wrapper around **readStatus()**
- **int internalStatus()** returns the internal status of the sensor. (debug ).
- **int internalStatus()** returns the internal status of the sensor. (for debug).
| status bit | meaning |
|:------------:|:---------------------------|
| 7 | busy making measurement |
| 7 | 1 = measurement, 0 = idle |
| 6 - 4 | unknown |
| 3 | 1 = calibrated, 0 is not |
| 3 | 1 = calibrated, 0 = not |
| 2 - 0 | unknown |
#### Experimental 0.1.4 resetSensor
Use with care, as this is not tested.
- **uint8_t resetSensor()** if at startup the sensor does not return a status of 0x18,
three registers 0x1B, 0x1C and 0x1E need to be reset.
See datasheet 7.4 Sensor Reading Process, point 1.
There is no documentation about the meaning of these registers.
The code is based upon example code for the AHT20 (from manufacturer).
### Timing
- **uint32_t lastRead()** last time the sensor is read in milliseconds since start.
@ -129,7 +141,7 @@ See the example **DHT20_async.ino**
| DHT20_MISSING_BYTES | -12 | check connection
| DHT20_ERROR_BYTES_ALL_ZERO | -13 | check connection
| DHT20_ERROR_READ_TIMEOUT | -14 |
| DHT20_ERROR_LASTREAD | -15 |
| DHT20_ERROR_LASTREAD | -15 | wait 1 second between reads
## Operation
@ -141,26 +153,24 @@ See examples
#### must
- update documentation
- comments in .h file
#### should
- add examples
- check TODO's in code.
#### could
- improve unit tests.
- investigate
- sensor calibration (website aosong?)
- investigate optimizing timing in readStatus()
- delay(1) ==> microSeconds(???).
- separate changelog.md
- connected flag?
#### won't
- **void setIgnoreChecksum(bool = false)** ignore checksum flag speeds up communication a bit
- **bool getIgnoreChecksum()** get status. for completeness.
- **bool getIgnoreChecksum()** get checksum flag. for completeness.
-

View File

@ -32,9 +32,7 @@ void setup()
Serial.println(DHT20_LIB_VERSION);
Serial.println();
delay(2000);
delay(1000);
}

View File

@ -1,6 +1,8 @@
...Arduino\libraries\DHT20\examples\DHT20\DHT20.ino
DHT20 LIBRARY VERSION: 0.1.2
IDE 1.8.19
Arduino UNO
Type Humidity (%) Temp (°C) Time (µs) Status
DHT20 70.8 21.4 86701 OK

View File

@ -1,6 +1,8 @@
...Arduino\libraries\DHT20\examples\DHT20\DHT20.ino
DHT20 LIBRARY VERSION: 0.1.3
IDE 1.8.19
Arduino UNO
Type Humidity (%) Temp (°C) Time (µs) Status
DHT20 61.4 21.5 54684 OK

View File

@ -0,0 +1,18 @@
...Arduino\libraries\DHT20\examples\DHT20\DHT20.ino
DHT20 LIBRARY VERSION: 0.1.4
IDE 1.8.19
Arduino UNO
Type Humidity (%) Temp (°C) Time (µs) Status
DHT20 56.6 21.7 44136 OK
DHT20 56.6 21.7 44136 OK
DHT20 56.7 21.7 44144 OK
DHT20 57.0 21.7 44140 OK
DHT20 57.4 21.7 44136 OK
DHT20 57.7 21.7 44140 OK
DHT20 58.1 21.7 44148 OK
DHT20 58.5 21.7 44140 OK
DHT20 58.7 21.7 44132 OK
DHT20 59.2 21.8 44140 OK

View File

@ -0,0 +1,108 @@
//
// FILE: DHT20_offset.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Demo for DHT20 I2C humidity & temperature sensor
//
// Always check datasheet - front view
//
// +--------------+
// VDD ----| 1 |
// SDA ----| 2 DHT20 |
// GND ----| 3 |
// SCL ----| 4 |
// +--------------+
#include "DHT20.h"
DHT20 DHT;
uint8_t count = 0;
void setup()
{
DHT.begin(); // ESP32 default pins 21 22
Wire.setClock(400000);
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DHT20 LIBRARY VERSION: ");
Serial.println(DHT20_LIB_VERSION);
Serial.println();
delay(1000);
}
void loop()
{
// set an offset after 10 seconds.
if (millis() > 10000)
{
DHT.setTempOffset(1.7);
DHT.setHumOffset(-2.3);
}
// make a measurement every 2 seconds
if (millis() - DHT.lastRead() >= 2000)
{
// READ DATA
uint32_t start = micros();
int status = DHT.read();
uint32_t stop = micros();
if ((count % 10) == 0)
{
count = 0;
Serial.println();
Serial.println("Type\tHumidity (%)\tTemp (°C)\tTime (µs)\tStatus\tOffset");
}
count++;
Serial.print("DHT20 \t");
// DISPLAY DATA, sensor has only one decimal.
Serial.print(DHT.getHumidity(), 1);
Serial.print("\t\t");
Serial.print(DHT.getTemperature(), 1);
Serial.print("\t\t");
Serial.print(stop - start);
Serial.print("\t\t");
switch (status)
{
case DHT20_OK:
Serial.print("OK");
break;
case DHT20_ERROR_CHECKSUM:
Serial.print("Checksum error");
break;
case DHT20_ERROR_CONNECT:
Serial.print("Connect error");
break;
case DHT20_MISSING_BYTES:
Serial.print("Missing bytes");
break;
case DHT20_ERROR_BYTES_ALL_ZERO:
Serial.print("All bytes read zero");
break;
case DHT20_ERROR_READ_TIMEOUT:
Serial.print("Read time out");
break;
case DHT20_ERROR_LASTREAD:
Serial.print("Error read too fast");
break;
default:
Serial.print("Unknown error");
break;
}
Serial.print("\t");
Serial.print(DHT.getHumOffset());
Serial.print("\t");
Serial.print(DHT.getTempOffset());
Serial.print("\n");
}
}
// -- END OF FILE --

View File

@ -20,13 +20,17 @@ setTempOffset KEYWORD2
getHumOffset KEYWORD2
getTempOffset KEYWORD2
lastRead KEYWORD2
lastRequest KEYWORD2
internalStatus KEYWORD2
readStatus KEYWORD2
isCalibrated KEYWORD2
isMeasuring KEYWORD2
isIdle KEYWORD2
internalStatus KEYWORD2
lastRead KEYWORD2
lastRequest KEYWORD2
resetSensor KEYWORD2
# Constants (LITERAL1)
DHT20_LIB_VERSION LITERAL2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/DHT20.git"
},
"version": "0.1.3",
"version": "0.1.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=DHT20
version=0.1.3
version=0.1.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for I2C DHT20 temperature and humidity sensor.