Low power gas, pressure, temperature and humidity sensor
Dependents: MERGE Sensor_iAQ_sgp30_bme_si7051 POCBreath_V2_smd_commercial
Revision 3:8aefe9304f85, committed 2018-07-23
- Comitter:
- mcm
- Date:
- Mon Jul 23 11:41:39 2018 +0000
- Parent:
- 2:090496028eb9
- Commit message:
- An example that shows how to use this driver was added into the header file.
Changed in this revision
BME680.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 090496028eb9 -r 8aefe9304f85 BME680.h --- a/BME680.h Mon Jul 23 11:34:10 2018 +0000 +++ b/BME680.h Mon Jul 23 11:41:39 2018 +0000 @@ -75,7 +75,298 @@ /** Example: @code -[TODO] +#include "mbed.h" +#include "BME680.h" + +BME680 myBME680 ( I2C_SDA, I2C_SCL, 400000 ); +Serial pc ( USBTX, USBRX ); + +DigitalOut myled ( LED1 ); +Ticker newReading; + +uint32_t myState = 0; + + +//@brief FUNCTION PROTOTYPES +void changeDATA ( void ); +void user_delay_ms ( uint32_t period ); +int8_t user_i2c_read ( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ); +int8_t user_i2c_write ( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ); + + +//@brief FUNCTION FOR APPLICATION MAIN ENTRY. +int main() +{ + pc.baud ( 115200 ); + + myled = 1; + wait(3); + myled = 0; + + + struct bme680_dev gas_sensor; + + gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY; + gas_sensor.intf = BME680_I2C_INTF; + gas_sensor.read = user_i2c_read; + gas_sensor.write = user_i2c_write; + gas_sensor.delay_ms = user_delay_ms; + // amb_temp can be set to 25 prior to configuring the gas sensor + // or by performing a few temperature readings without operating the gas sensor. + gas_sensor.amb_temp = 25; + + + int8_t rslt = BME680_OK; + rslt = myBME680.bme680_init ( &gas_sensor ); + + + uint8_t set_required_settings; + + // Set the temperature, pressure and humidity settings + gas_sensor.tph_sett.os_hum = BME680_OS_2X; + gas_sensor.tph_sett.os_pres = BME680_OS_4X; + gas_sensor.tph_sett.os_temp = BME680_OS_8X; + gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3; + + // Set the remaining gas sensor settings and link the heating profile + gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; + // Create a ramp heat waveform in 3 steps + gas_sensor.gas_sett.heatr_temp = 320; // degree Celsius + gas_sensor.gas_sett.heatr_dur = 150; // milliseconds + + // Select the power mode + // Must be set before writing the sensor configuration + gas_sensor.power_mode = BME680_FORCED_MODE; + + // Set the required sensor settings needed + set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL; + + // Set the desired sensor configuration + rslt = myBME680.bme680_set_sensor_settings ( set_required_settings, &gas_sensor ); + + // Set the power mode + rslt = myBME680.bme680_set_sensor_mode ( &gas_sensor ); + + + // Get the total measurement duration so as to sleep or wait till the measurement is complete + uint16_t meas_period; + myBME680.bme680_get_profile_dur ( &meas_period, &gas_sensor ); + + struct bme680_field_data data; + + + newReading.attach( &changeDATA, 1 ); // the address of the function to be attached ( changeDATA ) and the interval ( 1s ) + + // Let the callbacks take care of everything + while(1) { + sleep(); + + myled = 1; + + if ( myState == 1 ) { + // Delay till the measurement is ready + user_delay_ms ( meas_period ); + + rslt = myBME680.bme680_get_sensor_data ( &data, &gas_sensor ); + + // Prepare the data to be sent through the UART. NOTE: sprintf does NOT allow float numbers, that is why we round the number and plot them as integer + // Avoid using measurements from an unstable heating setup + if ( data.status & BME680_GASM_VALID_MSK ) { + pc.printf( "T: %.2f degC, P: %.2f hPa, H %.2f %%rH, G: %d ohms\r\n", ( data.temperature/100.0f ), ( data.pressure / 100.0f ), ( data.humidity / 1000.0f ), data.gas_resistance ); + } else { + pc.printf( "T: %.2f degC, P: %.2f hPa, H %.2f %%rH\r\n", ( data.temperature/100.0f ), ( data.pressure / 100.0f ), ( data.humidity / 1000.0f ) ); + } + + + // Trigger the next measurement if you would like to read data out continuously + if ( gas_sensor.power_mode == BME680_FORCED_MODE ) { + rslt = myBME680.bme680_set_sensor_mode ( &gas_sensor ); + } + + myState = 0; // Reset the variable + } + + myled = 0; + } +} + + + + + // @brief changeDATA ( void ) + // + // @details It changes myState variable + // + // @param[in] N/A + // + // @param[out] N/A. + // + // + // @return N/A.. + // + // + // @author Manuel Caballero + // @date 21/July/2018 + // @version 21/July/2018 The ORIGIN + // @pre N/A + // @warning N/A. +void changeDATA ( void ) +{ + myState = 1; +} + + + + // @brief user_delay_ms ( uint32_t ) + // + // @details Return control or wait, for a period amount of milliseconds + // + // @param[in] period: Delay in milliseconds. + // + // @param[out] N/A. + // + // + // @return N/A.. + // + // + // @author Manuel Caballero + // @date 21/July/2018 + // @version 21/July/2018 The ORIGIN + // @pre This is a Bosh pointer function adapted to our system. + // @warning N/A. +void user_delay_ms ( uint32_t period ) +{ + // Return control or wait, + // for a period amount of milliseconds + + wait_ms ( period ); +} + + + + // @brief user_i2c_read ( uint8_t , uint8_t reg_addr, uint8_t *reg_data, uint16_t len ) + // + // @details It adapts I2C reading functionality. + // + // @param[in] dev_id: I2C address. + // @param[in] reg_addr: Register to be read. + // @param[in] len: How many bytes to read. + // + // @param[out] reg_data: Result. + // + // + // @return Status of user_i2c_read. + // + // + // @author Manuel Caballero + // @date 21/July/2018 + // @version 21/July/2018 The ORIGIN + // @pre This is a Bosh pointer function adapted to our system. + // @warning N/A. +int8_t user_i2c_read ( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ) +{ + int8_t rslt = 0; // Return 0 for Success, non-zero for failure + + // The parameter dev_id can be used as a variable to store the I2C address of the device + + + // Data on the bus should be like + // |------------+---------------------| + // | I2C action | Data | + // |------------+---------------------| + // | Start | - | + // | Write | (reg_addr) | + // | Stop | - | + // | Start | - | + // | Read | (reg_data[0]) | + // | Read | (....) | + // | Read | (reg_data[len - 1]) | + // | Stop | - | + // |------------+---------------------| + + // Read data + uint32_t aux = 0; + aux = myBME680._i2c.write ( dev_id, (char*)®_addr, 1, true ); + aux = myBME680._i2c.read ( dev_id, (char*)®_data[0], len ); + + + + if ( aux == 0 ) { + rslt = 0; + } else { + rslt = 0xFF; + } + + + return rslt; +} + + + + + // @brief user_i2c_write ( uint8_t , uint8_t reg_addr, uint8_t *reg_data, uint16_t len ) + // + // @details It adapts I2C writing functionality. + // + // @param[in] dev_id: I2C address. + // @param[in] reg_addr: Register to be read. + // @param[out] reg_data: Data to be written. + // @param[in] len: How many bytes to read. + // + // @param[out] N/A. + // + // + // @return Status of user_i2c_write. + // + // + // @author Manuel Caballero + // @date 21/July/2018 + // @version 21/July/2018 The ORIGIN + // @pre This is a Bosh pointer function adapted to our system. + // @warning N/A. +int8_t user_i2c_write ( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len ) +{ + int8_t rslt = 0; // Return 0 for Success, non-zero for failure + + // The parameter dev_id can be used as a variable to store the I2C address of the device + + + // Data on the bus should be like + // |------------+---------------------| + // | I2C action | Data | + // |------------+---------------------| + // | Start | - | + // | Write | (reg_addr) | + // | Write | (reg_data[0]) | + // | Write | (....) | + // | Write | (reg_data[len - 1]) | + // | Stop | - | + // |------------+---------------------| + + uint32_t aux = 0; + char cmd[16] = { 0 }; + uint32_t i = 0; + + // Prepare the data to be sent + cmd[0] = reg_addr; + for ( i = 1; i <= len; i++ ) { + cmd[i] = reg_data[i - 1]; + } + + // Write data + aux = myBME680._i2c.write ( dev_id, &cmd[0], len + 1, false ); + + + + if ( aux == 0 ) { + rslt = 0; + } else { + rslt = 0xFF; + } + + + return rslt; +} @endcode */ @@ -256,9 +547,9 @@ */ int8_t bme680_get_sensor_settings(uint16_t desired_settings, struct bme680_dev *dev); - - I2C _i2c; - + + I2C _i2c; + private: /*! * @brief This internal API is used to read the calibrated data from the sensor.