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:
commit
7a2ebfbde6
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user