Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Nov 24, 2024
1 parent 6d6a3aa commit 088b6bf
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 86 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.5.1] - 2024-11-24
- fix #102, add support for KY015
- add three examples, dhtnew_dht11.ino, dhtnew_dht22.ino, dhtnew_simple.ino
- optimize decimal part DHT11 (type == 11)
- minor fix setType(23), could be bug.
- minor fix temperature conversion (-0.0)
- add offset functions with full name version (readability),
- short ones will become obsolete in the future
- update readme.md

## [0.5.0] - 2024-11-22
Expand Down
70 changes: 53 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,27 @@ As the AM2321 and AM2322 are quite identical according to the datasheet, those a

To use the library one should call **setType(22)** as the protocol is identical to the DHT22.
If there are differences in operation type (23) will be elaborated.
The value 23 is now mapped upon 22 code.
The type 23 is now mapped upon type 22.

Feedback (both positive and negative) about the AM232X sensors is welcome.

**Note: check the datasheet how to connect!**


### KY-015

Since 0.5.1 there is **experimental** support for the KY-015, which is a DHT11 (sort of).
Not tested myself but the KY-015 is confirmed to work, see https://github.com/RobTillaart/DHTNew/issues/102
Although it is a DHT11, the KY-015 was recognized as a DHT22 resulting in faulty conversions.

The library sensor recognition code has been adapted so it should be recognized.
In the case this fails, one can use **setType(11)** to force the type.

Feedback about the KY-015 sensors is welcome.

**Note: check the datasheet how to connect!**


### 0.5.0 Negative temperature

Apparently there are DHT22's which use another representation for negative temperatures.
Expand Down Expand Up @@ -85,11 +99,13 @@ See also https://arduino.stackexchange.com/questions/86448/dht22-sensor-reading-
| pin 3 | | Not Connected |
| pin 4 | | GND |

**Note: check the datasheet how to connect!**
**Note: check the datasheet of the sensor how to connect!** as some have only 3 pins.


## Specification DHT22

As most used model, for other sensors I refer to datasheet.

| Model | DHT22 | Notes |
|:----------------------------|:-------------------------|:--------|
| Power supply | 3.3 - 6.0 V DC |
Expand All @@ -115,21 +131,22 @@ See also https://arduino.stackexchange.com/questions/86448/dht22-sensor-reading-
### Constructor

- **DHTNEW(uint8_t pin)** defines the dataPin of the sensor.
- **void reset()** might help to reset a sensor behaving badly. It does reset the library settings to default,
- **void reset()** might help to reset a sensor behaving badly.
It resets the library internal settings to default,
however it does not reset the sensor in a hardware way.
- **uint8_t getType()** 0 = unknown, 11 or 22.
In case of 0, **getType()** will try to determine type.
Since 0.4.14 type 70 is added for **experimental** Sonoff Si7021 support.
- **void setType(uint8_t type = 0)** allows to force the type of the sensor.

| Type | Sensors | Notes |
|:-------:|:---------------:|:--------|
| 0 | not defined |
| 11 | DHT11 |
| 22 | DHT22 a.o | most others
| 23 | DHT22 a.o | mapped to 22 for now
| 70 | Sonoff Si7021 | experimental
| other | sets to 0 | 0.4.20
| Type | Sensors | Notes |
|:-------:|:-------------------------:|:--------|
| 0 | not defined |
| 11 | DHT11 DHT12, KY015 | KY015 needs setType(11)
| 22 | DHT22, DHT33, DHT44 a.o | most others
| 23 | DHT23 | mapped to 22 for now
| 70 | Sonoff Si7021 | experimental
| other | sets to 0 | 0.4.20


### Base interface
Expand All @@ -149,10 +166,19 @@ Note this error value can be suppressed by **setSuppressError(bool)**.

Adding offsets works well in normal range however they might introduce
under- or overflow at the ends of the sensor range.
Humidity is in % RH.
Humidity is constrained to 0.0 - 100.0 % in the code.
Temperature is in degrees Celsius.
For temperature such constrain would be type dependant, so it is not done.

Humidity offset is in % RH and is constrained to 0.0 - 100.0 % in the code.

Temperature offset is in degrees Celsius.
For temperature a constrain would be type dependant, so it is not done.
Furthermore by setting the offset to -273.15 one get the **Kelvin** scale.

- **void setHumidityOffset(float offset)** typical < ±5% RH.
- **void setTemperatureOffset(float offset)** typical < ±2°C.
- **float getHumidityOffset()** idem.
- **float getTemperatureOffset()** idem.

The "short-named" offset functions will become obsolete in the future (0.6.0).

