Merge pull request #1606 from OpenMote/master

Adapted OpenMote-CC2538 sensor drivers to Contiki sensor API.
This commit is contained in:
Antonio Lignan 2016-06-01 23:15:27 +02:00
commit acf13a4e0d
7 changed files with 387 additions and 182 deletions

View file

@ -83,31 +83,33 @@ static struct broadcast_conn bc;
PROCESS_THREAD(openmote_demo_process, ev, data) PROCESS_THREAD(openmote_demo_process, ev, data)
{ {
static struct etimer et; static struct etimer et;
static unsigned int raw, counter; static int16_t counter;
static uint8_t adxl346_present, max44009_present, sht21_present; static uint16_t adxl346_present, sht21_present, max44009_present;
static float light, temperature, humidity; static int16_t accel, light, temperature, humidity;
PROCESS_EXITHANDLER(broadcast_close(&bc)) PROCESS_EXITHANDLER(broadcast_close(&bc))
PROCESS_BEGIN(); PROCESS_BEGIN();
adxl346_init(); /* Initialize and calibrate the ADXL346 sensor */
adxl346_present = adxl346_is_present(); adxl346_present = SENSORS_ACTIVATE(adxl346);
if(!adxl346_present) { if(adxl346_present == ADXL346_ERROR) {
printf("ADXL346 sensor is NOT present!\n"); printf("ADXL346 sensor is NOT present!\n");
leds_on(LEDS_YELLOW); leds_on(LEDS_YELLOW);
} else {
adxl346.configure(ADXL346_CALIB_OFFSET, 0);
} }
max44009_init(); /* Initialize the MAX44009 sensor */
max44009_present = max44009_is_present(); max44009_present = SENSORS_ACTIVATE(max44009);
if(!max44009_present) { if(max44009_present == MAX44009_ERROR) {
printf("MAX44009 sensor is NOT present!\n"); printf("MAX44009 sensor is NOT present!\n");
leds_on(LEDS_ORANGE); leds_on(LEDS_ORANGE);
} }
sht21_init(); /* Initialize the SHT21 sensor */
sht21_present = sht21_is_present(); sht21_present = SENSORS_ACTIVATE(sht21);
if(!sht21_present) { if(sht21_present == SHT21_ERROR) {
printf("SHT21 sensor is NOT present!\n"); printf("SHT21 sensor is NOT present!\n");
leds_on(LEDS_RED); leds_on(LEDS_RED);
} }
@ -123,33 +125,30 @@ PROCESS_THREAD(openmote_demo_process, ev, data)
PROCESS_YIELD(); PROCESS_YIELD();
if(ev == PROCESS_EVENT_TIMER) { if(ev == PROCESS_EVENT_TIMER) {
if(adxl346_present) { if(adxl346_present != ADXL346_ERROR) {
leds_on(LEDS_YELLOW); leds_on(LEDS_YELLOW);
raw = adxl346_read_x(); accel = adxl346.value(ADXL346_READ_X_mG);
printf("X Acceleration: %u\n", raw); printf("X Acceleration: %d.%u G\n", accel / 1000, accel % 1000);
raw = adxl346_read_y(); accel = adxl346.value(ADXL346_READ_Y_mG);
printf("Y Acceleration: %u\n", raw); printf("Y Acceleration: %d.%u G\n", accel / 1000, accel % 1000);
raw = adxl346_read_z(); accel = adxl346.value(ADXL346_READ_Z_mG);
printf("Z Acceleration: %u\n", raw); printf("Z Acceleration: %d.%u G\n", accel / 1000, accel % 1000);
leds_off(LEDS_YELLOW); leds_off(LEDS_YELLOW);
} }
if(max44009_present) { if(max44009_present != MAX44009_ERROR) {
leds_on(LEDS_ORANGE); leds_on(LEDS_ORANGE);
raw = max44009_read_light(); light = max44009.value(MAX44009_READ_LIGHT);
light = max44009_convert_light(raw); printf("Light: %u.%ulux\n", light / 100, light % 100);
printf("Light: %u.%ulux\n", (unsigned int)light, (unsigned int)(light * 100) % 100);
leds_off(LEDS_ORANGE); leds_off(LEDS_ORANGE);
} }
if(sht21_present) { if(sht21_present != SHT21_ERROR) {
leds_on(LEDS_RED); leds_on(LEDS_RED);
raw = sht21_read_temperature(); temperature = sht21.value(SHT21_READ_TEMP);
temperature = sht21_convert_temperature(raw); printf("Temperature: %u.%uC\n", temperature / 100, temperature % 100);
printf("Temperature: %u.%uC\n", (unsigned int)temperature, (unsigned int)(temperature * 100) % 100); humidity = sht21.value(SHT21_READ_RHUM);
raw = sht21_read_humidity(); printf("Rel. humidity: %u.%u%%\n", humidity / 100, humidity % 100);
humidity = sht21_convert_humidity(raw);
printf("Rel. humidity: %u.%u%%\n", (unsigned int)humidity, (unsigned int)(humidity * 100) % 100);
leds_off(LEDS_RED); leds_off(LEDS_RED);
} }

View file

@ -43,6 +43,14 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#include "dev/i2c.h" #include "dev/i2c.h"
#include "dev/adxl346.h" #include "dev/adxl346.h"
#include "lib/sensors.h"
/*---------------------------------------------------------------------------*/
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* \name ADXL346 address and device identifier * \name ADXL346 address and device identifier
@ -145,21 +153,24 @@
#define ADXL346_DATA_FORMAT_RANGE_PM_4g (1) #define ADXL346_DATA_FORMAT_RANGE_PM_4g (1)
#define ADXL346_DATA_FORMAT_RANGE_PM_8g (2) #define ADXL346_DATA_FORMAT_RANGE_PM_8g (2)
#define ADXL346_DATA_FORMAT_RANGE_PM_16g (3) #define ADXL346_DATA_FORMAT_RANGE_PM_16g (3)
#define ADXL346_USER_CONFIGURATION (ADXL346_DATA_FORMAT_RANGE_PM_2g)
/** @} */ /** @} */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static uint8_t enabled;
/*---------------------------------------------------------------------------*/
static void
adxl346_init(void) adxl346_init(void)
{ {
uint8_t config[2]; uint8_t config[2];
config[0] = ADXL346_BW_RATE_ADDR; config[0] = ADXL346_BW_RATE_ADDR;
config[1] = (ADXL346_BW_RATE_RATE(11)); config[1] = (ADXL346_BW_RATE_RATE(6));
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
config[0] = ADXL346_DATA_FORMAT_ADDR; config[0] = ADXL346_DATA_FORMAT_ADDR;
config[1] = (ADXL346_DATA_FORMAT_SELF_TEST | config[1] = (ADXL346_USER_CONFIGURATION);
ADXL346_DATA_FORMAT_FULL_RES |
ADXL346_DATA_FORMAT_RANGE_PM_16g);
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
config[0] = ADXL346_POWER_CTL_ADDR; config[0] = ADXL346_POWER_CTL_ADDR;
@ -167,12 +178,7 @@ adxl346_init(void)
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config)); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static uint8_t
adxl346_reset(void)
{
}
/*---------------------------------------------------------------------------*/
uint8_t
adxl346_is_present(void) adxl346_is_present(void)
{ {
uint8_t is_present; uint8_t is_present;
@ -183,52 +189,150 @@ adxl346_is_present(void)
return is_present == ADXL346_DEVID_VALUE; return is_present == ADXL346_DEVID_VALUE;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static int16_t
adxl346_read_x(void) adxl346_read_accel(uint8_t addr1, uint8_t addr2)
{ {
uint8_t acceleration[2]; uint8_t acceleration[2];
uint16_t x; int16_t result;
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX0_ADDR); i2c_single_send(ADXL346_ADDRESS, addr1);
i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]);
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAX1_ADDR); i2c_single_send(ADXL346_ADDRESS, addr2);
i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]);
x = (acceleration[0] << 8) | acceleration[1]; result = (acceleration[1] << 8) | acceleration[0];
return x; return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static int16_t
adxl346_read_y(void) adxl346_convert_accel(int16_t accel)
{ {
uint8_t acceleration[2]; int32_t result;
uint16_t y;
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY0_ADDR); result = (1000 * accel) / 256;
i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]);
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAY1_ADDR);
i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]);
y = (acceleration[0] << 8) | acceleration[1]; return (int16_t)result;
return y;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static void
adxl346_read_z(void) adxl346_calibrate_offset(void)
{ {
uint8_t acceleration[2]; int32_t accum_x = 0;
uint16_t z; int32_t accum_y = 0;
int32_t accum_z = 0;
uint8_t config[2];
int8_t offset;
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ0_ADDR); config[0] = ADXL346_OFSX_ADDR;
i2c_single_receive(ADXL346_ADDRESS, &acceleration[0]); config[1] = 0;
i2c_single_send(ADXL346_ADDRESS, ADXL346_DATAZ1_ADDR); i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
i2c_single_receive(ADXL346_ADDRESS, &acceleration[1]); config[0] = ADXL346_OFSY_ADDR;
config[1] = 0;
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
config[0] = ADXL346_OFSZ_ADDR;
config[1] = 0;
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
z = (acceleration[0] << 8) | acceleration[1]; uint16_t i;
for(i = 0; i < 100; i++) {
uint16_t x, y, z;
return z; x = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR);
accum_x += x;
y = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR);
accum_y += y;
z = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR);
accum_z += z;
}
offset = (64 * accum_x) / 25600;
config[0] = ADXL346_OFSX_ADDR;
config[1] = -offset;
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
PRINTF("ADXL346: X calibration offset is %d\n", offset);
offset = (64 * accum_y) / 25600;
config[0] = ADXL346_OFSY_ADDR;
config[1] = -offset;
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
PRINTF("ADXL346: Y calibration offset is %d\n", offset);
offset = (64 * accum_z) / 25600;
config[0] = ADXL346_OFSZ_ADDR;
config[1] = -offset;
i2c_burst_send(ADXL346_ADDRESS, config, sizeof(config));
PRINTF("ADXL346: Z calibration offset is %d\n", offset);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int
status(int type)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
int16_t accel;
if(!enabled) {
PRINTF("ADXL346: sensor not started\n");
return ADXL346_ERROR;
}
if(type == ADXL346_READ_X) {
return adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR);
} else if(type == ADXL346_READ_Y) {
return adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR);
} else if(type == ADXL346_READ_Z) {
return adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR);
} else if(type == ADXL346_READ_X_mG) {
accel = adxl346_read_accel(ADXL346_DATAX0_ADDR, ADXL346_DATAX1_ADDR);
return adxl346_convert_accel(accel);
} else if(type == ADXL346_READ_Y_mG) {
accel = adxl346_read_accel(ADXL346_DATAY0_ADDR, ADXL346_DATAY1_ADDR);
return adxl346_convert_accel(accel);
} else if(type == ADXL346_READ_Z_mG) {
accel = adxl346_read_accel(ADXL346_DATAZ0_ADDR, ADXL346_DATAZ1_ADDR);
return adxl346_convert_accel(accel);
} else {
PRINTF("ADXL346: invalid value requested\n");
return ADXL346_ERROR;
}
return ADXL346_ERROR;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
if(type == ADXL346_ACTIVATE) {
if(!adxl346_is_present()) {
PRINTF("ADXL346: is not present\n");
enabled = 0;
return ADXL346_ERROR;
} else {
adxl346_init();
enabled = 1;
return ADXL346_SUCCESS;
}
}
if(type == ADXL346_CALIB_OFFSET && enabled) {
adxl346_calibrate_offset();
return ADXL346_SUCCESS;
}
return ADXL346_ERROR;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(adxl346, ADXL346_SENSOR, value, configure, status);
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View file

