1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #16934 from wosym/dht11fix

drivers/dht: correct interpreting raw values
This commit is contained in:
Marian Buschsieweke 2021-11-20 16:33:58 +01:00 committed by GitHub
commit 7a2ebfbde6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 68 deletions

View File

@ -82,6 +82,7 @@
/drivers/ccs811/ @gschorcht /drivers/ccs811/ @gschorcht
/drivers/enc28j60/ @haukepetersen /drivers/enc28j60/ @haukepetersen
/drivers/dcf77/ @daexel /drivers/dcf77/ @daexel
/drivers/dht/ @wosym
/drivers/dose/ @jue89 /drivers/dose/ @jue89
/drivers/ds18/ @leandrolanzieri /drivers/ds18/ @leandrolanzieri
/drivers/itg320x/ @gschorcht /drivers/itg320x/ @gschorcht
@ -141,6 +142,7 @@
/tests/ @smlng @leandrolanzieri @aabadie @MichelRottleuthner @fjmolinas /tests/ @smlng @leandrolanzieri @aabadie @MichelRottleuthner @fjmolinas
/tests/candev/ @wosym /tests/candev/ @wosym
/tests/driver_bq2429x/ @jeandudey /tests/driver_bq2429x/ @jeandudey
/tests/driver_dht/ @wosym
/tests/gnrc* @miri64 /tests/gnrc* @miri64
/tests/lwip* @miri64 /tests/lwip* @miri64
/tests/slip/ @miri64 /tests/slip/ @miri64

View File

