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:
parent
6439d7d5de
commit
5055d0993e
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += dht
|
||||
USEMODULE += fmt
|
||||
USEMODULE += xtimer
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user