drivers: sensor: ccs811: support update of environmental conditions
Accurate estimate of gas presence requires temperature and humidity data. Add API to update these values. Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
316c6e3aeb
commit
c90a738d8c
3 changed files with 89 additions and 0 deletions
|
@ -86,6 +86,7 @@ int ccs811_baseline_fetch(struct device *dev)
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
rc = baseline;
|
rc = baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +105,74 @@ int ccs811_baseline_update(struct device *dev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ccs811_envdata_update(struct device *dev,
|
||||||
|
const struct sensor_value *temperature,
|
||||||
|
const struct sensor_value *humidity)
|
||||||
|
{
|
||||||
|
struct ccs811_data *drv_data = dev->driver_data;
|
||||||
|
int rc;
|
||||||
|
u8_t buf[5] = { CCS811_REG_ENV_DATA };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Environment data are represented in a broken whole/fraction
|
||||||
|
* system that specified a 9-bit fractional part to represent
|
||||||
|
* milli-units. Since 1000 is greater than 512, the device
|
||||||
|
* actually only pays attention to the top bit, treating it as
|
||||||
|
* indicating 0.5. So we only write the first octet (7-bit
|
||||||
|
* while plus 1-bit half).
|
||||||
|
*
|
||||||
|
* Humidity is simple: scale it by two and round to the
|
||||||
|
* nearest half. Assume the fractional part is not
|
||||||
|
* negative.
|
||||||
|
*/
|
||||||
|
if (humidity) {
|
||||||
|
int value = 2 * humidity->val1;
|
||||||
|
|
||||||
|
value += (250000 + humidity->val2) / 500000;
|
||||||
|
if (value < 0) {
|
||||||
|
value = 0;
|
||||||
|
} else if (value > (2 * 100)) {
|
||||||
|
value = 2 * 100;
|
||||||
|
}
|
||||||
|
LOG_DBG("HUM %d.%06d becomes %d",
|
||||||
|
humidity->val1, humidity->val2, value);
|
||||||
|
buf[1] = value;
|
||||||
|
} else {
|
||||||
|
buf[1] = 2 * 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Temperature is offset from -25 Cel. Values below minimum
|
||||||
|
* store as zero. Default is 25 Cel. Again we round to the
|
||||||
|
* nearest half, complicated by Zephyr's signed representation
|
||||||
|
* of the fractional part.
|
||||||
|
*/
|
||||||
|
if (temperature) {
|
||||||
|
int value = 2 * temperature->val1;
|
||||||
|
|
||||||
|
if (temperature->val2 < 0) {
|
||||||
|
value += (250000 + temperature->val2) / 500000;
|
||||||
|
} else {
|
||||||
|
value += (-250000 + temperature->val2) / 500000;
|
||||||
|
}
|
||||||
|
if (value < (2 * -25)) {
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value += 2 * 25;
|
||||||
|
}
|
||||||
|
LOG_DBG("TEMP %d.%06d becomes %d",
|
||||||
|
temperature->val1, temperature->val2, value);
|
||||||
|
buf[3] = value;
|
||||||
|
} else {
|
||||||
|
buf[3] = 2 * (25 + 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_wake(drv_data, true);
|
||||||
|
rc = i2c_write(drv_data->i2c, buf, sizeof(buf), DT_INST_0_AMS_CCS811_BASE_ADDRESS);
|
||||||
|
set_wake(drv_data, false);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int ccs811_sample_fetch(struct device *dev, enum sensor_channel chan)
|
static int ccs811_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
{
|
{
|
||||||
struct ccs811_data *drv_data = dev->driver_data;
|
struct ccs811_data *drv_data = dev->driver_data;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define CCS811_REG_MEAS_MODE 0x01
|
#define CCS811_REG_MEAS_MODE 0x01
|
||||||
#define CCS811_REG_ALG_RESULT_DATA 0x02
|
#define CCS811_REG_ALG_RESULT_DATA 0x02
|
||||||
#define CCS811_REG_RAW_DATA 0x03
|
#define CCS811_REG_RAW_DATA 0x03
|
||||||
|
#define CCS811_REG_ENV_DATA 0x05
|
||||||
#define CCS811_REG_THRESHOLDS 0x10
|
#define CCS811_REG_THRESHOLDS 0x10
|
||||||
#define CCS811_REG_BASELINE 0x11
|
#define CCS811_REG_BASELINE 0x11
|
||||||
#define CCS811_REG_HW_ID 0x20
|
#define CCS811_REG_HW_ID 0x20
|
||||||
|
|
|
@ -20,6 +20,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
|
#include <drivers/sensor.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fetch the current value of the BASELINE register.
|
* @brief Fetch the current value of the BASELINE register.
|
||||||
|
@ -51,6 +52,24 @@ int ccs811_baseline_fetch(struct device *dev);
|
||||||
*/
|
*/
|
||||||
int ccs811_baseline_update(struct device *dev, u16_t baseline);
|
int ccs811_baseline_update(struct device *dev, u16_t baseline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the ENV_DATA register.
|
||||||
|
*
|
||||||
|
* Accurate calculation of gas levels requires accurate environment
|
||||||
|
* data. Measurements are only accurate to 0.5 Cel and 0.5 %RH.
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the sensor device
|
||||||
|
*
|
||||||
|
* @param temperature the current temperature at the sensor
|
||||||
|
*
|
||||||
|
* @param humidity the current humidity at the sensor
|
||||||
|
*
|
||||||
|
* @return 0 if successful, negative errno code if failure.
|
||||||
|
*/
|
||||||
|
int ccs811_envdata_update(struct device *dev,
|
||||||
|
const struct sensor_value *temperature,
|
||||||
|
const struct sensor_value *humidity);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue