diff --git a/bme680.c b/bme680.c index 0b2bc80..6d845d4 100644 --- a/bme680.c +++ b/bme680.c @@ -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) { - if (BME680_IS_SPI(bme680->mode)) { check_spi_page(bme680, reg); 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) { - if (BME680_IS_SPI(bme680->mode)) { check_spi_page(bme680, reg); 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) { - uint8_t id_reg; /* 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; int i; @@ -82,12 +98,12 @@ int bme680_init(bme680_t *bme680, uint8_t mode) { bme680->spi_page = 0; bme680->gas_valid = 0; bme680->heat_stab = 0; + bme680->setpoint = 0; if (bme680->dev.init() != 0) { return 1; } - if (read_id(bme680, &id) != 0) { return 1; } @@ -139,7 +155,6 @@ int bme680_reset(bme680_t *bme680) { /********************************************************************/ /* configure device */ int bme680_configure(bme680_t *bme680) { - uint8_t meas, hum, filter, ctrl_gas1, ctrl_gas0, err; int i; 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]); } - 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 */ 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 */ int bme680_start(bme680_t *bme680) { - int err = 0; uint8_t meas; meas = bme680->cfg.meas | 1; @@ -192,11 +206,8 @@ int bme680_start(bme680_t *bme680) { } /********************************************************************/ -/* blocks until the device all scheduled conversions are done. - * don't call out of order. - */ +/* blocks until all scheduled conversions on the device are done. */ int bme680_poll(bme680_t *bme680) { - uint8_t meas_status = 0; uint8_t gas_measuring = 0; uint8_t any_measuring = 0; @@ -205,7 +216,7 @@ int bme680_poll(bme680_t *bme680) { do { 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; any_measuring = (meas_status >> 5) & 1; @@ -217,7 +228,6 @@ int bme680_poll(bme680_t *bme680) { /********************************************************************/ /* assume start'd and poll'd */ int bme680_read(bme680_t *bme680) { - /* begin by reading ADCs */ uint8_t buffer[3] = {0, 0 ,0}; int err = 0; @@ -231,7 +241,6 @@ int bme680_read(bme680_t *bme680) { err |= read_dev(bme680, 0x25, buffer, 2); bme680->adc.hum = (buffer[0] << 8) | buffer[1]; - /* adc readings are only 20-bit when the IIR filter is enabled. * otherwise, it depends on the oversample settings. * 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) { - double var1, var2, temp_comp; 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) { - int32_t var1, var2, var3, temp_comp; 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) { - double var1, var2, var3, press_comp; 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 ) { - int32_t var1, var2, var3, press_comp; 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) { - double var1, var2, var3, var4, hum_comp, temp_comp; 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) { - int32_t var1, var2, var3, var4, var5, var6, temp_scaled, hum_comp; 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 int bme680_calibrate(bme680_t *bme680) { - uint8_t buffer[3] = {0, 0 ,0}; int err = 0; @@ -540,7 +540,6 @@ int bme680_calibrate(bme680_t *bme680) { return err; } -/********************************************************************/ /********************************************************************/ static void calc_gas_res_1(bme680_t *bme680) { double var1, gas_res; @@ -571,7 +570,6 @@ static void calc_gas_res(bme680_t *bme680) { } } -/********************************************************************/ /********************************************************************/ void bme680_print_calibration (bme680_t *bme680) { 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); } +/********************************************************************/ static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) { double var1, var2, var3, var4, var5; uint8_t res_heat; @@ -616,6 +615,7 @@ static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) { return res_heat; } +/********************************************************************/ static uint8_t calc_target_2(bme680_t *bme680, double target, double ambient) { int32_t var1, var2, var3, var4, var5, res_heat_x100; uint8_t res_heat; @@ -631,6 +631,7 @@ static uint8_t calc_target_2(bme680_t *bme680, double target, double ambient) { return res_heat; } +/********************************************************************/ uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient) { if (BME680_IS_FLOAT(bme680->mode)) { return calc_target_1(bme680, target, ambient); diff --git a/bme680.h b/bme680.h index 9fb5389..87b1865 100644 --- a/bme680.h +++ b/bme680.h @@ -94,7 +94,6 @@ struct bme680_config { uint8_t osrs_p; uint8_t osrs_h; uint8_t filter; - uint8_t setpoint; uint8_t idac_heat[10]; uint8_t res_heat[10]; uint8_t gas_wait[10]; @@ -134,6 +133,7 @@ struct bme680 { struct bme680_config cfg; struct bme680_adc adc; uint8_t mode; + uint8_t setpoint; uint8_t spi_page; uint8_t gas_valid; uint8_t heat_stab; @@ -150,6 +150,8 @@ int bme680_configure(bme680_t *bme680); int bme680_start(bme680_t *bme680); int bme680_poll(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); diff --git a/bst-bme680-ds001.pdf b/datasheet.pdf similarity index 100% rename from bst-bme680-ds001.pdf rename to datasheet.pdf diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..ead86ba --- /dev/null +++ b/example/README.md @@ -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 +``` diff --git a/example/continuous.c b/example/continuous.c new file mode 100644 index 0000000..5919d2a --- /dev/null +++ b/example/continuous.c @@ -0,0 +1,99 @@ + +#include +#include +#include + +#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); +} diff --git a/example/iterate_setpoint.c b/example/iterate_setpoint.c new file mode 100644 index 0000000..705b46b --- /dev/null +++ b/example/iterate_setpoint.c @@ -0,0 +1,127 @@ + +#include +#include +#include + +#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); +} diff --git a/i2c.c b/i2c.c index de21faa..57f65d6 100644 --- a/i2c.c +++ b/i2c.c @@ -15,7 +15,6 @@ static int fd; int i2c_init(void) { - fd = open(I2C_DEVICE, O_RDWR); if (fd < 0) { 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) { - uint8_t cmd[2] = {reg, 0x00}; 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_OK; } int i2c_write(uint8_t reg, uint8_t value) { - uint8_t cmd[2] = {reg, value}; if (write(fd, cmd, 2) != 2) { @@ -65,3 +63,4 @@ int i2c_deinit(void) { return I2C_OK; } + diff --git a/main.c b/main.c index 21bd8c0..28b1dea 100644 --- a/main.c +++ b/main.c @@ -33,13 +33,13 @@ int main(void) { /* 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) { fprintf(stderr, "bme680_init()\n"); exit(EXIT_FAILURE); } - /* 4. reset */ + /* 4. reset device */ bme680_reset(&bme680); /* 5. read calibration parameters from the device and store in memory */ @@ -61,14 +61,14 @@ int main(void) { /* configuring gas sensor. */ /* NB: mode |= BME680_ENABLE_GAS; */ /* there are 10 possible heater setpoints */ - /* they can be though of as frames that define one single gas-resistance measurement */ - /* they do not carry over or affect eachother in any way. */ + /* they can be thought of as frames that define one single gas-resistance measurement */ + /* they do not carry over or affect each other in any way. */ for(i=0; i<10; i++) { /* 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); - /* 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 */ /* 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. */ @@ -76,14 +76,16 @@ int main(void) { /* 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. */ + /* ^ probably with a good idac_heat current but doesn't mention it. */ /* 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); } /* The BME680 does not cycle between setpoints. They have to be manually set. */ /* 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 */ if (bme680_configure(&bme680) != 0) { @@ -92,23 +94,22 @@ int main(void) { 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) { fprintf(stderr, "bme680_start()\n"); bme680_deinit(&bme680); exit(EXIT_FAILURE); } - /* 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) { fprintf(stderr, "bme680_poll()\n"); bme680_deinit(&bme680); exit(EXIT_FAILURE); } - /* 10. read the ADC's and perform a conversion */ if (bme680_read(&bme680) != 0) { fprintf(stderr, "bme680_read()\n"); @@ -116,7 +117,6 @@ int main(void) { exit(EXIT_FAILURE); } - /* 11. use data ! */ if (BME680_IS_FLOAT(bme680.mode)) { puts("float mode"); diff --git a/registers.h b/registers.h index ccaeed0..f1546c1 100644 --- a/registers.h +++ b/registers.h @@ -63,7 +63,7 @@ #define REG_PRESS_LSB 0x20 #define REG_PRESS_MSB 0x1F -#define REG_EAS_STATUS 0x1D +#define REG_MEAS_STATUS 0x1D