- **void setHumOffset(float offset)** typical < ±5% RH.
- **void setTempOffset(float offset)** typical < ±2°C.
Expand Down Expand Up @@ -311,7 +337,7 @@ updated readme.md - added badges and remarks after testing with MKR1010 Wifi.
updated TIMEOUT_C from 70 -> 90 us to minimize its occurrence - See https://github.com/RobTillaart/DHTNew/issues/67.
added ```while(!Serial);``` in examples to they work for MKR1010 Wifi.
27. (0.4.11)
update library.json, license, minor edits (cleanup), unit tests
update library.json, license, minor edits (clean up), unit tests
28. (0.4.12)
Fix #72, delayMicroseconds() for wakeUp
29. (0.4.13)
Expand All @@ -332,6 +358,10 @@ Update readme.md
Update GitHub actions and readme.md
36. (0.4.21)
Add dhtnew_pulse_diag_ext.ino
37. (0.5.0)
Fix negative values
38. (0.5.1)
Support KY015 and more.


## Future
Expand Down Expand Up @@ -360,11 +390,17 @@ if (type == 11) temp = constrain(temp, 0, 100);
if (type == 22) temp = constrain(temp, -40, 80);
etc.
```

- type parameter in constructor, default 0
- reimplement the recognition algorithm (separate class?)
- read as 22 => check the hum / temp data range to determine type
- read as 11 => check idem
- read as 70 => check idem
- split wakeup time from bit interpretation used.

#### Wont

- move all code from .h to .cpp
- derived classes for fixed type?


## Support
Expand Down
84 changes: 57 additions & 27 deletions dhtnew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@


// these defines are not for user to adjust (microseconds)
// it adds 10% above the data sheet to allow a margin.
#define DHTLIB_DHT11_WAKEUP (18 * 1100UL)
#define DHTLIB_DHT_WAKEUP (1 * 1100UL)
// experimental 0.4.14
Expand Down Expand Up @@ -45,19 +46,20 @@ void DHTNEW::reset()
pinMode(_dataPin, OUTPUT);
digitalWrite(_dataPin, HIGH);

_wakeupDelay = 0;
_type = 0;
_humOffset = 0.0;
_tempOffset = 0.0;
_humidity = 0.0;
_temperature = 0.0;
_lastRead = 0;
_disableIRQ = true;
_waitForRead = false;
_suppressError = false;
_readDelay = 0;
_wakeupDelay = 0;
_type = 0;
_humidityOffset = 0.0;
_temperatureOffset = 0.0;
_humidity = 0.0;
_temperature = 0.0;
_lastRead = 0;
_disableIRQ = true;
_waitForRead = false;
_suppressError = false;
_readDelay = 0;
#if defined(__AVR__)
_disableIRQ = false;
// overrule
_disableIRQ = false;
#endif
// #if defined(ARDUINO_SAMD_MKRWIFI1010) // fix for issue #67
// _disableIRQ = false;
Expand All @@ -80,7 +82,7 @@ void DHTNEW::setType(uint8_t type)

if ((type == 22) || (type == 23))
{
_type = type;
_type = 22; // cannot differentiate type;
_wakeupDelay = DHTLIB_DHT_WAKEUP;
}
else if (type == 11)
Expand Down Expand Up @@ -125,27 +127,49 @@ int DHTNEW::read()
}

// AUTODETECT
// make sure sensor had time to wake up.
// make sure sensor had time to wake up after start of sketch.
while (millis() < 1000);

// NOTE: we could add conversion H and T here and
// check if these are in the allowed range.
// humidity 0..100%, temperature 0..80C or -40..80C
// drawback: would increase footprint.

// NOTE: cannot differentiate between type 23 and 22
_type = 22;
_wakeupDelay = DHTLIB_DHT_WAKEUP;
int rv = _read();
if (rv == DHTLIB_OK) return rv;
if (rv == DHTLIB_OK)
{
// test data bits to check for KY015 see issue #102
// if it has DHT11 encoding.
// humidity cannot be over 100.0 % = 0x03E8 in DHT22 encoding
// test would incorrectly fail if there is a very low humidity
if (_bits[0] > 3)
{
_type = 11;
}
return rv;
}

_type = 11;
_wakeupDelay = DHTLIB_DHT11_WAKEUP;
rv = _read();
if (rv == DHTLIB_OK) return rv;
if (rv == DHTLIB_OK)
{
return rv;
}

// experimental 0.4.14
_type = 70;
_wakeupDelay = DHTLIB_SI7021_WAKEUP;
rv = _read();
if (rv == DHTLIB_OK) return rv;
if (rv == DHTLIB_OK)
{
return rv;
}

_type = 0; // retry next time
_type = 0; // retry next time
return rv;
}

Expand Down Expand Up @@ -185,10 +209,12 @@ int DHTNEW::_read()
return rv; // propagate error value
}

if (_type == 11) // DHT11, DH12, compatible
if (_type == 11) // DHT11, DH12, KY015 compatible
{
_humidity = _bits[0] + _bits[1] * 0.1;
_temperature = _bits[2] + _bits[3] * 0.1;
_humidity = _bits[0];
if (_bits[1]) _humidity += _bits[1] * 0.1;
_temperature = _bits[2];
if (_bits[3]) _temperature + _bits[3] * 0.1;
}
else // DHT22, DHT33, DHT44, compatible + Si7021
{
Expand All @@ -200,9 +226,12 @@ int DHTNEW::_read()
int16_t t = ((_bits[2] & 0x7F) * 256 + _bits[3]);
if (t == 0)
{
_temperature = 0.0; // prevent -0.0;
_temperature = 0.0; // prevents -0.0;
}
else
{
_temperature = t * 0.1;
}
_temperature = t * 0.1;
}
else // negative temperature
{
Expand Down Expand Up @@ -257,15 +286,16 @@ int DHTNEW::_read()
}
#endif

if (_humOffset != 0.0)
if (_humidityOffset != 0.0)
{
_humidity += _humOffset;
_humidity += _humidityOffset;
// constrain range
if (_humidity > 100) _humidity = 100;
else if (_humidity < 0) _humidity = 0;
}
if (_tempOffset != 0.0)
if (_temperatureOffset != 0.0)
{
_temperature += _tempOffset;
_temperature += _temperatureOffset;
}

// TEST CHECKSUM
Expand Down
61 changes: 37 additions & 24 deletions dhtnew.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,42 @@ class DHTNEW
// might help to reset a sensor behaving badly
void reset();

// 0 = unknown
// 11 = DHT11 and compatibles
// 22 = DHT22 and compatibles
// 23 = mapped to 22 for now (AM23xx)
// 70 = Sonoff Si7021
// TYPE MEANING
// ----------------
// 0 unknown, not set.
// 11 DHT11 and compatibles
// 22 DHT22 and compatibles
// 23 mapped to 22 for now (AM23xx)
// 70 Sonoff Si7021
uint8_t getType();
void setType(uint8_t type = 0);
int read();


// CORE FUNCTIONS
int read();
// lastRead is in MilliSeconds since start sketch
uint32_t lastRead() { return _lastRead; };

// preferred interface
float getHumidity() { return _humidity; };
float getTemperature() { return _temperature; };


// OFFSET
// adding offsets works well in normal range
// might introduce under- or overflow at the ends of the sensor range
void setHumOffset(float offset) { _humOffset = offset; };
void setTempOffset(float offset) { _tempOffset = offset; };
float getHumOffset() { return _humOffset; };
float getTempOffset() { return _tempOffset; };

// adding -273.15 offset to temperature gives Kelvin scale.
void setHumidityOffset(float offset) { _humidityOffset = offset; };
void setTemperatureOffset(float offset) { _temperatureOffset = offset; };
float getHumidityOffset() { return _humidityOffset; };
float getTemperatureOffset() { return _temperatureOffset; };
// future obsolete versions
void setHumOffset(float offset) { _humidityOffset = offset; };
void setTempOffset(float offset) { _temperatureOffset = offset; };
float getHumOffset() { return _humidityOffset; };
float getTempOffset() { return _temperatureOffset; };


// INTERRUPT DISABLE
bool getDisableIRQ() { return _disableIRQ; };
void setDisableIRQ(bool b ) { _disableIRQ = b; };

Expand All @@ -106,18 +119,18 @@ class DHTNEW


private:
uint8_t _dataPin = 0;
uint32_t _wakeupDelay = 0;
uint8_t _type = 0;
float _humOffset = 0.0;
float _tempOffset = 0.0;
float _humidity = 0.0;
float _temperature = 0.0;
uint32_t _lastRead = 0;
bool _disableIRQ = true;
bool _waitForRead = false;
bool _suppressError = false;
uint16_t _readDelay = 0;
uint8_t _dataPin = 0;
uint32_t _wakeupDelay = 0;
uint8_t _type = 0;
float _humidityOffset = 0.0;
float _temperatureOffset = 0.0;
float _humidity = 0.0;
float _temperature = 0.0;
uint32_t _lastRead = 0;
bool _disableIRQ = true;
bool _waitForRead = false;
bool _suppressError = false;
uint16_t _readDelay = 0;

uint8_t _bits[5]; // buffer to receive data
int _read();
Expand Down
Loading

0 comments on commit 088b6bf

Please sign in to comment.