diff --git a/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.c b/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.c index f86cfdc..4868547 100644 --- a/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.c +++ b/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.c @@ -139,6 +139,52 @@ float BMP280_get_temperature(void) return T / 100; } +float BMP280_get_pressure(float * const temperature) +{ + int64_t var1, var2, p; + uint8_t data[3]; + + float temp = BMP280_get_temperature(); + if(temperature) *temperature = temp; + + if(!i2c_read(BMP280_I2C_ADDR, BMP280_PRESS_MSB, data, sizeof data)) return 0.0f; + + int32_t adc_P = data[0] << 16 | data[1] << 8 | data[2]; + + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)_calibration_data.dig_P6; + var2 = var2 + ((var1*(int64_t)_calibration_data.dig_P5)<<17); + var2 = var2 + (((int64_t)_calibration_data.dig_P4)<<35); + var1 = ((var1 * var1 * (int64_t)_calibration_data.dig_P3)>>8) + ((var1 * (int64_t)_calibration_data.dig_P2)<<12); + var1 = (((((int64_t)1)<<47)+var1))*((int64_t)_calibration_data.dig_P1)>>33; + + if (var1 == 0) + { + return 0.0f; // avoid exception caused by division by zero + } + + p = 1048576-adc_P; + p = (((p<<31)-var2)*3125)/var1; + var1 = (((int64_t)_calibration_data.dig_P9) * (p>>13) * (p>>13)) >> 25; + var2 = (((int64_t)_calibration_data.dig_P8) * p) >> 19; + p = ((p + var1 + var2) >> 8) + (((int64_t)_calibration_data.dig_P7)<<4); + + return (float)p/256; //to get rid of the Q24.8 format ! +} + +float BMP280_get_altitude(float pressureAtSeeLevel, float * const pressure, float * const temperature) +{ + if(pressureAtSeeLevel == 0) pressureAtSeeLevel = 1013.25; + + float press = BMP280_get_pressure(temperature); + + if(pressure) *pressure = press; + + press /= 100; + + return 44330 * (1.0 - pow(press / pressureAtSeeLevel, 0.1903)); +} + bool BMP280_software_reset(void) { return i2c_write_reg(BMP280_I2C_ADDR, BMP280_RESET, BMP280_RESET_CODE); diff --git a/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.h b/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.h index e08ba51..163fb1a 100644 --- a/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.h +++ b/src/W800 SDK v1.00.08/app/app_drivers/i2c/BMP280.h @@ -77,16 +77,70 @@ typedef enum BMP280_Standby_Duration BMP280_Standby_4000MS = 7, } BMP280_Standby_Duration_e; +/** + * @brief Initializes the BMP280 sensor. This must be called before any other API functions. + * Don't forget to initialize the I2C peripheral using the i2c_init function first ! + * + * @return true on success + * @return false on failure + */ bool BMP280_init(void); +/** + * @brief Configures the sensor by setting the sensor operating mode, temperature oversampling, pressure oversampling, the filter and the standby duration. + * + * @param mode the operating mode, can be BMP280_Sleep, BMP280_Forced or BMP280_Normal. + * In sleep mode, no measurements are taken and the sensor uses the least power + * In forced mode, one measurement is taken before the sensor goes to sleep. To trigger the next measurement, the @ref BMP280_trigger_measurement should be called first. + * In normal mode, a measurements is taken followed by a standby period set using @ref BMP280_Standby_Duration_e. This cycle repeats continuously. + * @param temperature_oversampling the oversampling to apply to the measurement, higher is cleaner, but takes more time. + * @param pressure_oversampling the oversampling to apply to the measurement, higher is cleaner, but takes more time. + * @param filter the filtering to apply to the temperature and pressure measurements. + * @param standby_duration the standby duration to apply in normal mode after a measurement has been performed. + * @return true if the configuration was successful + * @return false otherwise + */ bool BMP280_configure(BMP280_Mode_e mode, BMP280_Oversampling_e temperature_oversampling, BMP280_Oversampling_e pressure_oversampling, BMP280_Filter_e filter, BMP280_Standby_Duration_e standby_duration); +/** + * @brief Tells the sensor to perform a new measurement. This has to be called when the sensor is configured in the forced operating mode. + * + * @return true if a new measurement was triggered successfully + * @return false otherwise + */ bool BMP280_trigger_measurement(void); +/** + * @brief Returns the previously sampled temperature in °C. + * + * @return float the value of the temperature in °C + */ float BMP280_get_temperature(void); -float BMP280_get_pressure(void); +/** + * @brief Returns the previously sampled pressure in Pa. + * + * @param temperature the address of a float which will contain the measured temperature. If not needed, can be NULL. + * @return float the value of the pressure in Pa + */ +float BMP280_get_pressure(float * const temperature); +/** + * @brief Returns an approximation of the altitude using the measured atmospheric pressure. + * + * @param pressureAtSeeLevel the current atmospheric pressure at see level in hPa. Can be 0 if unknown and a default value of 1013.25 hPa will be used. + * @param pressure the address of a float which will contain the measured pressure. If not needed, can be NULL. + * @param temperature the address of a float which will contain the measured temperature. If not needed, can be NULL. + * @return float the altitude in meters + */ +float BMP280_get_altitude(float pressureAtSeeLevel, float * const pressure, float * const temperature); + +/** + * @brief Issues a software reset of the sensor. + * + * @return true on success + * @return false on failure + */ bool BMP280_software_reset(void); #endif //BMP280_H \ No newline at end of file