nodemcu-firmware/components/modules/dht.c

104 lines
2.3 KiB
C

#include "module.h"
#include "lauxlib.h"
#include <stdint.h>
#include "platform.h"
typedef enum {
LDHT_OK = 0,
LDHT_ERROR_CHECKSUM = -1,
LDHT_ERROR_TIMEOUT = -2,
LDHT_INVALID_VALUE = -999
} ldht_result_t;
typedef enum {
LDHT11,
LDHT2X
} ldht_type_t;
static int ldht_compute_data11( uint8_t *data, double *temp, double *humi )
{
*humi = data[0];
*temp = data[2];
uint8_t sum = data[0] + data[1] + data[2] + data[3];
return sum == data[4] ? LDHT_OK : LDHT_ERROR_CHECKSUM;
}
static int ldht_compute_data2x( uint8_t *data, double *temp, double *humi )
{
*humi = (data[0] * 256 + data[1]) * 0.1;
*temp = ((data[2] & 0x7f) * 256 + data[3]) * 0.1;
if (data[2] & 0x80)
*temp = - *temp;
uint8_t sum = data[0] + data[1] + data[2] + data[3];
return sum == data[4] ? LDHT_OK : LDHT_ERROR_CHECKSUM;
}
static int ldht_read_generic( lua_State *L, ldht_type_t type )
{
int stack = 0;
int gpio = luaL_checkint( L, ++stack );
luaL_argcheck( L, platform_gpio_output_exists( gpio ), stack, "invalid gpio" );
uint8_t data[5];
if (platform_dht_read( gpio,
type == LDHT11 ? PLATFORM_DHT11_WAKEUP_MS : PLATFORM_DHT2X_WAKEUP_MS,
data ) != PLATFORM_OK) {
lua_pushinteger( L, LDHT_ERROR_TIMEOUT );
return 1;
}
double temp, humi;
int res;
switch (type) {
case LDHT11:
res = ldht_compute_data11( data, &temp, &humi );
break;
case LDHT2X:
res = ldht_compute_data2x( data, &temp, &humi );
break;
default:
res = LDHT_INVALID_VALUE;
temp = humi = 0;
break;
}
lua_pushinteger( L, res );
lua_pushnumber( L, temp );
lua_pushnumber( L, humi );
int tempdec = (int)((temp - (int)temp) * 1000);
int humidec = (int)((humi - (int)humi) * 1000);
lua_pushinteger( L, tempdec );
lua_pushinteger( L, humidec );
return 5;
}
static int ldht_read11( lua_State *L )
{
return ldht_read_generic( L, LDHT11 );
}
static int ldht_read2x( lua_State *L )
{
return ldht_read_generic( L, LDHT2X );
}
static const LUA_REG_TYPE dht_map[] = {
{ LSTRKEY( "read11" ), LFUNCVAL( ldht_read11 ) },
{ LSTRKEY( "read2x" ), LFUNCVAL( ldht_read2x ) },
{ LSTRKEY( "OK" ), LNUMVAL( LDHT_OK ) },
{ LSTRKEY( "ERROR_CHECKSUM" ), LNUMVAL( LDHT_ERROR_CHECKSUM ) },
{ LSTRKEY( "ERROR_TIMEOUT" ), LNUMVAL( LDHT_ERROR_TIMEOUT ) },
{ LNILKEY, LNILVAL }
};
NODEMCU_MODULE(DHT, "dht", dht_map, NULL);