0.2.2 DHT20

This commit is contained in:
rob tillaart 2023-02-10 16:22:51 +01:00
parent 1316821ef3
commit 30ada60b3a
16 changed files with 436 additions and 57 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:

View File

@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.2] - 2022-12-21
- update keywords.txt
- add defaults to offset functions.
- update readme.md
- update GitHub actions
- update license 2023
## [0.2.1] - 2022-12-21
- first part of the **readStatus()** not part of the protocol
- different interpretation of datasheet page 10 section 7.4
@ -13,7 +21,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- see https://github.com/RobTillaart/DHT20/issues/8 + page 11 datasheet
- add **getAddress()** convenience function.
## [0.2.0] - 2022-10-30
- add changelog.md
- add rp2040 to build-CI

View File

@ -1,7 +1,7 @@
//
// FILE: DHT20.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// VERSION: 0.2.2
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
@ -23,7 +23,7 @@ DHT20::DHT20(TwoWire *wire)
_humidity = 0;
_humOffset = 0;
_tempOffset = 0;
_status = 0;
_status = DHT20_OK;
_lastRequest = 0;
_lastRead = 0;
}
@ -89,7 +89,7 @@ uint8_t DHT20::resetSensor()
//
int DHT20::read()
{
// do not read to fast
// do not read to fast == more than once per second.
if (millis() - _lastRead < 1000)
{
return DHT20_ERROR_LASTREAD;
@ -115,7 +115,7 @@ int DHT20::requestData()
{
// reset sensor if needed.
resetSensor();
// GET CONNECTION
_wire->beginTransmission(DHT20_ADDRESS);
_wire->write(0xAC);
@ -201,7 +201,7 @@ float DHT20::getTemperature()
void DHT20::setHumOffset(float offset)
{
_humOffset = offset;
_humOffset = offset;
};
@ -319,7 +319,7 @@ bool DHT20::_resetRegister(uint8_t reg)
if (_wire->endTransmission() != 0) return false;
delay(5);
int bytes = _wire->requestFrom(DHT20_ADDRESS, (uint8_t)3);
int bytes = _wire->requestFrom(DHT20_ADDRESS, (uint8_t)3);
for (int i = 0; i < bytes; i++)
{
value[i] = _wire->read();

View File

@ -3,8 +3,7 @@
// FILE: DHT20.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for DHT20 I2C temperature and humidity sensor.
// VERSION: 0.2.1
// HISTORY: See DHT20.cpp
// VERSION: 0.2.2
// URL: https://github.com/RobTillaart/DHT20
//
@ -21,7 +20,7 @@
#include "Arduino.h"
#include "Wire.h"
#define DHT20_LIB_VERSION (F("0.2.1"))
#define DHT20_LIB_VERSION (F("0.2.2"))
#define DHT20_OK 0
#define DHT20_ERROR_CHECKSUM -10
@ -53,11 +52,11 @@ public:
int requestData();
// read the raw data.
int readData();
// converts raw databits to temperature and humidity.
// converts raw data bits to temperature and humidity.
int convert();
// SYNCHRONUOUS CALL
// SYNCHRONOUS CALL
// blocking read call to read + convert data
int read();
// access the converted temperature & humidity
@ -66,8 +65,8 @@ public:
// OFFSET 1st order adjustments
void setHumOffset(float offset);
void setTempOffset(float offset);
void setHumOffset(float offset = 0);
void setTempOffset(float offset = 0);
float getHumOffset();
float getTempOffset();
@ -88,13 +87,13 @@ public:
// RESET (new since 0.1.4)
// use with care
// 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
// use with care
uint8_t resetSensor();
@ -118,5 +117,5 @@ private:
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022-2022 Rob Tillaart
Copyright (c) 2022-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -13,7 +13,7 @@ Arduino library for I2C DHT20 temperature and humidity sensor.
## Description
The DHT20 is a humidity an temperature sensor.
The DHT20 is a humidity and temperature sensor.
The sensor has a fixed address of **0x38**.
It is not known if the address can be changed.
@ -53,7 +53,21 @@ This keeps the API simple. The reads are 1-2 ms slower than 0.1.4. (< 50 ms).
Still far below the 80 ms mentioned in the datasheet.
### Connection
#### Tested
Verified to work with Arduino UNO and ESP32 and ESP8266 (see #8)
Please let me know if other platforms work (or not).
## I2C
#### Address
The sensor has a fixed address of **0x38**.
It is not known if the address can be changed.
#### Connection
Always check datasheet!
@ -67,16 +81,63 @@ Front view
+--------------+
```
### Tested
#### Performance
Verified to work with Arduino UNO and ESP32 and ESP8266 (see #8)
Please let me know if other platforms work (or not).
The datasheet states 400 KHz as the maximum speed.
Below the results of a small test that works well up to 800 KHz.
- Arduino UNO + 10 cm wires + no pull up + DHT20_I2C_speed.ino
Speed in KHz, Time in microseconds.
**read()**
| Speed | Time | notes |
|:-------:|:-------:|:--------|
| 100 | 44588 | default I2C speed |
| 200 | 43988 |
| 400 | 44040 | datasheet maximum |
| 600 | 43224 |
| 800 | 43988 |
**ASYNC: requestData()**
| Speed | Time | notes |
|:-------:|:-------:|:--------|
| 100 | 1676 | default I2C speed |
| 200 | 1384 |
| 400 | 1240 | datasheet maximum |
| 600 | 1188 |
| 800 | 1168 |
**ASYNC: readData()**
| Speed | Time | notes |
|:-------:|:-------:|:--------|
| 100 | 832 | default I2C speed |
| 200 | 464 |
| 400 | 284 | datasheet maximum |
| 600 | 212 |
| 800 | 188 |
The numbers indicate that the conversion takes > 40 milliseconds.
Requesting the measurement and fetching the data < 2.5 milliseconds.
Using the asynchronous interface frees up a lot of clock cycles.
Going beyond 400 KHz (datasheet max) does not save much extra time,
and should only be used if you are in a need for speed.
## Interface
```cpp
#include "DHT20.h"
```
### Constructor
#### Constructor
- **DHT20(TwoWire \*wire = &Wire)** constructor, using a specific Wire (I2C bus).
- **bool begin(uint8_t dataPin, uint8_t clockPin)** begin for ESP32 et al, to set I2C bus pins.
@ -84,7 +145,7 @@ Please let me know if other platforms work (or not).
- **bool isConnected()** returns true if the address of the DHT20 can be seen on the I2C bus.
- **uint8_t getAddress()** returns the (fixed) address - convenience.
### Core
#### Core
- **int8_t read()** read the sensor and store the values internally.
Returns the status of the read which should be 0 == **DHT20_OK**.
@ -94,15 +155,17 @@ Multiple calls will return same value until a new **read()** is made.
Multiple calls will return same value until a new **read()** is made.
### Offset
#### Offset
- **void setHumOffset(float offset)** set an offset to calibrate the sensor (1st order).
- **void setHumOffset(float offset = 0)** set an offset to calibrate the sensor (1st order).
Default offset is 0.
- **float getHumOffset()** return current humidity offset, default 0.
- **void setTempOffset(float offset)** set an offset to calibrate the sensor (1st order).
- **void setTempOffset(float offset = 0)** set an offset to calibrate the sensor (1st order).
Default offset is 0.
- **float getTempOffset()** return current temperature offset, default 0.
### Asynchronous interface
#### Asynchronous interface
There are two timings that need to be considered (from datasheet):
- time between requests = 1000 ms.
@ -126,7 +189,7 @@ Note there must be at least 1000 milliseconds between requests!
See the example **DHT20_async.ino**
### Status
#### Status
- **uint8_t readStatus()** forced read of the status only.
This function blocks a few milliseconds to optimize communication.
@ -157,53 +220,52 @@ The call is needed to get the **read()** working well so it has been embedded in
the read calls. (0.2.0)
### Timing
#### Timing
- **uint32_t lastRead()** last time the sensor is read in milliseconds since start.
- **uint32_t lastRequest()** last time a request is made to make a measurement.
### Return codes
#### Return codes
| name | value | notes |
|:----------------------------|:-------:|:--------|
| DHT20_OK | 00 | OK
| DHT20_ERROR_CHECKSUM | -10 | values might be OK if they are like recent previous ones.
| DHT20_ERROR_CONNECT | -11 | check connection
| DHT20_MISSING_BYTES | -12 | check connection
| DHT20_ERROR_BYTES_ALL_ZERO | -13 | check connection
| DHT20_ERROR_READ_TIMEOUT | -14 |
| DHT20_ERROR_LASTREAD | -15 | wait 1 second between reads
## Operation
See examples
| name | value | notes |
|:-----------------------------|:-------:|:--------|
| DHT20_OK | 00 | OK
| DHT20_ERROR_CHECKSUM | -10 | values might be OK if they are like recent previous ones.
| DHT20_ERROR_CONNECT | -11 | check connection
| DHT20_MISSING_BYTES | -12 | check connection
| DHT20_ERROR_BYTES_ALL_ZERO | -13 | check connection
| DHT20_ERROR_READ_TIMEOUT | -14 |
| DHT20_ERROR_LASTREAD | -15 | wait 1 second between reads
## Future
#### must
#### Must
- improve documentation.
- investigate the bug from #8 further
(is done in 0.2.1 see issue #8)
#### should
#### Should
#### could
#### Could
- improve unit tests.
- investigate
- sensor calibration (website aosong?)
- can sensor address be changed?
- investigate optimizing timing in readStatus()
- delay(1) ==> microSeconds(???).
- connected flag?
- keep in sync DHT12 ?
#### won't
#### Wont
- **void setIgnoreChecksum(bool = false)** ignore checksum flag speeds up communication a bit
- **bool getIgnoreChecksum()** get checksum flag. for completeness.
-

View File

@ -19,6 +19,8 @@
DHT20 DHT;
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
@ -46,6 +48,47 @@ void setup()
delay(1000);
}
Serial.println();
for (uint32_t speed = 50000; speed < 850000; speed += 50000)
{
Wire.setClock(speed);
start = micros();
DHT.read();
stop = micros();
Serial.print(speed);
Serial.print("\t");
Serial.print(stop - start); // time
Serial.print("\t");
Serial.print(DHT.getHumidity(), 1);
Serial.print("\t");
Serial.print(DHT.getTemperature(), 1);
Serial.println();
delay(1000);
}
Serial.println();
for (uint32_t speed = 50000; speed < 850000; speed += 50000)
{
DHT.requestData();
while (DHT.isMeasuring());
Wire.setClock(speed);
start = micros();
DHT.readData();
stop = micros();
DHT.convert();
Serial.print(speed);
Serial.print("\t");
Serial.print(stop - start); // time
Serial.print("\t");
Serial.print(DHT.getHumidity(), 1);
Serial.print("\t");
Serial.print(DHT.getTemperature(), 1);
Serial.println();
delay(1000);
}
Serial.println("\ndone...");
}

View File

@ -0,0 +1,61 @@
Board: UNO
IDE: 1.8.19
DHT20_I2C_speed.ino
DHT20 LIBRARY VERSION: 0.2.2
NOTE: datasheet states 400 KHz as maximum.
50000 0 48.7 17.3
100000 0 48.7 17.3
150000 0 48.7 17.3
200000 0 48.6 17.3
250000 0 48.6 17.3
300000 0 48.6 17.3
350000 0 48.6 17.3
400000 0 48.6 17.3
450000 0 48.6 17.3
500000 0 48.6 17.3
550000 0 48.6 17.3
600000 0 48.6 17.3
650000 0 48.6 17.3
700000 0 48.6 17.3
750000 0 48.6 17.3
800000 0 48.6 17.3
50000 46916 48.6 17.4
100000 44600 48.6 17.4
150000 44264 48.6 17.3
200000 43996 48.6 17.3
250000 44308 48.6 17.3
300000 43624 48.6 17.3
350000 44248 48.6 17.3
400000 44040 48.6 17.3
450000 43724 48.5 17.4
500000 43612 48.6 17.3
550000 43388 48.6 17.4
600000 43204 48.6 17.4
650000 44200 48.6 17.3
700000 44108 48.6 17.4
750000 43984 48.6 17.4
800000 43984 48.5 17.4
50000 1576 48.6 17.3
100000 836 48.6 17.4
150000 588 48.5 17.3
200000 472 48.6 17.4
250000 400 48.5 17.3
300000 336 48.6 17.4
350000 296 48.6 17.4
400000 284 48.6 17.3
450000 252 48.6 17.4
500000 244 48.6 17.3
550000 228 48.6 17.4
600000 216 48.6 17.3
650000 204 48.6 17.3
700000 200 48.5 17.4
750000 188 48.6 17.4
800000 188 48.6 17.4
done...

View File

@ -0,0 +1,30 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# - uno
# - due
# - zero
# - leonardo
# - m4
# - esp32
# - esp8266
# - mega2560
# - rpipico
libraries:
# - "LiquidCrystal" does not work

View File

@ -0,0 +1,173 @@
//
// FILE: DHT20_lcd.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;
uint32_t stop, start;
///////////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define BL_OFF 0
#define BL_ON 1
/*
#define BACKLIGHT_PIN 7
#define En_pin 4
#define Rw_pin 5
#define Rs_pin 6
#define D4_pin 0
#define D5_pin 1
#define D6_pin 2
#define D7_pin 3
#define LED_OFF 0
#define LED_ON 1
*/
int displayAddress = 0x27;
// lcd object is created as a placeholder as the actual address is determined in setupDisplay()
// constructor needs an I2C address. Better solution would be a function to set the address
// runtime in the class.
LiquidCrystal_I2C lcd(displayAddress);
void setupDisplay()
{
lcd = LiquidCrystal_I2C(displayAddress, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
lcd.begin(20, 4);
// lcd.setBacklightPin(BACKLIGHT_PIN, NEGATIVE);
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(BL_ON);
}
void display()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TEMP:");
lcd.setCursor(6, 0);
lcd.print(DHT.getTemperature());
lcd.setCursor(0, 1);
lcd.print("HUM:");
lcd.setCursor(6, 1);
lcd.print(DHT.getHumidity());
lcd.setCursor(0, 3);
lcd.print("TIME:");
lcd.setCursor(6, 3);
lcd.print(stop - start);
}
void setup()
{
DHT.begin(); // ESP32 default pins 21 22
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DHT20 LIBRARY VERSION: ");
Serial.println(DHT20_LIB_VERSION);
Serial.println();
setupDisplay();
delay(1000);
}
void loop()
{
if (millis() - DHT.lastRead() >= 1000)
{
// READ DATA
start = micros();
int status = DHT.read();
stop = micros();
display();
if ((count % 10) == 0)
{
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(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("\n");
}
}
// -- END OF FILE --

View File

@ -6,6 +6,7 @@ DHT20 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
getAddress KEYWORD2
requestData KEYWORD2
readData KEYWORD2

View File

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

View File

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

View File

@ -34,6 +34,7 @@ unittest_setup()
fprintf(stderr, "DHT20_LIB_VERSION: %s \n", (char *) DHT20_LIB_VERSION);
}
unittest_teardown()
{
}
@ -94,4 +95,6 @@ unittest(test_offset)
unittest_main()
// --------
// -- END OF FILE --