Skip to content

Commit

Permalink
add resetSensor() (#7)
Browse files Browse the repository at this point in the history
* add resetSensor()
* stabilize readStatus() 
* add examples
* improve comments in code
* update readme.md
  • Loading branch information
RobTillaart authored Sep 18, 2022
1 parent eee6f5a commit 2fc2c11
Show file tree
Hide file tree
Showing 11 changed files with 269 additions and 42 deletions.
67 changes: 63 additions & 4 deletions DHT20.cpp
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -89,7 +112,6 @@ int DHT20::read()
while (isMeasuring())
{
yield();
delay(1);
}
// read the measurement
status = readData();
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -249,7 +273,7 @@ int DHT20::internalStatus()

////////////////////////////////////////////////
//
// OTHER
// TIMING
//
uint32_t DHT20::lastRead()
{
Expand Down Expand Up @@ -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 --

42 changes: 34 additions & 8 deletions DHT20.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
//
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -87,6 +110,9 @@ class DHT20

uint8_t _crc8(uint8_t *ptr, uint8_t len);

// use with care
bool _resetRegister(uint8_t reg);

TwoWire* _wire;
};

Expand Down
54 changes: 32 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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.

Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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.
-


4 changes: 1 addition & 3 deletions examples/DHT20/DHT20.ino
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ void setup()
Serial.println(DHT20_LIB_VERSION);
Serial.println();

delay(2000);


delay(1000);
}


Expand Down
2 changes: 2 additions & 0 deletions examples/DHT20/performance_0.1.2.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions examples/DHT20/performance_0.1.3.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading

0 comments on commit 2fc2c11

Please sign in to comment.