Initial commit.
This commit is contained in:
commit
b726d03136
|
@ -0,0 +1,12 @@
|
|||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignConsecutiveAssignments: true
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterEnum: false
|
||||
AfterStruct: false
|
||||
SplitEmptyFunction: false
|
||||
ColumnLimit: 120
|
|
@ -0,0 +1,42 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(imsensors)
|
||||
|
||||
option(IMSENSORS_FLOAT_SUPPORT "Enable floating point support" OFF)
|
||||
|
||||
set(IMSENSORS_SRCS
|
||||
"src/dht/dht_bme280.c"
|
||||
)
|
||||
|
||||
set(IMSENSORS_INCS
|
||||
"include/imsensors"
|
||||
"include/imsensors/dht"
|
||||
)
|
||||
|
||||
set(IMSENSORS_INTF_INCS
|
||||
"include"
|
||||
)
|
||||
|
||||
set(IMSENSORS_DEFS
|
||||
|
||||
)
|
||||
|
||||
set(IMSENSORS_FLOAT_DEFS
|
||||
"IMS_CFG_DHT_BME280_ENABLE_FLOAT"
|
||||
"IMS_CFG_DHT_AHT10_ENABLE_FLOAT"
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} ${IMSENSORS_SRCS})
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${IMSENSORS_INCS}
|
||||
PUBLIC ${IMSENSORS_INTF_INCS}
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE ${IMSENSORS_DEFS}
|
||||
)
|
||||
|
||||
if(IMSENSORS_FLOAT_SUPPORT)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE ${IMSENSORS_FLOAT_DEFS})
|
||||
endif()
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef AHT10_H
|
||||
#define AHT10_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define AHT10_SKIP_BUSY_CHECK
|
||||
|
||||
typedef enum {
|
||||
AHT10_OK,
|
||||
AHT10_FAIL,
|
||||
} aht10_ret_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *tx_data;
|
||||
uint8_t *rx_data;
|
||||
uint16_t tx_size;
|
||||
uint16_t rx_size;
|
||||
} aht10_xfer_desc_t;
|
||||
|
||||
typedef aht10_ret_t (*aht10_i2c_xfer_t)(void *pdev, aht10_xfer_desc_t *xfer);
|
||||
typedef aht10_ret_t (*aht10_delay_t)(void *pdev, uint32_t delay_msec);
|
||||
|
||||
typedef struct {
|
||||
double temperature;
|
||||
double humidity;
|
||||
} aht10_result_t;
|
||||
|
||||
typedef struct {
|
||||
aht10_i2c_xfer_t xfer;
|
||||
aht10_delay_t delay;
|
||||
} aht10_cb_t;
|
||||
|
||||
typedef struct {
|
||||
aht10_cb_t cb;
|
||||
void *user_data;
|
||||
} aht10_t;
|
||||
|
||||
aht10_ret_t aht10_init(aht10_t *aht);
|
||||
aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef ims_bme280_DHT_H
|
||||
#define ims_bme280_DHT_H
|
||||
|
||||
#include "sensors_common.h"
|
||||
|
||||
typedef enum {
|
||||
IMS_BME280_MODE_SLEEP,
|
||||
IMS_BME280_MODE_FORCED,
|
||||
IMS_BME280_MODE_NORMAL,
|
||||
} ims_bme280_mode_t;
|
||||
|
||||
typedef enum {
|
||||
IMS_BME280_OSRS_SKIP,
|
||||
IMS_BME280_OSRS_1,
|
||||
IMS_BME280_OSRS_2,
|
||||
IMS_BME280_OSRS_4,
|
||||
IMS_BME280_OSRS_8,
|
||||
IMS_BME280_OSRS_16,
|
||||
} ims_bme280_osrs_config_t;
|
||||
|
||||
typedef enum {
|
||||
IMS_BME280_FILTER_OFF,
|
||||
IMS_BME280_FILTER_2,
|
||||
IMS_BME280_FILTER_4,
|
||||
IMS_BME280_FILTER_8,
|
||||
IMS_BME280_FILTER_16,
|
||||
} ims_bme280_fiter_config_t;
|
||||
|
||||
typedef enum {
|
||||
IMS_BME280_PRESET_WEATHER,
|
||||
IMS_BME280_PRESET_HUMIDITY,
|
||||
IMS_BME280_PRESET_INDOOR_NAV,
|
||||
IMS_BME280_PRESET_GAMING,
|
||||
} ims_bme280_mode_preset_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t dig_T1;
|
||||
int16_t dig_T2;
|
||||
int16_t dig_T3;
|
||||
uint16_t dig_P1;
|
||||
int16_t dig_P2;
|
||||
int16_t dig_P3;
|
||||
int16_t dig_P4;
|
||||
int16_t dig_P5;
|
||||
int16_t dig_P6;
|
||||
int16_t dig_P7;
|
||||
int16_t dig_P8;
|
||||
int16_t dig_P9;
|
||||
uint8_t dig_H1;
|
||||
int16_t dig_H2;
|
||||
uint8_t dig_H3;
|
||||
int16_t dig_H4;
|
||||
int16_t dig_H5;
|
||||
int8_t dig_H6;
|
||||
} ims_bme280_trim_t;
|
||||
|
||||
typedef struct {
|
||||
ims_bme280_mode_t mode;
|
||||
ims_bme280_osrs_config_t osrs_t;
|
||||
ims_bme280_osrs_config_t osrs_p;
|
||||
ims_bme280_osrs_config_t osrs_h;
|
||||
uint8_t t_sb;
|
||||
ims_bme280_fiter_config_t filter;
|
||||
} ims_bme280_config_t;
|
||||
|
||||
typedef struct {
|
||||
double temperature;
|
||||
double pressure;
|
||||
double humidity;
|
||||
} ims_bme280_result_t;
|
||||
|
||||
typedef struct {
|
||||
ims_i2c_xfer_t i2c_xfer;
|
||||
} ims_bme280_cb_t;
|
||||
|
||||
typedef struct {
|
||||
void *user_data;
|
||||
ims_bme280_trim_t trim;
|
||||
ims_bme280_cb_t cb;
|
||||
int32_t t_fine;
|
||||
} ims_bme280_t;
|
||||
|
||||
ims_ret_t ims_bme280_init(ims_bme280_t *bme);
|
||||
ims_ret_t ims_bme280_preset_config(ims_bme280_config_t *config, ims_bme280_mode_preset_t preset);
|
||||
ims_ret_t ims_bme280_apply_config(ims_bme280_t *bme, ims_bme280_config_t *config);
|
||||
ims_ret_t ims_bme280_measure(ims_bme280_t *bme, ims_bme280_result_t *result);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef SENSORS_COMMON_H
|
||||
#define SENSORS_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
IMS_SUCCESS,
|
||||
IMS_FAIL,
|
||||
} ims_ret_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *tx_data;
|
||||
uint8_t *rx_data;
|
||||
uint16_t tx_size;
|
||||
uint16_t rx_size;
|
||||
} ims_i2c_xfer_desc_t;
|
||||
|
||||
/* I2C xfer functions */
|
||||
typedef ims_ret_t (*ims_i2c_xfer_t)(void *pdev, uint16_t addr, ims_i2c_xfer_desc_t *xfer);
|
||||
|
||||
/* Delay */
|
||||
typedef ims_ret_t (*ims_delay_t)(void *pdev, uint32_t delay_msec);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,135 @@
|
|||
#include <stddef.h>
|
||||
|
||||
/* Private header */
|
||||
#include "aht10.h"
|
||||
|
||||
#define AHT10_STATUS_CALIBRATED_MASK (1U << 3U)
|
||||
#define AHT10_STATUS_BUSY_MASK (1U << 7U)
|
||||
|
||||
#define AHT10_ERROR_CHECK(x) \
|
||||
if (x != AHT10_OK) return AHT10_FAIL
|
||||
|
||||
typedef struct {
|
||||
uint8_t status;
|
||||
uint32_t temperature;
|
||||
uint32_t humidity;
|
||||
} aht10_raw_t;
|
||||
|
||||
static aht10_ret_t aht10_software_reset(aht10_t *aht) {
|
||||
/* Reset and initialize device */
|
||||
|
||||
uint8_t tx_data[3] = {0xBA};
|
||||
|
||||
aht10_xfer_desc_t xfer = {
|
||||
.tx_data = tx_data,
|
||||
.tx_size = 1U,
|
||||
.rx_data = NULL,
|
||||
.rx_size = 0U,
|
||||
};
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 20));
|
||||
|
||||
tx_data[0] = 0xE1;
|
||||
tx_data[1] = 0x08;
|
||||
tx_data[2] = 0x00;
|
||||
|
||||
xfer.tx_size = 3U;
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
|
||||
|
||||
return AHT10_OK;
|
||||
}
|
||||
|
||||
static aht10_ret_t aht10_start_measurement(aht10_t *aht) {
|
||||
/* Start measurement */
|
||||
|
||||
uint8_t tx_data[3] = {0xAC, 0x33, 0x00};
|
||||
|
||||
aht10_xfer_desc_t xfer = {
|
||||
.tx_data = tx_data,
|
||||
.tx_size = 3U,
|
||||
.rx_data = NULL,
|
||||
.rx_size = 0U,
|
||||
};
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
|
||||
|
||||
return AHT10_OK;
|
||||
}
|
||||
|
||||
static aht10_ret_t aht10_read_result(aht10_t *aht, aht10_raw_t *raw) {
|
||||
/* Read conversion result */
|
||||
|
||||
uint8_t tx_data[] = {0x71};
|
||||
uint8_t rx_data[6];
|
||||
|
||||
aht10_xfer_desc_t xfer = {
|
||||
.tx_data = tx_data,
|
||||
.tx_size = 1U,
|
||||
.rx_data = rx_data,
|
||||
.rx_size = 6U,
|
||||
};
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.xfer(aht->user_data, &xfer));
|
||||
|
||||
raw->humidity = rx_data[1] << 12U;
|
||||
raw->humidity |= rx_data[2] << 4U;
|
||||
raw->humidity |= rx_data[3] >> 4U;
|
||||
|
||||
raw->temperature = (rx_data[3] & 0x0FU) << 16U;
|
||||
raw->temperature |= rx_data[4] << 8U;
|
||||
raw->temperature |= rx_data[5];
|
||||
|
||||
raw->status = rx_data[0];
|
||||
|
||||
return AHT10_OK;
|
||||
}
|
||||
|
||||
aht10_ret_t aht10_init(aht10_t *aht) {
|
||||
/* Check if we need initialization */
|
||||
|
||||
/* Delay 40ms after POR */
|
||||
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 40));
|
||||
|
||||
aht10_raw_t raw;
|
||||
|
||||
/* Check 0x71 status byte, if uncalibrated then reset and calibrate it. */
|
||||
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
|
||||
if ((raw.status & AHT10_STATUS_CALIBRATED_MASK) == 0) {
|
||||
AHT10_ERROR_CHECK(aht10_software_reset(aht));
|
||||
}
|
||||
|
||||
return AHT10_OK;
|
||||
}
|
||||
|
||||
aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result) {
|
||||
/* Start a measurement and read back result... */
|
||||
|
||||
AHT10_ERROR_CHECK(aht10_start_measurement(aht));
|
||||
|
||||
AHT10_ERROR_CHECK(aht->cb.delay(aht->user_data, 80));
|
||||
|
||||
aht10_raw_t raw;
|
||||
|
||||
uint8_t max_retries = 5U;
|
||||
|
||||
do {
|
||||
AHT10_ERROR_CHECK(aht10_read_result(aht, &raw));
|
||||
max_retries--;
|
||||
if (max_retries == 0) {
|
||||
return AHT10_FAIL;
|
||||
}
|
||||
}
|
||||
#ifndef AHT10_SKIP_BUSY_CHECK
|
||||
while (raw.status & AHT10_STATUS_BUSY_MASK);
|
||||
#else
|
||||
while (0);
|
||||
#endif
|
||||
|
||||
result->temperature = ((double)raw.temperature * 200.0 / 1048576.0) - 50.0;
|
||||
result->humidity = (double)raw.humidity * 100.0 / 1048576.0;
|
||||
|
||||
return AHT10_OK;
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
#include "dht_bme280.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef IMS_CFG_DHT_BME280_ENABLE_FLOAT
|
||||
#define ims_bme280_compensate_T ims_bme280_compensate_T_double
|
||||
#define ims_bme280_compensate_P ims_bme280_compensate_P_double
|
||||
#define ims_bme280_compensate_H ims_bme280_compensate_H_double
|
||||
#else
|
||||
#define ims_bme280_compensate_T ims_bme280_compensate_T_int32
|
||||
#define ims_bme280_compensate_P ims_bme280_compensate_P_int32
|
||||
#define ims_bme280_compensate_H ims_bme280_compensate_H_int32
|
||||
#endif
|
||||
|
||||
#define IMS_BME280_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
|
||||
|
||||
static double ims_bme280_compensate_T_double(ims_bme280_t *bme, int32_t adc_T);
|
||||
static double ims_bme280_compensate_P_double(ims_bme280_t *bme, int32_t adc_P);
|
||||
static double ims_bme280_compensate_H_double(ims_bme280_t *bme, int32_t adc_H);
|
||||
|
||||
static ims_ret_t ims_bme280_reset(ims_bme280_t *bme) {
|
||||
return bme->cb.write_register_cb(bme->user_data, 0xE0, 0xB6);
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bme280_read_trim_data(ims_bme280_t *bme) {
|
||||
ims_ret_t ret;
|
||||
uint8_t rx_buf[2];
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x88, rx_buf, 0x02); // T1
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_T1 = IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x8A, rx_buf, 0x02); // T2
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_T2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x8C, rx_buf, 0x02); // T3
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_T3 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x8E, rx_buf, 0x02); // P1
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P1 = IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x90, rx_buf, 0x02); // P2
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x92, rx_buf, 0x02); // P3
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P3 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x94, rx_buf, 0x02); // P4
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P4 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x96, rx_buf, 0x02); // P5
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P5 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x98, rx_buf, 0x02); // P5
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P6 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x9A, rx_buf, 0x02); // P7
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P7 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x9C, rx_buf, 0x02); // P8
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P8 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0x9E, rx_buf, 0x02); // P9
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_P9 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xA1, rx_buf, 0x01); // H1
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H1 = rx_buf[0];
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xE1, rx_buf, 0x02); // H2
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H2 = (int16_t)IMS_BME280_CONCAT_BYTES(rx_buf[1], rx_buf[0]);
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xE3, rx_buf, 0x01); // H3
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H3 = (uint8_t)rx_buf[0];
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xE4, rx_buf, 0x02); // H4
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H4 = (int16_t)(((int8_t)rx_buf[0] << 0x04) | (rx_buf[1] & 0x0F));
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xE5, rx_buf, 0x02); // H5
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H5 = (int16_t)(((int8_t)rx_buf[1] << 0x04) | (rx_buf[0] >> 0x04));
|
||||
|
||||
ret = bme->cb.read_register_cb(bme->user_data, 0xE7, rx_buf, 0x01); // H6
|
||||
if (ret == IMS_FAIL) return ret;
|
||||
bme->trim.dig_H6 = (int8_t)rx_buf[0];
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t bme280_init(ims_bme280_t *bme) {
|
||||
if (!bme) return IMS_FAIL;
|
||||
if (ims_bme280_reset(bme) == IMS_FAIL) return IMS_FAIL;
|
||||
bme->cb.delay_cb(bme->user_data, 100);
|
||||
if (ims_bme280_read_trim_data(bme) == IMS_FAIL) return IMS_FAIL;
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t bme280_preset_config(ims_bme280_config_t *config, ims_bme280_mode_preset_t preset) {
|
||||
switch (preset) {
|
||||
case IMS_BME280_PRESET_WEATHER:
|
||||
config->mode = IMS_BME280_MODE_FORCED;
|
||||
config->osrs_t = IMS_BME280_OSRS_1;
|
||||
config->osrs_p = IMS_BME280_OSRS_1;
|
||||
config->osrs_h = IMS_BME280_OSRS_1;
|
||||
config->filter = IMS_BME280_FILTER_OFF;
|
||||
break;
|
||||
case IMS_BME280_PRESET_HUMIDITY:
|
||||
config->mode = IMS_BME280_MODE_FORCED;
|
||||
config->osrs_t = IMS_BME280_OSRS_1;
|
||||
config->osrs_p = IMS_BME280_OSRS_SKIP;
|
||||
config->osrs_h = IMS_BME280_OSRS_1;
|
||||
config->filter = IMS_BME280_FILTER_OFF;
|
||||
break;
|
||||
case IMS_BME280_PRESET_INDOOR_NAV:
|
||||
config->mode = IMS_BME280_MODE_NORMAL;
|
||||
config->osrs_t = IMS_BME280_OSRS_2;
|
||||
config->osrs_p = IMS_BME280_OSRS_16;
|
||||
config->osrs_h = IMS_BME280_OSRS_1;
|
||||
config->filter = IMS_BME280_FILTER_16;
|
||||
break;
|
||||
case IMS_BME280_PRESET_GAMING:
|
||||
config->mode = IMS_BME280_MODE_NORMAL;
|
||||
config->osrs_t = IMS_BME280_OSRS_1;
|
||||
config->osrs_p = IMS_BME280_OSRS_4;
|
||||
config->osrs_h = IMS_BME280_OSRS_SKIP;
|
||||
config->filter = IMS_BME280_FILTER_4;
|
||||
break;
|
||||
}
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t bme280_apply_config(ims_bme280_t *bme, ims_bme280_config_t *config) {
|
||||
uint8_t reg_config = config->filter << 0x02;
|
||||
uint8_t reg_ctrl_measure = (uint8_t)((config->osrs_t << 0x05) | (config->osrs_p << 0x02) | config->mode);
|
||||
uint8_t reg_ctrl_hum = config->osrs_h;
|
||||
bme->cb.write_register_cb(bme->user_data, 0xF5, reg_config);
|
||||
bme->cb.write_register_cb(bme->user_data, 0xF2, reg_ctrl_hum);
|
||||
bme->cb.write_register_cb(bme->user_data, 0xF4, reg_ctrl_measure);
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t bme280_measure(ims_bme280_t *bme, ims_bme280_result_t *result) {
|
||||
uint32_t raw_P = 0x00;
|
||||
uint32_t raw_T = 0x00;
|
||||
uint32_t raw_H = 0x00;
|
||||
uint8_t measure_data[8];
|
||||
uint8_t status = 0;
|
||||
uint8_t ctrl_meas;
|
||||
uint8_t loop_count = 0;
|
||||
if (bme->cb.read_register_cb(bme->user_data, 0xF4, &ctrl_meas, 0x01) != IMS_SUCCESS) return IMS_FAIL;
|
||||
|
||||
bme->cb.write_register_cb(bme->user_data, 0xF4, ctrl_meas | IMS_BME280_MODE_FORCED);
|
||||
do {
|
||||
if (bme->cb.read_register_cb(bme->user_data, 0xF3, &status, 0x01) != IMS_SUCCESS) return IMS_FAIL;
|
||||
loop_count++;
|
||||
bme->cb.delay_cb(bme->user_data, 100);
|
||||
} while (status & 0x08 && (loop_count < 12));
|
||||
|
||||
if (bme->cb.read_register_cb(bme->user_data, 0xF7, measure_data, 0x08) != IMS_SUCCESS) return IMS_FAIL;
|
||||
raw_P =
|
||||
((uint32_t)measure_data[0] << 12) | ((uint32_t)measure_data[1] << 0x04) | ((uint32_t)measure_data[2] >> 0x04);
|
||||
raw_T =
|
||||
((uint32_t)measure_data[3] << 12) | ((uint32_t)measure_data[4] << 0x04) | ((uint32_t)measure_data[5] >> 0x04);
|
||||
raw_H = ((uint32_t)measure_data[6] << 8) | ((uint32_t)measure_data[7]);
|
||||
result->temperature = ims_bme280_compensate_T(bme, raw_T);
|
||||
result->pressure = ims_bme280_compensate_P(bme, raw_P);
|
||||
result->humidity = ims_bme280_compensate_H(bme, raw_H);
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static double ims_bme280_compensate_T_double(ims_bme280_t *bme, int32_t adc_T) {
|
||||
double var1, var2, T;
|
||||
var1 = (((double)adc_T) / 16384.0 - ((double)bme->trim.dig_T1) / 1024.0) * ((double)bme->trim.dig_T2);
|
||||
var2 = ((((double)adc_T) / 131072.0 - ((double)bme->trim.dig_T1) / 8192.0) *
|
||||
(((double)adc_T) / 131072.0 - ((double)bme->trim.dig_T1) / 8192.0)) *
|
||||
((double)bme->trim.dig_T3);
|
||||
bme->t_fine = (int32_t)(var1 + var2);
|
||||
T = (var1 + var2) / 5120.0;
|
||||
return T;
|
||||
}
|
||||
|
||||
static double ims_bme280_compensate_P_double(ims_bme280_t *bme, int32_t adc_P) {
|
||||
double var1, var2, p;
|
||||
var1 = ((double)bme->t_fine / 2.0) - 64000.0;
|
||||
var2 = var1 * var1 * ((double)bme->trim.dig_P6) / 32768.0;
|
||||
var2 = var2 + var1 * ((double)bme->trim.dig_P5) * 2.0;
|
||||
var2 = (var2 / 4.0) + (((double)bme->trim.dig_P4) * 65536.0);
|
||||
var1 = (((double)bme->trim.dig_P3) * var1 * var1 / 524288.0 + ((double)bme->trim.dig_P2) * var1) / 524288.0;
|
||||
var1 = (1.0 + var1 / 32768.0) * ((double)bme->trim.dig_P1);
|
||||
if (var1 == 0.0) {
|
||||
return 0; // avoid exception caused by division by zero
|
||||
}
|
||||
p = 1048576.0 - (double)adc_P;
|
||||
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
|
||||
var1 = ((double)bme->trim.dig_P9) * p * p / 2147483648.0;
|
||||
var2 = p * ((double)bme->trim.dig_P8) / 32768.0;
|
||||
p = p + (var1 + var2 + ((double)bme->trim.dig_P7)) / 16.0;
|
||||
return p;
|
||||
}
|
||||
|
||||
static double ims_bme280_compensate_H_double(ims_bme280_t *bme, int32_t adc_H) {
|
||||
double var_H;
|
||||
var_H = (((double)bme->t_fine) - 76800.0);
|
||||
var_H = (adc_H - (((double)bme->trim.dig_H4) * 64.0 + ((double)bme->trim.dig_H5) / 16384.0 * var_H)) *
|
||||
(((double)bme->trim.dig_H2) / 65536.0 *
|
||||
(1.0 + ((double)bme->trim.dig_H6) / 67108864.0 * var_H *
|
||||
(1.0 + ((double)bme->trim.dig_H3) / 67108864.0 * var_H)));
|
||||
var_H = var_H * (1.0 - ((double)bme->trim.dig_H1) * var_H / 524288.0);
|
||||
if (var_H > 100.0)
|
||||
var_H = 100.0;
|
||||
else if (var_H < 0.0)
|
||||
var_H = 0.0;
|
||||
return var_H;
|
||||
}
|
Loading…
Reference in New Issue