cleanup + examples

This commit is contained in:
William Clark 2023-11-07 16:24:40 +00:00
parent 893ff1ec81
commit 4e09be2bf3
9 changed files with 395 additions and 43 deletions

View File

@ -18,7 +18,6 @@ static int set_spi_page(bme680_t *bme680, uint8_t no);
/********************************************************************/ /********************************************************************/
static int write_dev(bme680_t *bme680, uint8_t reg, uint8_t value) { static int write_dev(bme680_t *bme680, uint8_t reg, uint8_t value) {
if (BME680_IS_SPI(bme680->mode)) { if (BME680_IS_SPI(bme680->mode)) {
check_spi_page(bme680, reg); check_spi_page(bme680, reg);
reg &= 0x7F; reg &= 0x7F;
@ -29,7 +28,6 @@ static int write_dev(bme680_t *bme680, uint8_t reg, uint8_t value) {
/********************************************************************/ /********************************************************************/
static int read_dev(bme680_t *bme680, uint8_t reg, uint8_t *dst, uint32_t size) { static int read_dev(bme680_t *bme680, uint8_t reg, uint8_t *dst, uint32_t size) {
if (BME680_IS_SPI(bme680->mode)) { if (BME680_IS_SPI(bme680->mode)) {
check_spi_page(bme680, reg); check_spi_page(bme680, reg);
reg |= 0x80; reg |= 0x80;
@ -57,7 +55,6 @@ static int set_spi_page(bme680_t *bme680, uint8_t page_no) {
/********************************************************************/ /********************************************************************/
static int read_id(bme680_t *bme680, uint8_t *id) { static int read_id(bme680_t *bme680, uint8_t *id) {
uint8_t id_reg; uint8_t id_reg;
/* force spi page 0. special case */ /* force spi page 0. special case */
@ -73,8 +70,27 @@ static int read_id(bme680_t *bme680, uint8_t *id) {
} }
/********************************************************************/ /********************************************************************/
int bme680_init(bme680_t *bme680, uint8_t mode) { /* write local setpoint index to device, must not be running */
int bme680_write_setpoint_index(bme680_t *bme680) {
/* setpoint (0 thru 9) bits 0,1,2,3 and run_gas bit 4 */
uint8_t ctrl_gas_1 = (bme680->setpoint & 0x0F) | (1 << 4);
return write_dev(bme680, REG_CTRL_GAS_1, ctrl_gas_1);
}
/********************************************************************/
/* read the currently selected heater setpoint index on the device */
int bme680_read_setpoint_index(bme680_t *bme680, uint8_t *index) {
uint8_t meas_status;
int err = 0;
err |= read_dev(bme680, REG_MEAS_STATUS, &meas_status, 1);
*index = (meas_status) & 0x0F;
return err;
}
/********************************************************************/
int bme680_init(bme680_t *bme680, uint8_t mode) {
uint8_t id; uint8_t id;
int i; int i;
@ -82,12 +98,12 @@ int bme680_init(bme680_t *bme680, uint8_t mode) {
bme680->spi_page = 0; bme680->spi_page = 0;
bme680->gas_valid = 0; bme680->gas_valid = 0;
bme680->heat_stab = 0; bme680->heat_stab = 0;
bme680->setpoint = 0;
if (bme680->dev.init() != 0) { if (bme680->dev.init() != 0) {
return 1; return 1;
} }
if (read_id(bme680, &id) != 0) { if (read_id(bme680, &id) != 0) {
return 1; return 1;
} }
@ -139,7 +155,6 @@ int bme680_reset(bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
/* configure device */ /* configure device */
int bme680_configure(bme680_t *bme680) { int bme680_configure(bme680_t *bme680) {
uint8_t meas, hum, filter, ctrl_gas1, ctrl_gas0, err; uint8_t meas, hum, filter, ctrl_gas1, ctrl_gas0, err;
int i; int i;
meas = hum = filter = err = 0; meas = hum = filter = err = 0;
@ -170,7 +185,7 @@ int bme680_configure(bme680_t *bme680) {
err |= write_dev(bme680, 0x59 - i, bme680->cfg.idac_heat[9 - i]); err |= write_dev(bme680, 0x59 - i, bme680->cfg.idac_heat[9 - i]);
} }
ctrl_gas1 = bme680->cfg.setpoint | (1 << 4); ctrl_gas1 = bme680->setpoint | (1 << 4);
ctrl_gas0 = 0; /* := (1 << 3) to turn off current going to heater */ ctrl_gas0 = 0; /* := (1 << 3) to turn off current going to heater */
err |= write_dev(bme680, REG_CTRL_GAS_1, ctrl_gas1); err |= write_dev(bme680, REG_CTRL_GAS_1, ctrl_gas1);
@ -183,7 +198,6 @@ SKIP_GAS:
/********************************************************************/ /********************************************************************/
/* To start forced mode, you just have to set the lsb=1 of REG_CTRL_MEAS */ /* To start forced mode, you just have to set the lsb=1 of REG_CTRL_MEAS */
int bme680_start(bme680_t *bme680) { int bme680_start(bme680_t *bme680) {
int err = 0; int err = 0;
uint8_t meas; uint8_t meas;
meas = bme680->cfg.meas | 1; meas = bme680->cfg.meas | 1;
@ -192,11 +206,8 @@ int bme680_start(bme680_t *bme680) {
} }
/********************************************************************/ /********************************************************************/
/* blocks until the device all scheduled conversions are done. /* blocks until all scheduled conversions on the device are done. */
* don't call out of order.
*/
int bme680_poll(bme680_t *bme680) { int bme680_poll(bme680_t *bme680) {
uint8_t meas_status = 0; uint8_t meas_status = 0;
uint8_t gas_measuring = 0; uint8_t gas_measuring = 0;
uint8_t any_measuring = 0; uint8_t any_measuring = 0;
@ -205,7 +216,7 @@ int bme680_poll(bme680_t *bme680) {
do { do {
usleep(5000); /* 5 ms */ usleep(5000); /* 5 ms */
err |= read_dev(bme680, REG_EAS_STATUS, &meas_status, 1); err |= read_dev(bme680, REG_MEAS_STATUS, &meas_status, 1);
gas_measuring = (meas_status >> 6) & 1; gas_measuring = (meas_status >> 6) & 1;
any_measuring = (meas_status >> 5) & 1; any_measuring = (meas_status >> 5) & 1;
@ -217,7 +228,6 @@ int bme680_poll(bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
/* assume start'd and poll'd */ /* assume start'd and poll'd */
int bme680_read(bme680_t *bme680) { int bme680_read(bme680_t *bme680) {
/* begin by reading ADCs */ /* begin by reading ADCs */
uint8_t buffer[3] = {0, 0 ,0}; uint8_t buffer[3] = {0, 0 ,0};
int err = 0; int err = 0;
@ -231,7 +241,6 @@ int bme680_read(bme680_t *bme680) {
err |= read_dev(bme680, 0x25, buffer, 2); err |= read_dev(bme680, 0x25, buffer, 2);
bme680->adc.hum = (buffer[0] << 8) | buffer[1]; bme680->adc.hum = (buffer[0] << 8) | buffer[1];
/* adc readings are only 20-bit when the IIR filter is enabled. /* adc readings are only 20-bit when the IIR filter is enabled.
* otherwise, it depends on the oversample settings. * otherwise, it depends on the oversample settings.
* note: humidity is not IIR filtered, and always 16-bit. * note: humidity is not IIR filtered, and always 16-bit.
@ -302,7 +311,6 @@ static int const_array2_int[16] = {
/********************************************************************/ /********************************************************************/
/********************************************************************/ /********************************************************************/
static void calc_temp_comp_1 (bme680_t *bme680) { static void calc_temp_comp_1 (bme680_t *bme680) {
double var1, var2, temp_comp; double var1, var2, temp_comp;
var1 = (((double)bme680->adc.temp / 16384.0) - ((double)bme680->cal.par_t1 / 1024.0)) * var1 = (((double)bme680->adc.temp / 16384.0) - ((double)bme680->cal.par_t1 / 1024.0)) *
@ -317,7 +325,6 @@ static void calc_temp_comp_1 (bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
static void calc_temp_comp_2 (bme680_t *bme680) { static void calc_temp_comp_2 (bme680_t *bme680) {
int32_t var1, var2, var3, temp_comp; int32_t var1, var2, var3, temp_comp;
var1 = ((int32_t)bme680->adc.temp >> 3) - ((int32_t) bme680->cal.par_t1 << 1); var1 = ((int32_t)bme680->adc.temp >> 3) - ((int32_t) bme680->cal.par_t1 << 1);
@ -337,10 +344,8 @@ static void calc_temp_comp (bme680_t *bme680) {
} }
} }
/********************************************************************/
/********************************************************************/ /********************************************************************/
static void calc_press_comp_1 (bme680_t *bme680) { static void calc_press_comp_1 (bme680_t *bme680) {
double var1, var2, var3, press_comp; double var1, var2, var3, press_comp;
var1 = ((double)bme680->fcomp.tfine / 2.0) - 64000.0; var1 = ((double)bme680->fcomp.tfine / 2.0) - 64000.0;
@ -362,7 +367,6 @@ static void calc_press_comp_1 (bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
static void calc_press_comp_2 (bme680_t *bme680 ) { static void calc_press_comp_2 (bme680_t *bme680 ) {
int32_t var1, var2, var3, press_comp; int32_t var1, var2, var3, press_comp;
var1 = ((int32_t)bme680->icomp.tfine >> 1) - 64000; var1 = ((int32_t)bme680->icomp.tfine >> 1) - 64000;
@ -397,10 +401,8 @@ static void calc_press_comp (bme680_t *bme680) {
} }
} }
/********************************************************************/
/********************************************************************/ /********************************************************************/
static void calc_hum_comp_1 (bme680_t *bme680) { static void calc_hum_comp_1 (bme680_t *bme680) {
double var1, var2, var3, var4, hum_comp, temp_comp; double var1, var2, var3, var4, hum_comp, temp_comp;
temp_comp = bme680->fcomp.temp; temp_comp = bme680->fcomp.temp;
@ -417,7 +419,6 @@ static void calc_hum_comp_1 (bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
static void calc_hum_comp_2 (bme680_t *bme680) { static void calc_hum_comp_2 (bme680_t *bme680) {
int32_t var1, var2, var3, var4, var5, var6, temp_scaled, hum_comp; int32_t var1, var2, var3, var4, var5, var6, temp_scaled, hum_comp;
temp_scaled = (int32_t)bme680->icomp.temp; temp_scaled = (int32_t)bme680->icomp.temp;
@ -448,7 +449,6 @@ static void calc_hum_comp (bme680_t *bme680) {
/********************************************************************/ /********************************************************************/
// TODO: read one big contiguous block // TODO: read one big contiguous block
int bme680_calibrate(bme680_t *bme680) { int bme680_calibrate(bme680_t *bme680) {
uint8_t buffer[3] = {0, 0 ,0}; uint8_t buffer[3] = {0, 0 ,0};
int err = 0; int err = 0;
@ -540,7 +540,6 @@ int bme680_calibrate(bme680_t *bme680) {
return err; return err;
} }
/********************************************************************/
/********************************************************************/ /********************************************************************/
static void calc_gas_res_1(bme680_t *bme680) { static void calc_gas_res_1(bme680_t *bme680) {
double var1, gas_res; double var1, gas_res;
@ -571,7 +570,6 @@ static void calc_gas_res(bme680_t *bme680) {
} }
} }
/********************************************************************/
/********************************************************************/ /********************************************************************/
void bme680_print_calibration (bme680_t *bme680) { void bme680_print_calibration (bme680_t *bme680) {
printf("par_t1: %d\n", bme680->cal.par_t1); printf("par_t1: %d\n", bme680->cal.par_t1);
@ -602,6 +600,7 @@ void bme680_print_calibration (bme680_t *bme680) {
printf("res_heat_val: %d\n", bme680->cal.res_heat_val); printf("res_heat_val: %d\n", bme680->cal.res_heat_val);
} }
/********************************************************************/
static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) { static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) {
double var1, var2, var3, var4, var5; double var1, var2, var3, var4, var5;
uint8_t res_heat; uint8_t res_heat;
@ -616,6 +615,7 @@ static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) {
return res_heat; return res_heat;
} }
/********************************************************************/
static uint8_t calc_target_2(bme680_t *bme680, double target, double ambient) { static uint8_t calc_target_2(bme680_t *bme680, double target, double ambient) {
int32_t var1, var2, var3, var4, var5, res_heat_x100; int32_t var1, var2, var3, var4, var5, res_heat_x100;
uint8_t res_heat; uint8_t res_heat;
@ -631,6 +631,7 @@ static uint8_t calc_target_2(bme680_t *bme680, double target, double ambient) {
return res_heat; return res_heat;
} }
/********************************************************************/
uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient) { uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient) {
if (BME680_IS_FLOAT(bme680->mode)) { if (BME680_IS_FLOAT(bme680->mode)) {
return calc_target_1(bme680, target, ambient); return calc_target_1(bme680, target, ambient);

View File

@ -94,7 +94,6 @@ struct bme680_config {
uint8_t osrs_p; uint8_t osrs_p;
uint8_t osrs_h; uint8_t osrs_h;
uint8_t filter; uint8_t filter;
uint8_t setpoint;
uint8_t idac_heat[10]; uint8_t idac_heat[10];
uint8_t res_heat[10]; uint8_t res_heat[10];
uint8_t gas_wait[10]; uint8_t gas_wait[10];
@ -134,6 +133,7 @@ struct bme680 {
struct bme680_config cfg; struct bme680_config cfg;
struct bme680_adc adc; struct bme680_adc adc;
uint8_t mode; uint8_t mode;
uint8_t setpoint;
uint8_t spi_page; uint8_t spi_page;
uint8_t gas_valid; uint8_t gas_valid;
uint8_t heat_stab; uint8_t heat_stab;
@ -150,6 +150,8 @@ int bme680_configure(bme680_t *bme680);
int bme680_start(bme680_t *bme680); int bme680_start(bme680_t *bme680);
int bme680_poll(bme680_t *bme680); int bme680_poll(bme680_t *bme680);
int bme680_read(bme680_t *bme680); int bme680_read(bme680_t *bme680);
int bme680_write_setpoint_index(bme680_t *bme680);
int bme680_read_setpoint_index(bme680_t *bme680, uint8_t *index);
uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient); uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient);

124
example/README.md Normal file
View File

@ -0,0 +1,124 @@
# bme680/example
iterate\_setpoint.c
```
heater_target=300.0, ambient_temp=19.0
first few setpoints have heater_target=380
[Setpoint 0] temp=18.37°C, press=1005.54 mbar, hum=67.03 %RH, gas_res=10749063.67 gv=1 hs=0
[Setpoint 1] temp=18.37°C, press=1005.54 mbar, hum=67.06 %RH, gas_res=7906336.09 gv=1 hs=0
[Setpoint 2] temp=18.38°C, press=1005.54 mbar, hum=67.07 %RH, gas_res=6449438.20 gv=1 hs=0
[Setpoint 3] temp=18.38°C, press=1005.54 mbar, hum=67.06 %RH, gas_res=5329619.31 gv=1 hs=0
[Setpoint 4] temp=18.39°C, press=1005.54 mbar, hum=67.03 %RH, gas_res=4701064.70 gv=1 hs=0
[Setpoint 5] temp=18.40°C, press=1005.54 mbar, hum=66.99 %RH, gas_res=4242424.24 gv=1 hs=0
[Setpoint 6] temp=18.41°C, press=1005.54 mbar, hum=66.93 %RH, gas_res=7667.94 gv=1 hs=1
[Setpoint 7] temp=18.43°C, press=1005.54 mbar, hum=66.92 %RH, gas_res=8942.73 gv=1 hs=1
[Setpoint 8] temp=18.45°C, press=1005.54 mbar, hum=66.89 %RH, gas_res=9496.84 gv=1 hs=1
[Setpoint 9] temp=18.47°C, press=1005.54 mbar, hum=66.79 %RH, gas_res=9804.77 gv=1 hs=1
```
continuous.c
```
heater_target=300.0, ambient_temp=19.0
temp=20.73°C, press=1005.41 mbar, hum=54.19 %RH, gas_res=9537.32
temp=20.74°C, press=1005.41 mbar, hum=54.42 %RH, gas_res=9813.37
temp=20.75°C, press=1005.41 mbar, hum=54.61 %RH, gas_res=9813.37
temp=20.78°C, press=1005.41 mbar, hum=54.76 %RH, gas_res=9804.77
temp=20.80°C, press=1005.41 mbar, hum=54.87 %RH, gas_res=9813.37
temp=20.83°C, press=1005.41 mbar, hum=54.95 %RH, gas_res=9787.61
temp=20.85°C, press=1005.41 mbar, hum=54.99 %RH, gas_res=9770.52
temp=20.88°C, press=1005.42 mbar, hum=55.01 %RH, gas_res=9770.52
temp=20.91°C, press=1005.42 mbar, hum=55.00 %RH, gas_res=9744.99
temp=20.94°C, press=1005.42 mbar, hum=54.97 %RH, gas_res=9711.16
temp=20.98°C, press=1005.42 mbar, hum=54.91 %RH, gas_res=9711.16
temp=21.01°C, press=1005.42 mbar, hum=54.84 %RH, gas_res=9694.33
temp=21.04°C, press=1005.42 mbar, hum=54.76 %RH, gas_res=9685.94
temp=21.07°C, press=1005.42 mbar, hum=54.67 %RH, gas_res=9677.56
temp=21.11°C, press=1005.42 mbar, hum=54.56 %RH, gas_res=9669.20
temp=21.14°C, press=1005.42 mbar, hum=54.45 %RH, gas_res=9669.20
temp=21.18°C, press=1005.42 mbar, hum=54.34 %RH, gas_res=9660.85
temp=21.21°C, press=1005.42 mbar, hum=54.22 %RH, gas_res=9644.19
temp=21.24°C, press=1005.43 mbar, hum=54.09 %RH, gas_res=9652.51
temp=21.28°C, press=1005.43 mbar, hum=53.96 %RH, gas_res=9644.19
temp=21.31°C, press=1005.43 mbar, hum=53.83 %RH, gas_res=9627.59
temp=21.35°C, press=1005.43 mbar, hum=53.70 %RH, gas_res=9611.05
temp=21.38°C, press=1005.43 mbar, hum=53.55 %RH, gas_res=9619.32
temp=21.42°C, press=1005.43 mbar, hum=53.42 %RH, gas_res=9619.32
temp=21.45°C, press=1005.43 mbar, hum=53.30 %RH, gas_res=9611.05
temp=21.49°C, press=1005.43 mbar, hum=53.16 %RH, gas_res=9602.80
temp=21.52°C, press=1005.44 mbar, hum=53.02 %RH, gas_res=9586.35
temp=21.56°C, press=1005.44 mbar, hum=52.90 %RH, gas_res=9602.80
temp=21.59°C, press=1005.44 mbar, hum=52.76 %RH, gas_res=9569.95
temp=21.63°C, press=1005.44 mbar, hum=52.62 %RH, gas_res=9586.35
temp=21.66°C, press=1005.44 mbar, hum=52.51 %RH, gas_res=9569.95
temp=21.70°C, press=1005.44 mbar, hum=52.38 %RH, gas_res=9569.95
temp=21.73°C, press=1005.44 mbar, hum=52.26 %RH, gas_res=9561.77
temp=21.77°C, press=1005.44 mbar, hum=52.13 %RH, gas_res=9553.61
temp=21.80°C, press=1005.45 mbar, hum=52.00 %RH, gas_res=9553.61
temp=21.84°C, press=1005.45 mbar, hum=51.89 %RH, gas_res=9553.61
temp=21.87°C, press=1005.45 mbar, hum=51.77 %RH, gas_res=9553.61
temp=21.91°C, press=1005.45 mbar, hum=51.65 %RH, gas_res=9553.61
temp=21.94°C, press=1005.45 mbar, hum=51.55 %RH, gas_res=9537.32
temp=21.98°C, press=1005.45 mbar, hum=51.41 %RH, gas_res=9521.09
temp=22.01°C, press=1005.45 mbar, hum=51.31 %RH, gas_res=9529.20
temp=22.04°C, press=1005.45 mbar, hum=51.19 %RH, gas_res=9529.20
temp=22.08°C, press=1005.45 mbar, hum=51.08 %RH, gas_res=9529.20
temp=22.11°C, press=1005.45 mbar, hum=50.97 %RH, gas_res=9512.99
temp=22.15°C, press=1005.46 mbar, hum=50.86 %RH, gas_res=9504.91
temp=22.18°C, press=1005.46 mbar, hum=50.76 %RH, gas_res=9504.91
temp=22.22°C, press=1005.46 mbar, hum=50.64 %RH, gas_res=9512.99
temp=22.25°C, press=1005.46 mbar, hum=50.54 %RH, gas_res=9504.91
temp=22.28°C, press=1005.46 mbar, hum=50.44 %RH, gas_res=9488.79
temp=22.32°C, press=1005.46 mbar, hum=50.34 %RH, gas_res=9488.79
temp=22.35°C, press=1005.46 mbar, hum=50.24 %RH, gas_res=9480.75
temp=22.39°C, press=1005.46 mbar, hum=50.15 %RH, gas_res=9480.75
temp=22.42°C, press=1005.46 mbar, hum=50.05 %RH, gas_res=9472.72
temp=22.45°C, press=1005.47 mbar, hum=49.94 %RH, gas_res=9464.71
temp=22.49°C, press=1005.47 mbar, hum=49.86 %RH, gas_res=9472.72
temp=22.52°C, press=1005.47 mbar, hum=49.76 %RH, gas_res=9464.71
temp=22.55°C, press=1005.47 mbar, hum=49.67 %RH, gas_res=9480.75
temp=22.59°C, press=1005.47 mbar, hum=49.58 %RH, gas_res=9456.71
temp=22.62°C, press=1005.47 mbar, hum=49.49 %RH, gas_res=9472.72
temp=22.65°C, press=1005.47 mbar, hum=49.41 %RH, gas_res=9456.71
temp=22.68°C, press=1005.47 mbar, hum=49.33 %RH, gas_res=9456.71
temp=22.72°C, press=1005.47 mbar, hum=49.24 %RH, gas_res=9432.79
temp=22.75°C, press=1005.47 mbar, hum=49.15 %RH, gas_res=9432.79
temp=22.78°C, press=1005.47 mbar, hum=49.08 %RH, gas_res=9440.75
temp=22.81°C, press=1005.47 mbar, hum=49.00 %RH, gas_res=9440.75
temp=22.85°C, press=1005.48 mbar, hum=48.92 %RH, gas_res=9432.79
temp=22.88°C, press=1005.48 mbar, hum=48.84 %RH, gas_res=9432.79
temp=22.91°C, press=1005.48 mbar, hum=48.77 %RH, gas_res=9416.91
temp=22.94°C, press=1005.48 mbar, hum=48.71 %RH, gas_res=9440.75
temp=22.97°C, press=1005.48 mbar, hum=48.63 %RH, gas_res=9440.75
temp=23.00°C, press=1005.48 mbar, hum=48.56 %RH, gas_res=9432.79
temp=23.04°C, press=1005.48 mbar, hum=48.50 %RH, gas_res=9408.99
temp=23.07°C, press=1005.48 mbar, hum=48.42 %RH, gas_res=9424.84
temp=23.10°C, press=1005.48 mbar, hum=48.36 %RH, gas_res=9416.91
temp=23.13°C, press=1005.48 mbar, hum=48.29 %RH, gas_res=9408.99
temp=23.16°C, press=1005.48 mbar, hum=48.24 %RH, gas_res=9408.99
temp=23.19°C, press=1005.48 mbar, hum=48.17 %RH, gas_res=9408.99
temp=23.22°C, press=1005.48 mbar, hum=48.12 %RH, gas_res=9416.91
temp=23.25°C, press=1005.48 mbar, hum=48.05 %RH, gas_res=9416.91
temp=23.28°C, press=1005.49 mbar, hum=48.00 %RH, gas_res=9416.91
temp=23.31°C, press=1005.49 mbar, hum=47.94 %RH, gas_res=9401.09
temp=23.34°C, press=1005.49 mbar, hum=47.89 %RH, gas_res=9385.32
temp=23.37°C, press=1005.49 mbar, hum=47.84 %RH, gas_res=9385.32
temp=23.40°C, press=1005.49 mbar, hum=47.78 %RH, gas_res=9401.09
temp=23.43°C, press=1005.49 mbar, hum=47.74 %RH, gas_res=9393.19
temp=23.46°C, press=1005.49 mbar, hum=47.68 %RH, gas_res=9385.32
temp=23.49°C, press=1005.49 mbar, hum=47.64 %RH, gas_res=9377.45
temp=23.52°C, press=1005.49 mbar, hum=47.58 %RH, gas_res=9385.32
temp=23.54°C, press=1005.49 mbar, hum=47.54 %RH, gas_res=9377.45
temp=23.57°C, press=1005.49 mbar, hum=47.49 %RH, gas_res=9385.32
temp=23.60°C, press=1005.49 mbar, hum=47.45 %RH, gas_res=9385.32
temp=23.63°C, press=1005.49 mbar, hum=47.40 %RH, gas_res=9377.45
temp=23.66°C, press=1005.49 mbar, hum=47.36 %RH, gas_res=9369.60
temp=23.69°C, press=1005.49 mbar, hum=47.32 %RH, gas_res=9361.76
temp=23.71°C, press=1005.49 mbar, hum=47.28 %RH, gas_res=9377.45
temp=23.74°C, press=1005.49 mbar, hum=47.24 %RH, gas_res=9369.60
temp=23.77°C, press=1005.49 mbar, hum=47.20 %RH, gas_res=9377.45
temp=23.80°C, press=1005.50 mbar, hum=47.16 %RH, gas_res=9385.32
temp=23.82°C, press=1005.50 mbar, hum=47.13 %RH, gas_res=9377.45
temp=23.85°C, press=1005.50 mbar, hum=47.08 %RH, gas_res=9353.93
temp=23.88°C, press=1005.50 mbar, hum=47.04 %RH, gas_res=9353.93
```

99
example/continuous.c Normal file
View File

@ -0,0 +1,99 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "bme680.h"
#include "i2c.h"
#include "spi.h"
#define AMBIENT_TEMP_GUESS 19.0
#define HEATER_TARGET 300.0
void pretty_print(bme680_t *bme680);
int main(void) {
bme680_t bme680;
uint8_t mode;
int counter;
bme680.dev.init = spi_init;
bme680.dev.read = spi_read;
bme680.dev.write = spi_write;
bme680.dev.deinit = spi_deinit;
mode = BME680_MODE_FLOAT | BME680_SPI | BME680_ENABLE_GAS;
if (bme680_init(&bme680, mode) != 0) {
fprintf(stderr, "bme680_init()\n");
exit(EXIT_FAILURE);
}
bme680_reset(&bme680);
if (bme680_calibrate(&bme680) != 0) {
fprintf(stderr, "bme680_calibrate()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
bme680.cfg.osrs_t = BME680_OVERSAMPLE_X16;
bme680.cfg.osrs_p = BME680_OVERSAMPLE_X16;
bme680.cfg.osrs_h = BME680_OVERSAMPLE_X8;
bme680.cfg.filter = BME680_IIR_COEFF_127;
/* only 1 setpoint */
bme680.cfg.res_heat[0] = bme680_calc_target(&bme680, HEATER_TARGET, AMBIENT_TEMP_GUESS);
bme680.cfg.idac_heat[0] = BME680_IDAC(100);
bme680.cfg.gas_wait[0] = BME680_GAS_WAIT(50, BME680_GAS_WAIT_X4);
bme680.setpoint = 0;
if (bme680_configure(&bme680) != 0) {
fprintf(stderr, "bme680_configure()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
counter = 0;
printf("heater_target=%.1f, ambient_temp=%.1f\n", HEATER_TARGET, AMBIENT_TEMP_GUESS);
do {
if (bme680_start(&bme680) != 0) {
fprintf(stderr, "bme680_start()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
if (bme680_poll(&bme680) != 0) {
fprintf(stderr, "bme680_poll()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
if (bme680_read(&bme680) != 0) {
fprintf(stderr, "bme680_read()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
pretty_print(&bme680);
} while(counter++ < 100);
bme680_deinit(&bme680);
return 0;
}
void pretty_print(bme680_t *bme680) {
double t = bme680->fcomp.temp;
double p = bme680->fcomp.press / 100.0;
double h = bme680->fcomp.hum;
double gr = bme680->fcomp.gas_res;
printf("temp=%.2f°C, press=%.2f mbar, hum=%.2f %%RH, gas_res=%.2f\n", t, p, h, gr);
}

127
example/iterate_setpoint.c Normal file
View File

@ -0,0 +1,127 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "bme680.h"
#include "i2c.h"
#include "spi.h"
#define AMBIENT_TEMP_GUESS 19.0
/* heater prob won't settle */
#define HEATER_TARGET_CLEAN_SENSOR 380.0
/* for the "real" measurement */
#define HEATER_TARGET 300.0
void pretty_print(bme680_t *bme680);
int main(void) {
bme680_t bme680;
uint8_t mode;
int i;
bme680.dev.init = spi_init;
bme680.dev.read = spi_read;
bme680.dev.write = spi_write;
bme680.dev.deinit = spi_deinit;
mode = BME680_MODE_FLOAT | BME680_SPI | BME680_ENABLE_GAS;
if (bme680_init(&bme680, mode) != 0) {
fprintf(stderr, "bme680_init()\n");
exit(EXIT_FAILURE);
}
bme680_reset(&bme680);
if (bme680_calibrate(&bme680) != 0) {
fprintf(stderr, "bme680_calibrate()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
bme680.cfg.osrs_t = BME680_OVERSAMPLE_X16;
bme680.cfg.osrs_p = BME680_OVERSAMPLE_X16;
bme680.cfg.osrs_h = BME680_OVERSAMPLE_X8;
bme680.cfg.filter = BME680_IIR_COEFF_127;
for(i=0; i<10; i++) {
/* extra heat to clean the sensor surface. might work ! */
if (i < 6) {
bme680.cfg.res_heat[i] = bme680_calc_target(&bme680, HEATER_TARGET_CLEAN_SENSOR, AMBIENT_TEMP_GUESS);
bme680.cfg.idac_heat[i] = BME680_IDAC(100); // 12.5 mA
bme680.cfg.gas_wait[i] = BME680_GAS_WAIT(50, BME680_GAS_WAIT_X4);
} else {
bme680.cfg.res_heat[i] = bme680_calc_target(&bme680, HEATER_TARGET, AMBIENT_TEMP_GUESS);
bme680.cfg.idac_heat[i] = BME680_IDAC(50);
bme680.cfg.gas_wait[i] = BME680_GAS_WAIT(50, BME680_GAS_WAIT_X4);
}
}
bme680.setpoint = 0;
if (bme680_configure(&bme680) != 0) {
fprintf(stderr, "bme680_configure()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
printf("heater_target=%.1f, ambient_temp=%.1f\n", HEATER_TARGET, AMBIENT_TEMP_GUESS);
printf("first few setpoints have heater_target=%1.f\n", HEATER_TARGET_CLEAN_SENSOR);
for(i=0; i<10; i++) {
bme680.setpoint = i;
if (bme680_write_setpoint_index(&bme680) != 0) {
fprintf(stderr, "bme680_write_setpoint()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
if (bme680_start(&bme680) != 0) {
fprintf(stderr, "bme680_start()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
if (bme680_poll(&bme680) != 0) {
fprintf(stderr, "bme680_poll()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
if (bme680_read(&bme680) != 0) {
fprintf(stderr, "bme680_read()\n");
bme680_deinit(&bme680);
exit(EXIT_FAILURE);
}
pretty_print(&bme680);
}
bme680_deinit(&bme680);
return 0;
}
void pretty_print(bme680_t *bme680) {
uint8_t dev_sp;
bme680_read_setpoint_index(bme680, &dev_sp);
double t = bme680->fcomp.temp;
double p = bme680->fcomp.press / 100.0;
double h = bme680->fcomp.hum;
double gr = bme680->fcomp.gas_res;
int gv = bme680->gas_valid;
int hs = bme680->heat_stab;
printf("[Setpoint %d] temp=%.2f°C, press=%.2f mbar, hum=%.2f %%RH, gas_res=%.2f gv=%d hs=%d\n",
dev_sp, t, p, h, gr, gv, hs);
}

5
i2c.c
View File

@ -15,7 +15,6 @@
static int fd; static int fd;
int i2c_init(void) { int i2c_init(void) {
fd = open(I2C_DEVICE, O_RDWR); fd = open(I2C_DEVICE, O_RDWR);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "could not open device: %s\n", I2C_DEVICE); fprintf(stderr, "could not open device: %s\n", I2C_DEVICE);
@ -33,7 +32,6 @@ int i2c_init(void) {
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) { int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
uint8_t cmd[2] = {reg, 0x00}; uint8_t cmd[2] = {reg, 0x00};
write(fd, cmd, 2); write(fd, cmd, 2);
@ -42,12 +40,12 @@ int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
return I2C_ERR; return I2C_ERR;
} }
return I2C_OK; return I2C_OK;
} }
int i2c_write(uint8_t reg, uint8_t value) { int i2c_write(uint8_t reg, uint8_t value) {
uint8_t cmd[2] = {reg, value}; uint8_t cmd[2] = {reg, value};
if (write(fd, cmd, 2) != 2) { if (write(fd, cmd, 2) != 2) {
@ -65,3 +63,4 @@ int i2c_deinit(void) {
return I2C_OK; return I2C_OK;
} }

24
main.c
View File

@ -33,13 +33,13 @@ int main(void) {
/* BME680_MODE_INT | BME680_I2C; */ /* BME680_MODE_INT | BME680_I2C; */
/* 3. initialise device, and check its id */ /* 3. initialise dev func's, and check device id */
if (bme680_init(&bme680, mode) != 0) { if (bme680_init(&bme680, mode) != 0) {
fprintf(stderr, "bme680_init()\n"); fprintf(stderr, "bme680_init()\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* 4. reset */ /* 4. reset device */
bme680_reset(&bme680); bme680_reset(&bme680);
/* 5. read calibration parameters from the device and store in memory */ /* 5. read calibration parameters from the device and store in memory */
@ -61,14 +61,14 @@ int main(void) {
/* configuring gas sensor. */ /* configuring gas sensor. */
/* NB: mode |= BME680_ENABLE_GAS; */ /* NB: mode |= BME680_ENABLE_GAS; */
/* there are 10 possible heater setpoints */ /* there are 10 possible heater setpoints */
/* they can be though of as frames that define one single gas-resistance measurement */ /* they can be thought of as frames that define one single gas-resistance measurement */
/* they do not carry over or affect eachother in any way. */ /* they do not carry over or affect each other in any way. */
for(i=0; i<10; i++) { for(i=0; i<10; i++) {
/* calculate a resistance target, based on desired temp, and ambient temp */ /* calculate a resistance target, based on desired temp, and ambient temp */
bme680.cfg.res_heat[i] = bme680_calc_target(&bme680, HEATER_TARGET, AMBIENT_TEMP_GUESS); bme680.cfg.res_heat[i] = bme680_calc_target(&bme680, HEATER_TARGET, AMBIENT_TEMP_GUESS);
/* initial heating current for the setpoint. Could be useful in cold places.. */ /* initial heating current for the setpoint. Could be useful in cold places or short gas_wait durations */
/* 7-bit word. Each step/lsb is equiv. to 1/8 mA; so max 16 mA */ /* 7-bit word. Each step/lsb is equiv. to 1/8 mA; so max 16 mA */
/* a value of 20 would be equal to 2.5 mA */ /* a value of 20 would be equal to 2.5 mA */
/* this s.p. field is allowed to be left as 0 if no preload is required. */ /* this s.p. field is allowed to be left as 0 if no preload is required. */
@ -76,14 +76,16 @@ int main(void) {
/* define the time between the start of heating and start of resistance sensing in this s.p.*/ /* define the time between the start of heating and start of resistance sensing in this s.p.*/
/* Bosch datasheet suggests ~30 - 40ms is usually all that is required to get up to temp. */ /* Bosch datasheet suggests ~30 - 40ms is usually all that is required to get up to temp. */
/* ^ probably with a good idac_heat current but doesn't mention it. */
/* 25 * X4 = 100 ms wait before sampling resistance starts. */ /* 25 * X4 = 100 ms wait before sampling resistance starts. */
/* the first value is 6-bit (0...64) with 1 ms step size. */ /* the first value is 6-bit (0...63) with 1 ms step size. */
bme680.cfg.gas_wait[i] = BME680_GAS_WAIT(25, BME680_GAS_WAIT_X4); bme680.cfg.gas_wait[i] = BME680_GAS_WAIT(25, BME680_GAS_WAIT_X4);
} }
/* The BME680 does not cycle between setpoints. They have to be manually set. */ /* The BME680 does not cycle between setpoints. They have to be manually set. */
/* After each "run", the setpoint has to be changed. */ /* After each "run", the setpoint has to be changed. */
bme680.cfg.setpoint = 0; /* 0 thru 9 */ /* the func bme680_write_setpoint_index() will write this field to the dev, without having to reconfigure */
bme680.setpoint = 0; /* 0 thru 9 */
/* 7. write config to device */ /* 7. write config to device */
if (bme680_configure(&bme680) != 0) { if (bme680_configure(&bme680) != 0) {
@ -92,23 +94,22 @@ int main(void) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* 8. Start forced measurement*. After it finishes, it should remember the previous config. */
/* 8. Start forced measurement. After it finishes, it should remember the previous config. */ /* * = bosch speak for one single T, P, H, GasRes measuring cycle. */
if (bme680_start(&bme680) != 0) { if (bme680_start(&bme680) != 0) {
fprintf(stderr, "bme680_start()\n"); fprintf(stderr, "bme680_start()\n");
bme680_deinit(&bme680); bme680_deinit(&bme680);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* 9. poll the meas_status register until all scheduled conversions are done */ /* 9. poll the meas_status register until all scheduled conversions are done */
/* this step can be skipped with SPI interrupt (3 wire SPI only. See 5.3.1.1 in datasheet; pg 29) */
if (bme680_poll(&bme680) != 0) { if (bme680_poll(&bme680) != 0) {
fprintf(stderr, "bme680_poll()\n"); fprintf(stderr, "bme680_poll()\n");
bme680_deinit(&bme680); bme680_deinit(&bme680);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* 10. read the ADC's and perform a conversion */ /* 10. read the ADC's and perform a conversion */
if (bme680_read(&bme680) != 0) { if (bme680_read(&bme680) != 0) {
fprintf(stderr, "bme680_read()\n"); fprintf(stderr, "bme680_read()\n");
@ -116,7 +117,6 @@ int main(void) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
/* 11. use data ! */ /* 11. use data ! */
if (BME680_IS_FLOAT(bme680.mode)) { if (BME680_IS_FLOAT(bme680.mode)) {
puts("float mode"); puts("float mode");

View File

@ -63,7 +63,7 @@
#define REG_PRESS_LSB 0x20 #define REG_PRESS_LSB 0x20
#define REG_PRESS_MSB 0x1F #define REG_PRESS_MSB 0x1F
#define REG_EAS_STATUS 0x1D #define REG_MEAS_STATUS 0x1D