@ -13,7 +13,7 @@
* @{ * @{
* *
* @file * @file
* @brief Device driver implementation for the DHT 11 and 22 * @brief Device driver implementation for the DHT11, 21 and 22
* temperature and humidity sensor * temperature and humidity sensor
* *
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de> * @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
@ -75,12 +75,12 @@ static inline int _wait_for_level(gpio_t pin, bool expect, unsigned timeout)
return (timeout > 0) ? 0 : -1; return (timeout > 0) ? 0 : -1;
} }
static int _read(uint16_t *dest, gpio_t pin, int bits) static int _read(uint8_t *dest, gpio_t pin)
{ {
DEBUG("read\n"); DEBUG("[dht] read\n");
uint16_t res = 0; uint16_t res = 0;
for (int i = 0; i < bits; i++) { for (int i = 0; i < 8; i++) {
uint32_t start, end; uint32_t start, end;
res <<= 1; res <<= 1;
/* measure the length between the next rising and falling flanks (the /* measure the length between the next rising and falling flanks (the
@ -107,11 +107,10 @@ static int _read(uint16_t *dest, gpio_t pin, int bits)
int dht_init(dht_t *dev, const dht_params_t *params) int dht_init(dht_t *dev, const dht_params_t *params)
{ {
DEBUG("dht_init\n"); DEBUG("[dht] dht_init\n");
/* check parameters and configuration */ /* check parameters and configuration */
assert(dev && params); assert(dev && params);
assert((params->type == DHT11) || (params->type == DHT22) || (params->type == DHT21));
memset(dev, 0, sizeof(dht_t)); memset(dev, 0, sizeof(dht_t));
dev->params = *params; dev->params = *params;
@ -120,14 +119,14 @@ int dht_init(dht_t *dev, const dht_params_t *params)
xtimer_msleep(2000); xtimer_msleep(2000);
DEBUG("dht_init: success\n"); DEBUG("[dht] dht_init: success\n");
return DHT_OK; return DHT_OK;
} }
int dht_read(dht_t *dev, int16_t *temp, int16_t *hum) int dht_read(dht_t *dev, int16_t *temp, int16_t *hum)
{ {
uint16_t csum; uint8_t csum;
uint16_t raw_hum, raw_temp; uint8_t raw_temp_i, raw_temp_d, raw_hum_i, raw_hum_d;
assert(dev); assert(dev);
@ -158,17 +157,24 @@ int dht_read(dht_t *dev, int16_t *temp, int16_t *hum)
*/ */
/* read the humidity, temperature, and checksum bits */ /* read the humidity, temperature, and checksum bits */
if (_read(&raw_hum, dev->params.pin, 16)) { if (_read(&raw_hum_i, dev->params.pin)) {
_reset(dev);
return DHT_TIMEOUT;
}
if (_read(&raw_hum_d, dev->params.pin)) {
_reset(dev);
return DHT_TIMEOUT;
}
if (_read(&raw_temp_i, dev->params.pin)) {
_reset(dev);
return DHT_TIMEOUT;
}
if (_read(&raw_temp_d, dev->params.pin)) {
_reset(dev); _reset(dev);
return DHT_TIMEOUT; return DHT_TIMEOUT;
} }
if (_read(&raw_temp, dev->params.pin, 16)) { if (_read(&csum, dev->params.pin)) {
_reset(dev);
return DHT_TIMEOUT;
}
if (_read(&csum, dev->params.pin, 8)) {
_reset(dev); _reset(dev);
return DHT_TIMEOUT; return DHT_TIMEOUT;
} }
@ -178,33 +184,23 @@ int dht_read(dht_t *dev, int16_t *temp, int16_t *hum)
_reset(dev); _reset(dev);
/* validate the checksum */ /* validate the checksum */
uint8_t sum = (raw_temp >> 8) + (raw_temp & 0xff) + (raw_hum >> 8) uint8_t sum = (raw_temp_i) + (raw_temp_d) + (raw_hum_i) + (raw_hum_d);
+ (raw_hum & 0xff);
if (sum != csum) { if (sum != csum) {
DEBUG("error: checksum doesn't match\n"); DEBUG("[dht] error: checksum doesn't match\n");
return DHT_NOCSUM; return DHT_NOCSUM;
} }
/* parse the RAW values */ /* parse the RAW values */
DEBUG("RAW values: temp: %7i hum: %7i\n", (int)raw_temp, (int)raw_hum); DEBUG("[dht] RAW values: temp: %2i.%i hum: %2i.%i\n", (int)raw_temp_i,
switch (dev->params.type) { (int)raw_temp_d, (int)raw_hum_i, (int)raw_hum_d);
case DHT11:
dev->last_val.temperature = (int16_t)((raw_temp >> 8) * 10); dev->last_val.humidity = raw_hum_i * 10 + raw_hum_d;
dev->last_val.humidity = (int16_t)((raw_hum >> 8) * 10); /* MSB set means negative temperature on DHT22. Will always be 0 on DHT11 */
break; if (raw_temp_i & 0x80) {
/* DHT21 == DHT22 (same value in enum), so both are handled here */ dev->last_val.temperature = -((raw_temp_i & ~0x80) * 10 + raw_temp_d);
case DHT22:
dev->last_val.humidity = (int16_t)raw_hum;
/* if the high-bit is set, the value is negative */
if (raw_temp & 0x8000) {
dev->last_val.temperature = (int16_t)((raw_temp & ~0x8000) * -1);
} }
else { else {
dev->last_val.temperature = (int16_t)raw_temp; dev->last_val.temperature = raw_temp_i * 10 + raw_temp_d;
}
break;
default:
return DHT_NODEV; /* this should never be reached */
} }
/* update time of last measurement */ /* update time of last measurement */

View File

@ -34,15 +34,11 @@ extern "C" {
#ifndef DHT_PARAM_PIN #ifndef DHT_PARAM_PIN
#define DHT_PARAM_PIN (GPIO_PIN(0, 0)) #define DHT_PARAM_PIN (GPIO_PIN(0, 0))
#endif #endif
#ifndef DHT_PARAM_TYPE
#define DHT_PARAM_TYPE (DHT11)
#endif
#ifndef DHT_PARAM_PULL #ifndef DHT_PARAM_PULL
#define DHT_PARAM_PULL (GPIO_IN_PU) #define DHT_PARAM_PULL (GPIO_IN_PU)
#endif #endif
#ifndef DHT_PARAMS #ifndef DHT_PARAMS
#define DHT_PARAMS { .pin = DHT_PARAM_PIN, \ #define DHT_PARAMS { .pin = DHT_PARAM_PIN, \
.type = DHT_PARAM_TYPE, \
.in_mode = DHT_PARAM_PULL } .in_mode = DHT_PARAM_PULL }
#endif #endif
#ifndef DHT_SAULINFO #ifndef DHT_SAULINFO

View File

@ -46,35 +46,23 @@ enum {
DHT_OK = 0, /**< all good */ DHT_OK = 0, /**< all good */
DHT_NOCSUM = -1, /**< checksum error */ DHT_NOCSUM = -1, /**< checksum error */
DHT_TIMEOUT = -2, /**< communication timed out */ DHT_TIMEOUT = -2, /**< communication timed out */
DHT_NODEV = -3 /**< device type not defined */
}; };
/** /**
* @brief Data type for storing DHT sensor readings * @brief Data type for storing DHT sensor readings
*/ */
typedef struct { typedef struct {
uint16_t humidity; /**< relative deca-humidity */ uint16_t humidity; /**< relative percent */
uint16_t temperature; /**< temperature in deca-Celsius */ uint16_t temperature; /**< temperature in deci-Celsius */
} dht_data_t; } dht_data_t;
/**
* @brief Device type of the DHT device
*/
typedef enum {
DHT11, /**< DHT11 device identifier */
DHT22, /**< DHT22 device identifier */
DHT21 = DHT22 /**< DHT21 device identifier */
} dht_type_t;
/** /**
* @brief Configuration parameters for DHT devices * @brief Configuration parameters for DHT devices
*/ */
typedef struct { typedef struct {
gpio_t pin; /**< GPIO pin of the device's data pin */ gpio_t pin; /**< GPIO pin of the device's data pin */
dht_type_t type; /**< type of the DHT device */
gpio_mode_t in_mode; /**< input pin configuration, with or without pull gpio_mode_t in_mode; /**< input pin configuration, with or without pull
* resistor */ * resistor */
} dht_params_t; } dht_params_t;
/** /**
@ -110,7 +98,6 @@ int dht_init(dht_t *dev, const dht_params_t *params);
* @retval DHT_OK Success * @retval DHT_OK Success
* @retval DHT_NOCSUM Checksum error * @retval DHT_NOCSUM Checksum error
* @retval DHT_TIMEOUT Reading data timed out (check wires!) * @retval DHT_TIMEOUT Reading data timed out (check wires!)
* @retval DHT_NODEV Unsupported device type specified
*/ */
int dht_read(dht_t *dev, int16_t *temp, int16_t *hum); int dht_read(dht_t *dev, int16_t *temp, int16_t *hum);

View File

@ -1,7 +1,6 @@
include ../Makefile.tests_common include ../Makefile.tests_common
USEMODULE += dht USEMODULE += dht
USEMODULE += fmt
USEMODULE += xtimer USEMODULE += xtimer
include $(RIOTBASE)/Makefile.include include $(RIOTBASE)/Makefile.include

View File

@ -1,5 +1,4 @@
# this file enables modules defined in Kconfig. Do not use this file for # this file enables modules defined in Kconfig. Do not use this file for
# application configuration. This is only needed during migration. # application configuration. This is only needed during migration.
CONFIG_MODULE_DHT=y CONFIG_MODULE_DHT=y
CONFIG_MODULE_FMT=y
CONFIG_MODULE_XTIMER=y CONFIG_MODULE_XTIMER=y

View File

@ -35,8 +35,6 @@ int main(void)
{ {
dht_t dev; dht_t dev;
int16_t temp, hum; int16_t temp, hum;
char temp_s[10];
char hum_s[10];
puts("DHT temperature and humidity sensor test application\n"); puts("DHT temperature and humidity sensor test application\n");
@ -57,13 +55,8 @@ int main(void)
continue; continue;
} }
size_t n = fmt_s16_dfp(temp_s, temp, -1); printf("DHT values - temp: %d.%d°C - relative humidity: %d.%d%%\n",
temp_s[n] = '\0'; temp/10, temp%10, hum/10, hum%10);
n = fmt_s16_dfp(hum_s, hum, -1);
hum_s[n] = '\0';
printf("DHT values - temp: %s°C - relative humidity: %s%%\n",
temp_s, hum_s);
xtimer_usleep(DELAY); xtimer_usleep(DELAY);
} }