Fix DHT module (#3334)
* DHT module negative values bug fix * Revamp of the DHT module, DHT12 support * Updated documentation
This commit is contained in:
parent
f4ba635d3c
commit
9c1f4aca5b
195
app/dht/dht.c
195
app/dht/dht.c
|
@ -26,6 +26,7 @@
|
|||
//
|
||||
// Released to the public domain
|
||||
//
|
||||
// #define NODE_DEBUG
|
||||
|
||||
#include "user_interface.h"
|
||||
#include "platform.h"
|
||||
|
@ -40,21 +41,14 @@
|
|||
#define HIGH 1
|
||||
#endif /* ifndef HIGH */
|
||||
|
||||
#define COMBINE_HIGH_AND_LOW_BYTE(byte_high, byte_low) ((uint16_t)((byte_high) << 8) | (byte_low))
|
||||
|
||||
static double dht_humidity;
|
||||
static double dht_temperature;
|
||||
|
||||
static uint8_t dht_bytes[5]; // buffer to receive data
|
||||
|
||||
typedef enum {
|
||||
Humidity = 0,
|
||||
Temperature,
|
||||
Humidity8,
|
||||
Temperature8
|
||||
} dht_Signal;
|
||||
|
||||
static int dht_readSensor(uint8_t pin, uint8_t wakeupDelay);
|
||||
static double getValue(dht_Signal s);
|
||||
static bool verifyChecksum();
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -79,10 +73,15 @@ double dht_getTemperature(void)
|
|||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read_universal(uint8_t pin)
|
||||
int dht_read(uint8_t pin, dht_type type)
|
||||
{
|
||||
// READ VALUES
|
||||
int rv = dht_readSensor(pin, DHTLIB_DHT_UNI_WAKEUP);
|
||||
int rv = dht_readSensor(pin,
|
||||
type == DHT22 ? DHTLIB_DHT_WAKEUP :
|
||||
type == DHT11 ? DHTLIB_DHT11_WAKEUP :
|
||||
DHTLIB_DHT_UNI_WAKEUP
|
||||
);
|
||||
|
||||
if (rv != DHTLIB_OK)
|
||||
{
|
||||
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
||||
|
@ -90,129 +89,73 @@ int dht_read_universal(uint8_t pin)
|
|||
return rv; // propagate error value
|
||||
}
|
||||
|
||||
#if defined(DHT_DEBUG_BYTES)
|
||||
int i;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
DHT_DEBUG("%02X\n", dht_bytes[i]);
|
||||
}
|
||||
#endif // defined(DHT_DEBUG_BYTES)
|
||||
NODE_DBG("DHT registers: %x\t%x\t%x\t%x\t%x == %x\n", dht_bytes[0], dht_bytes[1], dht_bytes[2], dht_bytes[3], dht_bytes[4], (uint8_t)(dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3]));
|
||||
|
||||
// Assume it is DHT11
|
||||
// Assume it is special case of DHT11,
|
||||
// i.e. positive temperature and dht_bytes[3] == 0 ((dht_bytes[3] & 0x0f) * 0.1 to be added to temperature readout)
|
||||
// If it is DHT11, both temp and humidity's decimal
|
||||
dht_humidity = dht_bytes[0];
|
||||
dht_temperature = dht_bytes[2];
|
||||
if ((dht_bytes[1] == 0) && (dht_bytes[3] == 0))
|
||||
{
|
||||
// It may DHT11
|
||||
// CONVERT AND STORE
|
||||
DHT_DEBUG("DHT11 method\n");
|
||||
dht_humidity = getValue(Humidity8);
|
||||
dht_temperature = getValue(Temperature8);
|
||||
NODE_DBG("DHT11 method\n");
|
||||
|
||||
// TEST CHECKSUM
|
||||
if (!verifyChecksum())
|
||||
{
|
||||
// It may not DHT11
|
||||
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
||||
dht_temperature = DHTLIB_INVALID_VALUE; // invalid value
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
uint8_t sum = dht_bytes[0] + dht_bytes[2];
|
||||
if (dht_bytes[4] == sum)
|
||||
{
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Assume it is not DHT11
|
||||
// Assume it is not DHT11 special case
|
||||
// CONVERT AND STORE
|
||||
DHT_DEBUG("DHTxx method\n");
|
||||
dht_humidity = getValue(Humidity);
|
||||
dht_temperature = getValue(Temperature);
|
||||
NODE_DBG("DHTxx method\n");
|
||||
|
||||
switch (type) {
|
||||
case DHT11:
|
||||
case DHT12:
|
||||
dht_humidity += dht_bytes[1] * 0.1;
|
||||
break;
|
||||
default:
|
||||
dht_humidity = COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DHT11:
|
||||
if (dht_bytes[3] & 0x80) {
|
||||
dht_temperature = -1 - dht_temperature;
|
||||
}
|
||||
dht_temperature += (dht_bytes[3] & 0x0f) * 0.1;
|
||||
break;
|
||||
case DHT12:
|
||||
dht_temperature += (dht_bytes[3] & 0x0f) * 0.1;
|
||||
if (dht_bytes[2] & 0x80) // negative dht_temperature
|
||||
{
|
||||
dht_temperature *= -1;
|
||||
}
|
||||
break;
|
||||
default: // DHT22, DHT_NON11
|
||||
dht_temperature = COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
|
||||
if (dht_bytes[2] & 0x80) // negative dht_temperature
|
||||
{
|
||||
dht_temperature *= -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// TEST CHECKSUM
|
||||
if (!verifyChecksum())
|
||||
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
||||
if (dht_bytes[4] != sum)
|
||||
{
|
||||
return DHTLIB_ERROR_CHECKSUM;
|
||||
}
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read11(uint8_t pin)
|
||||
{
|
||||
// READ VALUES
|
||||
int rv = dht_readSensor(pin, DHTLIB_DHT11_WAKEUP);
|
||||
if (rv != DHTLIB_OK)
|
||||
{
|
||||
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
||||
dht_temperature = DHTLIB_INVALID_VALUE; // invalid value
|
||||
return rv;
|
||||
}
|
||||
|
||||
// CONVERT AND STORE
|
||||
dht_humidity = getValue(Humidity8);
|
||||
dht_temperature = getValue(Temperature8);
|
||||
|
||||
// TEST CHECKSUM
|
||||
if (!verifyChecksum()) return DHTLIB_ERROR_CHECKSUM;
|
||||
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read(uint8_t pin)
|
||||
{
|
||||
// READ VALUES
|
||||
int rv = dht_readSensor(pin, DHTLIB_DHT_WAKEUP);
|
||||
if (rv != DHTLIB_OK)
|
||||
{
|
||||
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
|
||||
dht_temperature = DHTLIB_INVALID_VALUE; // invalid value
|
||||
return rv; // propagate error value
|
||||
}
|
||||
|
||||
// CONVERT AND STORE
|
||||
dht_humidity = getValue(Humidity);
|
||||
dht_temperature = getValue(Temperature);
|
||||
|
||||
// TEST CHECKSUM
|
||||
if (!verifyChecksum())
|
||||
{
|
||||
return DHTLIB_ERROR_CHECKSUM;
|
||||
}
|
||||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read21(uint8_t pin) __attribute__((alias("dht_read")));
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read22(uint8_t pin) __attribute__((alias("dht_read")));
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read33(uint8_t pin) __attribute__((alias("dht_read")));
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read44(uint8_t pin) __attribute__((alias("dht_read")));
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
|
@ -236,7 +179,7 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
|
|||
// volatile uint8_t *PIR = portInputRegister(port);
|
||||
|
||||
// EMPTY BUFFER
|
||||
memset(dht_bytes, sizeof(uint8_t)*5, 0);
|
||||
memset(dht_bytes, 0, sizeof(uint8_t)*5);
|
||||
|
||||
// REQUEST SAMPLE
|
||||
// pinMode(pin, OUTPUT);
|
||||
|
@ -309,32 +252,6 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
|
|||
return DHTLIB_OK;
|
||||
}
|
||||
|
||||
// Assembles the high and low byte in a signed 16bit value
|
||||
static double getValue(dht_Signal s)
|
||||
{
|
||||
uint8_t high=0, low=0;
|
||||
|
||||
// the '8' variants leave the low byte set to 0
|
||||
switch(s){
|
||||
case Humidity:
|
||||
low = dht_bytes[1];
|
||||
case Humidity8:
|
||||
high = dht_bytes[0];
|
||||
break;
|
||||
case Temperature:
|
||||
low = dht_bytes[3];
|
||||
case Temperature8:
|
||||
high = dht_bytes[2];
|
||||
break;
|
||||
}
|
||||
return ((high << 8) | low) * 0.1;
|
||||
}
|
||||
|
||||
static bool verifyChecksum(){
|
||||
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
|
||||
return (dht_bytes[4] == sum);
|
||||
}
|
||||
|
||||
//
|
||||
// END OF FILE
|
||||
//
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#define DHTLIB_DHT_WAKEUP 1
|
||||
#define DHTLIB_DHT_UNI_WAKEUP 18
|
||||
|
||||
#define DHT_DEBUG
|
||||
|
||||
// max timeout is 100 usec.
|
||||
// For a 16 Mhz proc 100 usec is 1600 clock cycles
|
||||
// loops using DHTLIB_TIMEOUT use at least 4 clock cycli
|
||||
|
@ -48,19 +46,18 @@
|
|||
#define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
|
||||
#define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))
|
||||
|
||||
typedef enum {
|
||||
DHT11 = 0,
|
||||
DHT12,
|
||||
DHT22,
|
||||
DHT_NON11
|
||||
} dht_type;
|
||||
|
||||
// return values:
|
||||
// DHTLIB_OK
|
||||
// DHTLIB_ERROR_CHECKSUM
|
||||
// DHTLIB_ERROR_TIMEOUT
|
||||
int dht_read_universal(uint8_t pin);
|
||||
int dht_read11(uint8_t pin);
|
||||
int dht_read(uint8_t pin);
|
||||
|
||||
int dht_read21(uint8_t pin);
|
||||
int dht_read22(uint8_t pin);
|
||||
int dht_read33(uint8_t pin);
|
||||
int dht_read44(uint8_t pin);
|
||||
|
||||
int dht_read(uint8_t pin, dht_type type);
|
||||
double dht_getHumidity(void);
|
||||
double dht_getTemperature(void);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ static int dht_lapi_read( lua_State *L )
|
|||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( dht, id );
|
||||
lua_pushinteger( L, dht_read_universal(id) );
|
||||
lua_pushinteger( L, dht_read(id, DHT_NON11) );
|
||||
aux_read( L );
|
||||
return 5;
|
||||
}
|
||||
|
@ -42,7 +42,17 @@ static int dht_lapi_read11( lua_State *L )
|
|||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( dht, id );
|
||||
lua_pushinteger( L, dht_read11(id) );
|
||||
lua_pushinteger( L, dht_read(id, DHT11) );
|
||||
aux_read( L );
|
||||
return 5;
|
||||
}
|
||||
|
||||
// Lua: status, temp, humi, tempdec, humidec = dht.read12( id ))
|
||||
static int dht_lapi_read12( lua_State *L )
|
||||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( dht, id );
|
||||
lua_pushinteger( L, dht_read(id, DHT12) );
|
||||
aux_read( L );
|
||||
return 5;
|
||||
}
|
||||
|
@ -52,48 +62,17 @@ static int dht_lapi_readxx( lua_State *L )
|
|||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
MOD_CHECK_ID( dht, id );
|
||||
lua_pushinteger( L, dht_read(id) );
|
||||
lua_pushinteger( L, dht_read(id, DHT22) );
|
||||
aux_read( L );
|
||||
return 5;
|
||||
}
|
||||
|
||||
// // Lua: result = dht.humidity()
|
||||
// static int dht_lapi_humidity( lua_State *L )
|
||||
// {
|
||||
// lua_pushnumber( L, dht_getHumidity() );
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// // Lua: result = dht.humiditydecimal()
|
||||
// static int dht_lapi_humiditydecimal( lua_State *L )
|
||||
// {
|
||||
// double value = dht_getHumidity();
|
||||
// int result = (int)((value - (int)value) * 1000);
|
||||
// lua_pushnumber( L, result );
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// // Lua: result = dht.temperature()
|
||||
// static int dht_lapi_temperature( lua_State *L )
|
||||
// {
|
||||
// lua_pushnumber( L, dht_getTemperature() );
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// // Lua: result = dht.temperaturedecimal()
|
||||
// static int dht_lapi_temperaturedecimal( lua_State *L )
|
||||
// {
|
||||
// double value = dht_getTemperature();
|
||||
// int result = (int)((value - (int)value) * 1000);
|
||||
// lua_pushnumber( L, result );
|
||||
// return 1;
|
||||
// }
|
||||
|
||||
// Module function map
|
||||
LROT_BEGIN(dht, NULL, 0)
|
||||
LROT_FUNCENTRY( read, dht_lapi_read )
|
||||
LROT_FUNCENTRY( read11, dht_lapi_read11 )
|
||||
LROT_FUNCENTRY( readxx, dht_lapi_readxx )
|
||||
LROT_FUNCENTRY( read12, dht_lapi_read12 )
|
||||
LROT_FUNCENTRY( readxx, dht_lapi_read )
|
||||
LROT_NUMENTRY( OK, DHTLIB_OK )
|
||||
LROT_NUMENTRY( ERROR_CHECKSUM, DHTLIB_ERROR_CHECKSUM )
|
||||
LROT_NUMENTRY( ERROR_TIMEOUT, DHTLIB_ERROR_TIMEOUT )
|
||||
|
|
|
@ -9,7 +9,8 @@ Constants for various functions.
|
|||
`dht.OK`, `dht.ERROR_CHECKSUM`, `dht.ERROR_TIMEOUT` represent the potential values for the DHT read status
|
||||
|
||||
## dht.read()
|
||||
Read all kinds of DHT sensors, including DHT11, 21, 22, 33, 44 humidity temperature combo sensor.
|
||||
Reads all kinds of DHT sensors, including DHT11, 21, 22, 33, 44 humidity temperature combo sensor.
|
||||
Returns correct readout except for DHT12 and negative temperatures by DHT11. Use [`dht.read12()`](#dhtread12) and [`dht.read11()`](#dhtread11) instead. It is to use model specific read function anyway.
|
||||
|
||||
#### Syntax
|
||||
`dht.read(pin)`
|
||||
|
@ -74,8 +75,32 @@ Read DHT11 humidity temperature combo sensor.
|
|||
#### See also
|
||||
[dht.read()](#dhtread)
|
||||
|
||||
## dht.read12()
|
||||
Read DHT12 humidity temperature combo sensor.
|
||||
|
||||
#### Syntax
|
||||
`dht.read12(pin)`
|
||||
|
||||
#### Parameters
|
||||
`pin` pin number of DHT12 sensor (can't be 0), type is number
|
||||
|
||||
#### Returns
|
||||
- `status` as defined in Constants
|
||||
- `temp` temperature (see note below)
|
||||
- `humi` humidity (see note below)
|
||||
- `temp_dec` temperature decimal
|
||||
- `humi_dec` humidity decimal
|
||||
|
||||
!!! note
|
||||
|
||||
If using float firmware then `temp` and `humi` are floating point numbers. On an integer firmware, the final values have to be concatenated from `temp` and `temp_dec` / `humi` and `hum_dec`.
|
||||
|
||||
#### See also
|
||||
[dht.read()](#dhtread)
|
||||
|
||||
|
||||
## dht.readxx()
|
||||
Read all kinds of DHT sensors, except DHT11.
|
||||
Read all kinds of DHT sensors, except DHT11 and DHT12. Differs from `dht.read()` only by waiting only sufficient 1 ms for sensor wake-up while `dht.read()` waits universal 18 ms.
|
||||
|
||||
####Syntax
|
||||
`dht.readxx(pin)`
|
||||
|
|
Loading…
Reference in New Issue