Skip to content

Commit

Permalink
update async interface + some examples (#2)
Browse files Browse the repository at this point in the history
* update async interface
* update examples
* minor edits
  • Loading branch information
RobTillaart authored Sep 11, 2022
1 parent 225ba22 commit 8081424
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 72 deletions.
50 changes: 27 additions & 23 deletions DHT20.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
//
// FILE: DHT20.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
//
// HISTORY:
// 0.1.0 2022-01-11 initial version (based upon DHT20)

// 0.1.0 2022-01-11 initial version (based upon DHT20 datasheet)
// 0.1.1 2022-09-10 add hardware schema to readme.md.
// fix async interface (first version)


#include "DHT20.h"

#define DHT20_ACQUISITION_TIME 85

const uint8_t DHT20_ADDRESS = 0x38;


Expand Down Expand Up @@ -57,25 +60,26 @@ bool DHT20::isConnected()
}


bool DHT20::readyData()
{
return ((millis() - _lastRequest) > 85);
}


int DHT20::read()
{
// READ SENSOR ==> uses the async interface!
// READ SENSOR ==> uses the async interface!
// check lastRead!
int status = _requestData();
if (status < 0) return status;
while (!readyData())
while ((millis() - _lastRequest) <= DHT20_ACQUISITION_TIME)
{
yield();
delay(1);
}
_readData();

// CONVERT AND STORE
return convert();
}