@ -47,35 +47,21 @@
#ifndef ADXL346_H_ #ifndef ADXL346_H_
#define ADXL346_H_ #define ADXL346_H_
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define ADXL346_ERROR (-1)
* \brief Initialize the ADXL346 sensor #define ADXL346_SUCCESS (0)
*/ #define ADXL346_ACTIVATE (SENSORS_ACTIVE)
void adxl346_init(void); #define ADXL346_READ_X (2)
#define ADXL346_READ_X_mG (3)
#define ADXL346_READ_Y (4)
#define ADXL346_READ_Y_mG (5)
#define ADXL346_READ_Z (6)
#define ADXL346_READ_Z_mG (7)
#define ADXL346_CALIB_OFFSET (8)
#define ADXL346_NONE (9)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define ADXL346_SENSOR "ADXL346 Sensor"
* \brief Reset the ADXL346 sensor
*/
void adxl346_reset(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** extern const struct sensors_sensor adxl346;
* \brief Check if the ADXL346 sensor is present
*/
uint8_t adxl346_is_present(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the x-axis from the ADXL346 sensor
*/
uint16_t adxl346_read_x(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the y-axis from the ADXL346 sensor
*/
uint16_t adxl346_read_y(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the z-axis from the ADXL346 sensor
*/
uint16_t adxl346_read_z(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* ADXL346_H_ */ #endif /* ADXL346_H_ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -43,6 +43,14 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#include "dev/i2c.h" #include "dev/i2c.h"
#include "dev/max44009.h" #include "dev/max44009.h"
#include "lib/sensors.h"
/*---------------------------------------------------------------------------*/
#define DEBUG 1
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* \name MAX44009 address and device identifier * \name MAX44009 address and device identifier
@ -94,9 +102,17 @@
MAX44009_CONFIG_AUTO | \ MAX44009_CONFIG_AUTO | \
MAX44009_CONFIG_CDR_NORMAL | \ MAX44009_CONFIG_CDR_NORMAL | \
MAX44009_CONFIG_INTEGRATION_100ms) MAX44009_CONFIG_INTEGRATION_100ms)
#define MAX44009_USER_CONFIGURATION (MAX44009_CONFIG_DEFAULT | \
MAX44009_CONFIG_AUTO | \
MAX44009_CONFIG_CDR_NORMAL | \
MAX44009_CONFIG_INTEGRATION_800ms)
/** @} */ /** @} */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static uint8_t enabled;
/*---------------------------------------------------------------------------*/
static void
max44009_init(void) max44009_init(void)
{ {
uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \
@ -106,8 +122,8 @@ max44009_init(void)
uint8_t max44009_data[2]; uint8_t max44009_data[2];
uint8_t i; uint8_t i;
max44009_value[0] = (MAX44009_INT_STATUS_ON); max44009_value[0] = (MAX44009_INT_STATUS_OFF);
max44009_value[1] = (MAX44009_DEFAULT_CONFIGURATION); max44009_value[1] = (MAX44009_USER_CONFIGURATION);
max44009_value[2] = (0xFF); max44009_value[2] = (0xFF);
max44009_value[3] = (0x00); max44009_value[3] = (0x00);
max44009_value[4] = (0xFF); max44009_value[4] = (0xFF);
@ -119,7 +135,7 @@ max44009_init(void)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static void
max44009_reset(void) max44009_reset(void)
{ {
uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \ uint8_t max44009_address[5] = { MAX44009_INT_ENABLE_ADDR, MAX44009_CONFIG_ADDR, \
@ -136,7 +152,7 @@ max44009_reset(void)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t static uint8_t
max44009_is_present(void) max44009_is_present(void)
{ {
uint8_t status; uint8_t status;
@ -151,12 +167,12 @@ max44009_is_present(void)
return is_present != MAX44009_NOT_FOUND; return is_present != MAX44009_NOT_FOUND;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static uint16_t
max44009_read_light(void) max44009_read_light(void)
{ {
uint8_t exponent, mantissa; uint8_t exponent, mantissa;
uint8_t max44009_data[2]; uint8_t max44009_data[2];
uint16_t result; uint32_t result;
i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_HIGH_ADDR); i2c_single_send(MAX44009_ADDRESS, MAX44009_LUX_HIGH_ADDR);
i2c_single_receive(MAX44009_ADDRESS, &max44009_data[0]); i2c_single_receive(MAX44009_ADDRESS, &max44009_data[0]);
@ -171,20 +187,77 @@ max44009_read_light(void)
return result; return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
float static uint16_t
max44009_convert_light(uint16_t lux) max44009_convert_light(uint16_t lux)
{ {
uint8_t exponent, mantissa; uint8_t exponent, mantissa;
float result = 0.045; uint32_t result;
exponent = (lux >> 8) & 0xFF; exponent = (lux >> 8) & 0xFF;
exponent = (exponent == 0x0F ? exponent & 0x0E : exponent); exponent = (exponent == 0x0F ? exponent & 0x0E : exponent);
mantissa = (lux >> 0) & 0xFF; mantissa = (lux >> 0) & 0xFF;
result *= 2 ^ exponent * mantissa; result = 45 * (2 ^ exponent * mantissa) / 10;
return result; return (uint16_t)result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int
status(int type)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
uint16_t value;
if(!enabled) {
PRINTF("MAX44009: sensor not started\n");
return MAX44009_ERROR;
}
if(type == MAX44009_READ_RAW_LIGHT) {
return max44009_read_light();
} else if(type == MAX44009_READ_LIGHT) {
value = max44009_read_light();
return max44009_convert_light(value);
} else {
PRINTF("MAX44009: invalid value requested\n");
return MAX44009_ERROR;
}
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
if(type == MAX44009_ACTIVATE) {
if(!max44009_is_present()) {
return MAX44009_ERROR;
} else {
max44009_init();
enabled = 1;
return MAX44009_SUCCESS;
}
}
if((type == MAX44009_RESET) && enabled) {
max44009_reset();
return MAX44009_SUCCESS;
} else {
PRINTF("MAX44009: is not enabled\n");
return MAX44009_ERROR;
}
return MAX44009_ERROR;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(max44009, MAX44009_SENSOR, value, configure, status);
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View file

@ -47,30 +47,17 @@
#ifndef MAX44009_H_ #ifndef MAX44009_H_
#define MAX44009_H_ #define MAX44009_H_
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define MAX44009_ERROR (-1)
* \brief Initialize the MAX44009 sensor #define MAX44009_SUCCESS (0)
*/ #define MAX44009_ACTIVATE (SENSORS_ACTIVE)
void max44009_init(void); #define MAX44009_READ_RAW_LIGHT (2)
#define MAX44009_READ_LIGHT (3)
#define MAX44009_RESET (4)
#define MAX44009_NONE (5)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define MAX44009_SENSOR "MAX44009 Sensor"
* \brief Reset the MAX44009 sensor
*/
void max44009_reset(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** extern const struct sensors_sensor max44009;
* \brief Check if the MAX44009 sensor is present
*/
uint8_t max44009_is_present(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the light from the MAX44009 sensor
*/
uint16_t max44009_read_light(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Convert the light from the MAX44009 sensor
*/
float max44009_convert_light(uint16_t light);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* MAX44009_H_ */ #endif /* MAX44009_H_ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -41,8 +41,16 @@
* Pere Tuset <peretuset@openmote.com> * Pere Tuset <peretuset@openmote.com>
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#include "i2c.h" #include "dev/i2c.h"
#include "sht21.h" #include "dev/sht21.h"
#include "lib/sensors.h"
/*---------------------------------------------------------------------------*/
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* \name SHT21 address * \name SHT21 address
@ -87,13 +95,15 @@
SHT21_BATTERY_ABOVE_2V25 | \ SHT21_BATTERY_ABOVE_2V25 | \
SHT21_OTP_RELOAD_DISABLE) SHT21_OTP_RELOAD_DISABLE)
#define SHT21_USER_CONFIG (SHT21_RESOLUTION_8b_12b | \ #define SHT21_USER_CONFIG (SHT21_RESOLUTION_12b_14b | \
SHT21_ONCHIP_HEATER_DISABLE | \ SHT21_ONCHIP_HEATER_DISABLE | \
SHT21_BATTERY_ABOVE_2V25 | \ SHT21_BATTERY_ABOVE_2V25 | \
SHT21_OTP_RELOAD_DISABLE) SHT21_OTP_RELOAD_DISABLE)
/** @} */ /** @} */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static uint8_t enabled;
/*---------------------------------------------------------------------------*/
static void
sht21_init(void) sht21_init(void)
{ {
uint8_t config[2]; uint8_t config[2];
@ -116,14 +126,14 @@ sht21_init(void)
i2c_burst_send(SHT21_ADDRESS, config, sizeof(config)); i2c_burst_send(SHT21_ADDRESS, config, sizeof(config));
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void static void
sht21_reset(void) sht21_reset(void)
{ {
/* Send a soft-reset command according to the datasheet (pag. 9, fig. 17) */ /* Send a soft-reset command according to the datasheet (pag. 9, fig. 17) */
i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD); i2c_single_send(SHT21_ADDRESS, SHT21_RESET_CMD);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint8_t static uint8_t
sht21_is_present(void) sht21_is_present(void)
{ {
uint8_t status; uint8_t status;
@ -142,7 +152,7 @@ sht21_is_present(void)
return (is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG); return (is_present == SHT21_USER_CONFIG) || (is_present == SHT21_DEFAULT_CONFIG);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static uint32_t
sht21_read_temperature(void) sht21_read_temperature(void)
{ {
uint8_t sht21_temperature[2]; uint8_t sht21_temperature[2];
@ -152,23 +162,24 @@ sht21_read_temperature(void)
i2c_single_send(SHT21_ADDRESS, SHT21_TEMPERATURE_HM_CMD); i2c_single_send(SHT21_ADDRESS, SHT21_TEMPERATURE_HM_CMD);
i2c_burst_receive(SHT21_ADDRESS, sht21_temperature, sizeof(sht21_temperature)); i2c_burst_receive(SHT21_ADDRESS, sht21_temperature, sizeof(sht21_temperature));
temperature = (sht21_temperature[0] << 8) | (sht21_temperature[1] & SHT21_STATUS_MASK); temperature = (sht21_temperature[0] << 8) | ((sht21_temperature[1] & SHT21_STATUS_MASK));
return temperature; return temperature;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
float static int16_t
sht21_convert_temperature(uint16_t temperature) sht21_convert_temperature(uint32_t temperature)
{ {
float result; int16_t result;
result = -46.85; temperature *= 17572;
result += 175.72 * (float)temperature / 65536.0; temperature = temperature >> 16;
result = (int16_t)temperature - 4685;
return result; return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
uint16_t static uint32_t
sht21_read_humidity(void) sht21_read_humidity(void)
{ {
uint8_t sht21_humidity[2]; uint8_t sht21_humidity[2];
@ -178,20 +189,86 @@ sht21_read_humidity(void)
i2c_single_send(SHT21_ADDRESS, SHT21_HUMIDITY_HM_CMD); i2c_single_send(SHT21_ADDRESS, SHT21_HUMIDITY_HM_CMD);
i2c_burst_receive(SHT21_ADDRESS, sht21_humidity, sizeof(sht21_humidity)); i2c_burst_receive(SHT21_ADDRESS, sht21_humidity, sizeof(sht21_humidity));
humidity = (sht21_humidity[0] << 8) | (sht21_humidity[1] & SHT21_STATUS_MASK); humidity = (sht21_humidity[0] << 8) | ((sht21_humidity[1] & SHT21_STATUS_MASK));
return humidity; return humidity;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
float static int16_t
sht21_convert_humidity(uint16_t humidity) sht21_convert_humidity(uint32_t humidity)
{ {
float result; int16_t result;
result = -6.0; humidity *= 12500;
result += 125.0 * (float)humidity / 65536.0; humidity = humidity >> 16;
result = (int16_t)humidity - 600;
result = (result > 10000) ? 10000 : result;
return result; return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int
status(int type)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
uint32_t value;
if(!enabled) {
PRINTF("SHT21: sensor not started\n");
return SHT21_ERROR;
}
if(type == SHT21_READ_RAW_TEMP) {
return sht21_read_temperature();
} else if(type == SHT21_READ_RAW_RHUM) {
return sht21_read_humidity();
} else if(type == SHT21_READ_TEMP) {
value = sht21_read_temperature();
return sht21_convert_temperature(value);
} else if(type == SHT21_READ_RHUM) {
value = sht21_read_humidity();
return sht21_convert_humidity(value);
} else {
PRINTF("SHT21: invalid value requested\n");
return SHT21_ERROR;
}
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
if(type == SHT21_ACTIVATE) {
if(!sht21_is_present()) {
PRINTF("SHT21: is not present\n");
return SHT21_ERROR;
} else {
sht21_init();
enabled = 1;
return SHT21_SUCCESS;
}
}
if(type == SHT21_RESET && enabled) {
sht21_reset();
return SHT21_SUCCESS;
} else {
PRINTF("SHT21: is not enabled\n");
return SHT21_ERROR;
}
return SHT21_ERROR;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(sht21, SHT21_SENSOR, value, configure, status);
/*---------------------------------------------------------------------------*/
/** @} */ /** @} */

View file

@ -47,40 +47,19 @@
#ifndef SHT21_H_ #ifndef SHT21_H_
#define SHT21_H_ #define SHT21_H_
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define SHT21_ERROR (-1)
* \brief Initialize the SHT21 sensor #define SHT21_SUCCESS (0)
*/ #define SHT21_ACTIVATE (SENSORS_ACTIVE)
void sht21_init(void); #define SHT21_READ_RAW_TEMP (2)
#define SHT21_READ_RAW_RHUM (3)
#define SHT21_READ_TEMP (4)
#define SHT21_READ_RHUM (5)
#define SHT21_RESET (6)
#define SHT21_NONE (7)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** #define SHT21_SENSOR "SHT21 Sensor"
* \brief Reset the SHT21 sensor
*/
void sht21_reset(void);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** extern const struct sensors_sensor sht21;
* \brief Check if the SHT21 sensor is present
*/
uint8_t sht21_is_present(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the temperature from the SHT21 sensor
*/
uint16_t sht21_read_temperature(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Convert the temperature from the SHT21 sensor
*/
float sht21_convert_temperature(uint16_t temperature);
/*---------------------------------------------------------------------------*/
/**
* \brief Read the relative humidity from the SHT21 sensor
*/
uint16_t sht21_read_humidity(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Convert the relative humidity from the SHT21 sensor
*/
float sht21_convert_humidity(uint16_t humidity);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* SHT21_H_ */ #endif /* SHT21_H_ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/