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

drivers/dht: correct interpreting raw values

This commit is contained in:
Wouter Symons 2021-11-20 14:48:07 +01:00
parent 6439d7d5de
commit 5055d0993e
6 changed files with 38 additions and 68 deletions

View File

@ -13,7 +13,7 @@
* @{
*
* @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
*
* @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;
}
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;
for (int i = 0; i < bits; i++) {
for (int i = 0; i < 8; i++) {
uint32_t start, end;
res <<= 1;
/* 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)
{
DEBUG("dht_init\n");
DEBUG("[dht] dht_init\n");
/* check parameters and configuration */
assert(dev && params);
assert((params->type == DHT11) || (params->type == DHT22) || (params->type == DHT21));
memset(dev, 0, sizeof(dht_t));
dev->params = *params;
@ -120,14 +119,14 @@ int dht_init(dht_t *dev, const dht_params_t *params)
xtimer_msleep(2000);
DEBUG("dht_init: success\n");
DEBUG("[dht] dht_init: success\n");
return DHT_OK;
}
int dht_read(dht_t *dev, int16_t *temp, int16_t *hum)
{
uint16_t csum;
uint16_t raw_hum, raw_temp;
uint8_t csum;
uint8_t raw_temp_i, raw_temp_d, raw_hum_i, raw_hum_d;
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 */
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);
return DHT_TIMEOUT;
}
if (_read(&raw_temp, dev->params.pin, 16)) {
_reset(dev);
return DHT_TIMEOUT;
}
if (_read(&csum, dev->params.pin, 8)) {
if (_read(&csum, dev->params.pin)) {
_reset(dev);
return DHT_TIMEOUT;
}
@ -178,33 +184,23 @@ int dht_read(dht_t *dev, int16_t *temp, int16_t *hum)
_reset(dev);
/* validate the checksum */
uint8_t sum = (raw_temp >> 8) + (raw_temp & 0xff) + (raw_hum >> 8)
+ (raw_hum & 0xff);
uint8_t sum = (raw_temp_i) + (raw_temp_d) + (raw_hum_i) + (raw_hum_d);
if (sum != csum) {
DEBUG("error: checksum doesn't match\n");
DEBUG("[dht] error: checksum doesn't match\n");
return DHT_NOCSUM;
}
/* parse the RAW values */
DEBUG("RAW values: temp: %7i hum: %7i\n", (int)raw_temp, (int)raw_hum);
switch (dev->params.type) {
case DHT11:
dev->last_val.temperature = (int16_t)((raw_temp >> 8) * 10);
dev->last_val.humidity = (int16_t)((raw_hum >> 8) * 10);
break;
/* DHT21 == DHT22 (same value in enum), so both are handled here */
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 {
dev->last_val.temperature = (int16_t)raw_temp;
}
break;
default:
return DHT_NODEV; /* this should never be reached */
DEBUG("[dht] RAW values: temp: %2i.%i hum: %2i.%i\n", (int)raw_temp_i,
(int)raw_temp_d, (int)raw_hum_i, (int)raw_hum_d);
dev->last_val.humidity = raw_hum_i * 10 + raw_hum_d;
/* MSB set means negative temperature on DHT22. Will always be 0 on DHT11 */
if (raw_temp_i & 0x80) {
dev->last_val.temperature = -((raw_temp_i & ~0x80) * 10 + raw_temp_d);
}
else {
dev->last_val.temperature = raw_temp_i * 10 + raw_temp_d;
}
/* update time of last measurement */

View File

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

View File

@ -46,35 +46,23 @@ enum {
DHT_OK = 0, /**< all good */
DHT_NOCSUM = -1, /**< checksum error */
DHT_TIMEOUT = -2, /**< communication timed out */
DHT_NODEV = -3 /**< device type not defined */
};
/**
* @brief Data type for storing DHT sensor readings
*/
typedef struct {
uint16_t humidity; /**< relative deca-humidity */
uint16_t temperature; /**< temperature in deca-Celsius */
uint16_t humidity; /**< relative percent */
uint16_t temperature; /**< temperature in deci-Celsius */
} 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
*/
typedef struct {
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
* resistor */
} dht_params_t;
/**
@ -110,7 +98,6 @@ int dht_init(dht_t *dev, const dht_params_t *params);
* @retval DHT_OK Success
* @retval DHT_NOCSUM Checksum error
* @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);

View File

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

View File

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

View File

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