Skip to content

Commit

Permalink
improve performance read() (#6)
Browse files Browse the repository at this point in the history
* improve performance read()
* refactor
  • Loading branch information
RobTillaart authored Sep 17, 2022
1 parent 6232655 commit eee6f5a
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 92 deletions.
180 changes: 138 additions & 42 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.2
// VERSION: 0.1.3
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
//
// HISTORY:
Expand All @@ -12,15 +12,16 @@
// fix keywords
// add readStatus() fix _readStatus()
// add setWireTimeout(250000, true); // in comments
// 0.1.3 2022-09-xx add wrapper status functions
// improve performance read()
// refactor, update readme.md


#include "DHT20.h"


#define DHT20_ACQUISITION_TIME 85 // milliseconds

// set DHT20_WIRE_TIME_OUT to 0 to disable.
#define DHT20_WIRE_TIME_OUT 250000 // microseconds
#define DHT20_WIRE_TIME_OUT 250000 // microseconds

const uint8_t DHT20_ADDRESS = 0x38;

Expand Down Expand Up @@ -70,57 +71,36 @@ bool DHT20::isConnected()
}


////////////////////////////////////////////////
//
// READ THE SENSOR
//
int DHT20::read()
{
// READ SENSOR ==> uses the async interface!
// check lastRead!
int status = _requestData();
// do not read to fast
if (millis() - _lastRead < 1000)
{
return DHT20_ERROR_LASTREAD;
}

int status = requestData();
if (status < 0) return status;
// wait for measurement ready
while ((millis() - _lastRequest) <= DHT20_ACQUISITION_TIME)
while (isMeasuring())
{
yield();
delay(1);
}
// read the measurement
status = _readData();
status = readData();
if (status < 0) return status;

// convert it to meaningfull data
return convert();
}


int DHT20::convert()
{
// CONVERT AND STORE
_status = _bits[0];
uint32_t tmp = _bits[1];
tmp <<= 8;
tmp += _bits[2];
tmp <<= 4;
tmp += (_bits[3] >> 4);
_humidity = tmp * 9.5367431640625e-5; // ==> / 1048576.0 * 100%;

tmp = (_bits[3] & 0x0F);
tmp <<= 8;
tmp += _bits[4];
tmp <<= 8;
tmp += _bits[5];
_temperature = tmp * 1.9073486328125e-4 - 50; // ==> / 1048576.0 * 200 - 50;

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

return DHT20_OK;
}


int DHT20::_requestData()
int DHT20::requestData()
{
// GET CONNECTION
_wire->beginTransmission(DHT20_ADDRESS);
Expand All @@ -134,7 +114,7 @@ int DHT20::_requestData()
}


int DHT20::_readData()
int DHT20::readData()
{
// GET DATA
const uint8_t length = 7;
Expand All @@ -160,17 +140,133 @@ int DHT20::_readData()
}


uint8_t DHT20::_readStatus()
int DHT20::convert()
{
// CONVERT AND STORE
_status = _bits[0];
uint32_t raw = _bits[1];
raw <<= 8;
raw += _bits[2];
raw <<= 4;
raw += (_bits[3] >> 4);
_humidity = raw * 9.5367431640625e-5; // ==> / 1048576.0 * 100%;

raw = (_bits[3] & 0x0F);
raw <<= 8;
raw += _bits[4];
raw <<= 8;
raw += _bits[5];
_temperature = raw * 1.9073486328125e-4 - 50; // ==> / 1048576.0 * 200 - 50;

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

return DHT20_OK;
}


////////////////////////////////////////////////
//
// TEMPERATURE & HUMIDITY & OFFSET
//
float DHT20::getHumidity()
{
return _humidity + _humOffset;
};


float DHT20::getTemperature()
{
return _temperature + _tempOffset;
};


void DHT20::setHumOffset(float offset)
{
_humOffset = offset;
};


void DHT20::setTempOffset(float offset)
{
_tempOffset = offset;
};


float DHT20::getHumOffset()
{
return _humOffset;
};


float DHT20::getTempOffset()
{
return _tempOffset;
};


////////////////////////////////////////////////
//
// STATUS
//
uint8_t DHT20::readStatus()
{
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0x71);
_wire->endTransmission();

_wire->requestFrom(DHT20_ADDRESS, (uint8_t)1);
return (uint8_t) _wire->read();
}


bool DHT20::isCalibrated()
{
return (readStatus() & 0x08) == 0x08;
}


bool DHT20::isMeasuring()
{
return (readStatus() & 0x80) == 0x80;
}


bool DHT20::isIdle()
{
return (readStatus() & 0x80) == 0x00;
}


int DHT20::internalStatus()
{
return _status;
};


////////////////////////////////////////////////
//
// OTHER
//
uint32_t DHT20::lastRead()
{
return _lastRead;
};


uint32_t DHT20::lastRequest()
{
return _lastRequest;
};


////////////////////////////////////////////////
//
// PRIVATE
//
uint8_t DHT20::_crc8(uint8_t *ptr, uint8_t len)
{
uint8_t crc = 0xFF;
Expand Down
46 changes: 25 additions & 21 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.2
// VERSION: 0.1.3
// HISTORY: See DHT20.cpp
// URL: https://github.com/RobTillaart/DHT20
//
Expand All @@ -21,13 +21,15 @@
#include "Arduino.h"
#include "Wire.h"

#define DHT20_LIB_VERSION (F("0.1.2"))
#define DHT20_LIB_VERSION (F("0.1.3"))

#define DHT20_OK 0
#define DHT20_ERROR_CHECKSUM -10
#define DHT20_ERROR_CONNECT -11
#define DHT20_MISSING_BYTES -12
#define DHT20_ERROR_BYTES_ALL_ZERO -13
#define DHT20_ERROR_READ_TIMEOUT -14
#define DHT20_ERROR_LASTREAD -15


#define DHT20_ACQUISITION_TIME 85
Expand All @@ -45,40 +47,42 @@ class DHT20
bool isConnected();

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

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

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

// CALIBRATION 1st order
void setHumOffset(float offset);
void setTempOffset(float offset);
float getHumOffset();
float getTempOffset();

// READ STATUS
uint8_t readStatus();
bool isCalibrated();
bool isMeasuring();
bool isIdle();
int internalStatus();

// OTHER
uint32_t lastRead() { return _lastRead; };
uint32_t lastRequest() { return _lastRequest; };
int internalStatus() { return _status; };
// forced read status
uint8_t readStatus() { return _readStatus(); };
uint32_t lastRead();
uint32_t lastRequest();


private:
float _humidity;
float _temperature;
float _humOffset;
float _tempOffset;

uint8_t _status;
uint32_t _lastRequest;
uint32_t _lastRead;

int _requestData();
int _readData();
uint8_t _readStatus();
uint8_t _bits[7];

uint8_t _crc8(uint8_t *ptr, uint8_t len);
Expand Down
Loading

0 comments on commit eee6f5a

Please sign in to comment.