Library for BMP085 digital pressure sensor.
BMP085.cpp
- Committer:
- mcm
- Date:
- 2017-08-25
- Revision:
- 2:34a32898cd23
- Parent:
- 1:01aeefb5f4cf
File content as of revision 2:34a32898cd23:
/** * @brief BMP085.c * @details Digital pressure sensor. * Functions file. * * * @return NA * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre NaN. * @warning NaN * @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ). */ #include "BMP085.h" BMP085::BMP085 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq ) : i2c ( sda, scl ) , BMP085_Addr ( addr ) { i2c.frequency( freq ); } BMP085::~BMP085(){ } /** * @brief BMP085_GetCalibrationCoefficients ( Vector_cal_coeff_t* ) * * @details It gets the calibration coefficients. * * @param[in] NaN * * @param[out] Vector_cal_coeff_t: Calibration coefficients. * * * @return Status of BMP085_GetCalibrationCoefficients. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre NaN * @warning NaN. */ BMP085::BMP085_status_t BMP085::BMP085_GetCalibrationCoefficients ( Vector_cal_coeff_t* myCalCoeff ) { char cmd[22] = { 0 }; uint32_t aux = 0; cmd[0] = BMP085_AC1_MSB; aux = i2c.write ( BMP085_Addr, &cmd[0], 1 ); aux = i2c.read ( BMP085_Addr, &cmd[0], 22 ); // Parse the data myCalCoeff->AC1 = ( cmd[0] << 8 ) | cmd[1]; myCalCoeff->AC2 = ( cmd[2] << 8 ) | cmd[3]; myCalCoeff->AC3 = ( cmd[4] << 8 ) | cmd[5]; myCalCoeff->AC4 = ( cmd[6] << 8 ) | cmd[7]; myCalCoeff->AC5 = ( cmd[8] << 8 ) | cmd[9]; myCalCoeff->AC6 = ( cmd[10] << 8 ) | cmd[11]; myCalCoeff->B1 = ( cmd[12] << 8 ) | cmd[13]; myCalCoeff->B2 = ( cmd[14] << 8 ) | cmd[15]; myCalCoeff->MB = ( cmd[16] << 8 ) | cmd[17]; myCalCoeff->MC = ( cmd[18] << 8 ) | cmd[19]; myCalCoeff->MD = ( cmd[20] << 8 ) | cmd[21]; if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_TriggerTemperature ( void ) * * @details It triggers a new temperature measurement. * * @param[in] NaN. * * @param[out] NaN. * * * @return Status of BMP085_TriggerTemperature. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre NaN * @warning The user MUST respect the maximum temperature conversion time, in this * case, that value is 4.5ms. */ BMP085::BMP085_status_t BMP085::BMP085_TriggerTemperature ( void ) { char cmd[] = { BMP085_CONTROL, BMP085_TRIGGER_TEMPERATURE }; uint32_t aux = 0; aux = i2c.write ( BMP085_Addr, &cmd[0], 2 ); if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_ReadRawTemperature ( Vector_temp_f* ) * * @details It reads an uncompensated temperature. * * @param[in] NaN. * * @param[out] myRawTemperature: Uncompensated temperature. * * * @return Status of BMP085_ReadRawTemperature. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre BMP085_TriggerTemperature function MUST be called before calling this one. * @warning The user MUST respect the maximum temperature conversion time, in this * case, that value is 4.5ms. */ BMP085::BMP085_status_t BMP085::BMP085_ReadRawTemperature ( Vector_temp_f* myRawTemperature ) { char cmd[] = { BMP085_READ_TEMPERATURE, 0 }; uint32_t aux = 0; aux = i2c.write ( BMP085_Addr, &cmd[0], 1 ); aux = i2c.read ( BMP085_Addr, &cmd[0], 2 ); // Parse the data myRawTemperature->UT_Temperature = ( cmd[0] << 8 ) | cmd[1]; if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_ReadCompensatedTemperature ( Vector_temp_f*, Vector_cal_coeff_t ) * * @details It reads an compensated/true temperature. * * @param[in] myCalCoeff: Calibration coefficients. * * @param[out] myTrueTemperature: Compensated/True temperature. * * * @return Status of BMP085_ReadCompensatedTemperature. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre Both BMP085_TriggerTemperature and BMP085_GetCalibrationCoefficients functions MUST be called before calling this one. * @warning The user MUST respect the maximum temperature conversion time, in this * case, that value is 4.5ms. */ BMP085::BMP085_status_t BMP085::BMP085_ReadCompensatedTemperature ( Vector_temp_f* myTrueTemperature, Vector_cal_coeff_t myCalCoeff ) { uint32_t aux = 0; int32_t X1, X2, B5; Vector_temp_f myRawTemperature; aux = BMP085_ReadRawTemperature ( &myRawTemperature ); // Parse the data X1 = ( ( myRawTemperature.UT_Temperature - myCalCoeff.AC6 ) * myCalCoeff.AC5 ) / 32768; X2 = ( myCalCoeff.MC * 2048 ) / ( X1 + myCalCoeff.MD ); B5 = X1 + X2; myTrueTemperature->UT_Temperature = ( B5 + 8 ) / 16; if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_TriggerPressure ( BMP085_pressure_osrs_t ) * * @details It triggers a new pressure measurement. * * @param[in] myResolution: Pressure resolution. * * @param[out] NaN. * * * @return Status of BMP085_TriggerPressure. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre NaN * @warning The user MUST respect the maximum pressure conversion time: * Ultra Low Power Mode: 4.5ms. * Standard Mode: 7.5ms. * High Resolution Mode: 13.5ms. * Ultra High Res. Mode: 25.5ms. */ BMP085::BMP085_status_t BMP085::BMP085_TriggerPressure ( BMP085_pressure_osrs_t myResolution ) { char cmd[] = { BMP085_CONTROL, BMP085_TRIGGER_PRESSURE }; uint32_t aux = 0; // adjust the pressure resolution cmd[1] |= ( myResolution << 6 ); aux = i2c.write ( BMP085_Addr, &cmd[0], 2 ); if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_ReadRawPressure ( Vector_pressure_f* ) * * @details It reads an uncompensated temperature. * * @param[in] NaN. * * @param[out] myRawPressure: Uncompensated temperature. * * * @return Status of BMP085_ReadRawPressure. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre BMP085_TriggerPressure function MUST be called before calling this one. * @warning The user MUST respect the maximum pressure conversion time: * Ultra Low Power Mode: 4.5ms. * Standard Mode: 7.5ms. * High Resolution Mode: 13.5ms. * Ultra High Res. Mode: 25.5ms. */ BMP085::BMP085_status_t BMP085::BMP085_ReadRawPressure ( Vector_pressure_f* myRawPressure ) { char cmd[] = { BMP085_READ_PRESSURE, 0, 0 }; uint32_t aux = 0; aux = i2c.write ( BMP085_Addr, &cmd[0], 1 ); aux = i2c.read ( BMP085_Addr, &cmd[0], 3 ); // Parse the data myRawPressure->UP_Pressure = ( cmd[0] << 16 ) | ( cmd[1] << 8 ) | cmd[2]; if ( aux == I2C_SUCCESS ) return BMP085_SUCCESS; else return BMP085_FAILURE; } /** * @brief BMP085_CalculateCompensated_Temperature_Pressure ( Vector_cal_coeff_t , Vector_temp_f , Vector_pressure_f , BMP085_pressure_osrs_t ) * * @details It reads an compensated pressure. * * @param[in] myCalCoeff: Calibration coefficients. * @param[in] myRawTemperature: Uncompensated temperature data. * @param[in] myRawPressure: Uncompensated pressure data. * @param[in] myResolution: Pressure resolution. * * @param[out] NaN. * * * @return Compensated Temperature and Pressure. * * * @author Manuel Caballero * @date 25/August/2017 * @version 25/August/2017 The ORIGIN * @pre BMP085_GetCalibrationCoefficients, BMP085_ReadRawPressure and BMP085_ReadRawTemperature MUST be called before using this function. * @warning NaN */ BMP085::Vector_compensated_data_f BMP085::BMP085_CalculateCompensated_Temperature_Pressure ( Vector_cal_coeff_t myCalCoeff, Vector_temp_f myRawTemperature, Vector_pressure_f myRawPressure, BMP085_pressure_osrs_t myResolution ) { int32_t B6, X1, B5, X2, X3, B3; uint32_t B4, B7; Vector_compensated_data_f myTrueData; // Calculate true temperature X1 = ( ( myRawTemperature.UT_Temperature - myCalCoeff.AC6 ) * myCalCoeff.AC5 ) / 32768; X2 = ( myCalCoeff.MC * 2048 ) / ( X1 + myCalCoeff.MD ); B5 = X1 + X2; myTrueData.Temperature = ( B5 + 8 ) / 16; // Calculate true pressure B6 = B5 - 4000; X1 = ( myCalCoeff.B2 * ( B6 * B6 / 4096 ) ) /2048; X2 = myCalCoeff.AC2 * B6 / 2048; X3 = X1 + X2; B3 = ( ( ( myCalCoeff.AC1 * 4 + X3 ) << myResolution ) + 2 ) / 4; X1 = myCalCoeff.AC3 * B6 / 8192; X2 = ( myCalCoeff.B1 * ( B6 * B6 / 4096 ) ) / 65536; X3 = ( ( X1 + X2 ) + 2 ) / 4; B4 = myCalCoeff.AC4 * ( uint32_t )( X3 + 32768 ) / 32768; B7 = ( ( uint32_t )myRawPressure.UP_Pressure - B3 ) * ( 50000 >> myResolution ); if ( B7 < 0x80000000 ) myTrueData.Pressure = ( B7 * 2 ) / B4; else myTrueData.Pressure = ( B7 / B4 ) * 2; X1 = ( myTrueData.Pressure / 256 ) * ( myTrueData.Pressure / 256 ); X1 = ( X1 * 3038 ) / 65536; X2 = ( -7357 * myTrueData.Pressure ) / 65536; myTrueData.Pressure = myTrueData.Pressure + ( X1 + X2 + 3791 ) / 16; return myTrueData; }