int DHT20::convert()
{
// CONVERT AND STORE
_status = _bits[0];
uint32_t tmp = _bits[1];
tmp <<= 8;
Expand All @@ -91,11 +95,11 @@ int DHT20::read()
tmp += _bits[5];
_temperature = tmp * 1.9073486328125e-4 - 50; // ==> / 1048576.0 * 200 - 50;

// TEST CHECKSUM
// TEST CHECKSUM
uint8_t _crc = _crc8(_bits, 6);
// Serial.print(_crc, HEX);
// Serial.print("\t");
// Serial.println(_bits[6], HEX);
// Serial.print(_crc, HEX);
// Serial.print("\t");
// Serial.println(_bits[6], HEX);
if (_crc != _bits[6]) return DHT20_ERROR_CHECKSUM;

return DHT20_OK;
Expand All @@ -104,7 +108,7 @@ int DHT20::read()

int DHT20::_requestData()
{
// GET CONNECTION
// GET CONNECTION
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0xAC);
_wire->write(0x33);
Expand All @@ -118,7 +122,7 @@ int DHT20::_requestData()

int DHT20::_readData()
{
// GET DATA
// GET DATA
const uint8_t length = 7;
int bytes = _wire->requestFrom(DHT20_ADDRESS, length);

Expand All @@ -128,11 +132,11 @@ int DHT20::_readData()
for (int i = 0; i < bytes; i++)
{
_bits[i] = _wire->read();
// if (_bits[i] < 0x10) Serial.print(0);
// Serial.print(_bits[i], HEX);
// Serial.print(" ");
// if (_bits[i] < 0x10) Serial.print(0);
// Serial.print(_bits[i], HEX);
// Serial.print(" ");
}
// Serial.println();
// Serial.println();

_lastRead = millis();
return bytes;
Expand All @@ -141,7 +145,7 @@ int DHT20::_readData()

int DHT20::_readStatus()
{
// GET CONNECTION
// GET CONNECTION
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0xAC);
_wire->write(0x71);
Expand Down
27 changes: 19 additions & 8 deletions DHT20.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,35 @@
// FILE: DHT20.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
// VERSION: 0.1.0
// VERSION: 0.1.1
// HISTORY: See DHT20.cpp
// URL: https://github.com/RobTillaart/DHT20
//

// Always check datasheet - front view
//
// +--------------+
// VDD ----| 1 |
// SDA ----| 2 DHT20 |
// GND ----| 3 |
// SCL ----| 4 |
// +--------------+


#include "Arduino.h"
#include "Wire.h"

#define DHT20_LIB_VERSION (F("0.1.0"))
#define DHT20_LIB_VERSION (F("0.1.1"))

#define DHT20_OK 0
#define DHT20_ERROR_CHECKSUM -10
#define DHT20_ERROR_CONNECT -11
#define DHT20_MISSING_BYTES -12


#define DHT20_ACQUISITION_TIME 85


class DHT20
{
public:
Expand All @@ -31,24 +43,23 @@ class DHT20
bool begin();
bool isConnected();

// ASYNCHRONUOUS CALL
// ASYNCHRONUOUS CALL
int requestData() { return _requestData(); };
bool readyData();
int readData() { return _readData(); };
int convert();


// SYNCHRONUOUS CALL
// SYNCHRONUOUS CALL
int read();
float getHumidity() { return _humidity + _humOffset; };
float getTemperature() { return _temperature + _tempOffset; };

// allows 1st order calibration
// allows 1st order calibration
void setHumOffset(float offset) { _humOffset = offset; };
void setTempOffset(float offset) { _tempOffset = offset; };
float getHumOffset() { return _humOffset; };
float getTempOffset() { return _tempOffset; };

// OTHER
// OTHER
uint32_t lastRead() { return _lastRead; };
uint32_t lastRequest() { return _lastRequest; };
int internalStatus() { return _status; };
Expand Down
67 changes: 56 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ The **read()** call of this sensor is blocking for 80+ milliseconds (datasheet 7
so the library also has a asynchronous interface. See below.


## Connection

Always check datasheet

Front view
```
+--------------+
VDD ----| 1 |
SDA ----| 2 DHT20 |
GND ----| 3 |
SCL ----| 4 |
+--------------+
```

## Tested

Examples verified to work with Arduino UNO and ESP32.


## Interface


Expand Down Expand Up @@ -53,14 +72,33 @@ It returns the status of the read which should be 0.

### Asynchronous interface

The async interface allows one to continue processing after a **requestData()** has been made.
One can check **readyData()** and if it returns true, enough time has
passed to make the measurement and the sensor can be read with **readData()**.
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.

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.

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()**.

To interpret the read bits to temperature, humidity and status one needs to call **convert()** as last step.


- **int requestData()** signals the sensor to make a new measurement.
- **bool readyData()** returns true if 85 milliseconds have passed since the last **requestData()** call.
The time of 85 ms is hard coded.
Note there must be at least 1000 milliseconds between requests!
- **int readData()** does the actual reading of the data.
- **int convert()** converts the read bits to temperature and humidity.

See the example **DHT20_async.ino**

In the .h file there is a line
```cpp
#define DHT20_ACQUISITION_TIME 85
```
This can be used to optimize performance a bit. Use with care.


### Miscellaneous
Expand Down Expand Up @@ -89,23 +127,30 @@ See examples

## Future

#### must

- update documentation
- improve the code
- check return codes etc.
- add missing error codes
- describe async interface
- **read()** should check lastRead() and return ERROR_LASTREAD

#### should

- test more in detail
- test on ESP32
- add examples
- asynchronous

#### could

- improve unit tests.
- improve the code (check return codes etc.)
- investigate
- status register bits
- sensor calibration (website aosong?)
- check for optimizations.
- mainly for asynchronous
- test at different I2C speeds 400 KHz should be possible.
- 85 ms wait time?
- add examples
- asynchronous
-


#### won't
Expand Down
64 changes: 42 additions & 22 deletions examples/DHT20/DHT20.ino
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@
// 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();
DHT.begin(); // ESP32 default pins 21 22

Wire.setClock(400000);

Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DHT20 LIBRARY VERSION: ");
Expand All @@ -24,7 +34,7 @@ void setup()

delay(2000);

Serial.println("Type,\tStatus,\tHumidity (%),\tTemperature (C)");

}


Expand All @@ -36,31 +46,41 @@ void loop()
uint32_t start = micros();
int status = DHT.read();
uint32_t stop = micros();
switch (status)

if ((count % 10) == 0)
{
case DHT20_OK:
Serial.print("OK,\t");
break;
case DHT20_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
case DHT20_ERROR_CONNECT:
Serial.print("Connect error,\t");
break;
case DHT20_MISSING_BYTES:
Serial.print("Missing bytes,\t");
break;
default:
Serial.print("Unknown error,\t");
break;
count = 0;
Serial.println();
Serial.println("Type\tHumidity (%)\tTemp (°C)\tTime (µs)\tStatus");
}
count++;

Serial.print("DHT20 \t");
// DISPLAY DATA, sensor has only one decimal.
Serial.print("DHT20, \t");
Serial.print(DHT.getHumidity(), 1);
Serial.print(",\t");
Serial.print("\t\t");
Serial.print(DHT.getTemperature(), 1);
Serial.print(",\t");
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;
default:
Serial.print("Unknown error");
break;
}
Serial.print("\n");
}
}
Expand Down
Loading

0 comments on commit 8081424

Please sign in to comment.