Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BMP280 by
Diff: BMP280.cpp
- Revision:
- 8:0aae5bf93aaa
- Parent:
- 7:c72b726c7dc9
--- a/BMP280.cpp Tue Apr 19 02:03:35 2016 +0000 +++ b/BMP280.cpp Thu Nov 23 11:44:38 2017 +0000 @@ -1,165 +1,330 @@ -/** - * BMP280 Combined humidity and pressure sensor library - * - * @author Toyomasa Watarai - * @version 1.0 - * @date 06-April-2015 - * - * Library for "BMP280 temperature, humidity and pressure sensor module" from Switch Science - * https://www.switch-science.com/catalog/2236/ - * - * For more information about the BMP280: - * http://ae-bst.resource.bosch.com/media/products/dokumente/BMP280/BST-BMP280_DS001-10.pdf - */ +/******************************************************************//** +* @file BMP280.c +* @brief Contains all functions support for I2C based BMP280 +* Pressure Sensor library +* @version 1.0 +* @date 26. May. 2016 +* @author Bhavin.Edutech Learning Solutions +**********************************************************************/ -#include "mbed.h" #include "BMP280.h" -BMP280::BMP280(PinName sda, PinName scl, char slave_adr) - : - i2c_p(new I2C(sda, scl)), - i2c(*i2c_p), - address(slave_adr), - t_fine(0) +//****************************************************************************** +BMP280::BMP280(PinName sda, PinName scl) { - initialize(); + i2c_ = new I2C(sda, scl); + i2c_owner = true; + + i2c_->frequency(400000); } -BMP280::BMP280(I2C &i2c_obj, char slave_adr) - : - i2c_p(NULL), - i2c(i2c_obj), - address(slave_adr), - t_fine(0) +//****************************************************************************** +BMP280::BMP280(I2C *i2c) : + i2c_(i2c) { - initialize(); + i2c_owner = false; } +//****************************************************************************** BMP280::~BMP280() { - if (NULL != i2c_p) - delete i2c_p; + if(i2c_owner) { + delete i2c_; + } } - -void BMP280::initialize() + +//****************************************************************************** + +void BMP280::writeByte(uint8_t Address, uint8_t data) +{ + char data_write[2]; + data_write[0] = Address; + data_write[1] = data; + i2c_->write(BMP280_I2C_ADDRESS2, data_write, 2, 0); +} + +//****************************************************************************** + +char BMP280::readByte(uint8_t Address) { - char cmd[18]; - - cmd[0] = 0xf2; // ctrl_hum - cmd[1] = 0x01; // Humidity oversampling x1 - i2c.write(address, cmd, 2); - - cmd[0] = 0xf4; // ctrl_meas - cmd[1] = 0x27; // Temparature oversampling x1, Pressure oversampling x1, Normal mode - i2c.write(address, cmd, 2); - - cmd[0] = 0xf5; // config - cmd[1] = 0xa0; // Standby 1000ms, Filter off - i2c.write(address, cmd, 2); - - cmd[0] = 0x88; // read dig_T regs - i2c.write(address, cmd, 1); - i2c.read(address, cmd, 6); - - dig_T1 = (cmd[1] << 8) | cmd[0]; - dig_T2 = (cmd[3] << 8) | cmd[2]; - dig_T3 = (cmd[5] << 8) | cmd[4]; - - DEBUG_PRINT("dig_T = 0x%x, 0x%x, 0x%x\n", dig_T1, dig_T2, dig_T3); - - cmd[0] = 0x8E; // read dig_P regs - i2c.write(address, cmd, 1); - i2c.read(address, cmd, 18); - - dig_P1 = (cmd[ 1] << 8) | cmd[ 0]; - dig_P2 = (cmd[ 3] << 8) | cmd[ 2]; - dig_P3 = (cmd[ 5] << 8) | cmd[ 4]; - dig_P4 = (cmd[ 7] << 8) | cmd[ 6]; - dig_P5 = (cmd[ 9] << 8) | cmd[ 8]; - dig_P6 = (cmd[11] << 8) | cmd[10]; - dig_P7 = (cmd[13] << 8) | cmd[12]; - dig_P8 = (cmd[15] << 8) | cmd[14]; - dig_P9 = (cmd[17] << 8) | cmd[16]; - - DEBUG_PRINT("dig_P = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9); - - /* cmd[0] = 0xA1; // read dig_H regs - i2c.write(address, cmd, 1); - i2c.read(address, cmd, 1); - cmd[1] = 0xE1; // read dig_H regs - i2c.write(address, &cmd[1], 1); - i2c.read(address, &cmd[1], 7); + char data[1]; // `data` will store the register data + char data_write[1]; + data_write[0] = Address; + i2c_->write(BMP280_I2C_ADDRESS2, data_write, 1, 1); // no stop + i2c_->read(BMP280_I2C_ADDRESS2, data, 1, 0); + return data[0]; +} + +//****************************************************************************** + +void BMP280::readBytes(uint8_t Address, uint8_t count, uint8_t * dest) +{ + char data[14]; + char data_write[1]; + data_write[0] = Address; + i2c_->write(BMP280_I2C_ADDRESS2, data_write, 1, 1); // no stop + i2c_->read(BMP280_I2C_ADDRESS2, data, count, 0); + for(int ii = 0; ii < count; ii++) { + dest[ii] = data[ii]; + } +} - dig_H1 = cmd[0]; - dig_H2 = (cmd[2] << 8) | cmd[1]; - dig_H3 = cmd[3]; - dig_H4 = (cmd[4] << 4) | (cmd[5] & 0x0f); - dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f); - dig_H6 = cmd[7]; - - DEBUG_PRINT("dig_H = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6); -*/ +//****************************************************************************** +uint8_t BMP280::BMP280_GetID(void) +{ + return readByte(BMP280_CHIP_ID_REG); +} +//****************************************************************************** +void BMP280::BMP280_SoftReset(void) +{ + writeByte(BMP280_RST_REG, BMP280_SOFT_RESET_CODE); +} +//****************************************************************************** +uint8_t BMP280::BMP280_GetStatus(void) +{ + return readByte(BMP280_STAT_REG); +} +//****************************************************************************** +uint8_t BMP280::BMP280_GetCtrlMeasurement(void) +{ + return readByte(BMP280_CTRL_MEAS_REG); +} +//****************************************************************************** +uint8_t BMP280::BMP280_GetConfig(void) +{ + return readByte(BMP280_CONFIG_REG); +} +//****************************************************************************** +void BMP280::BMP280_ReadMeasurements(void) +{ + uint8_t rx_Buf[6]= {0}; + + readBytes(BMP280_PRESSURE_MSB_REG, 6, &rx_Buf[0]); + + adc_t = (uint32_t)rx_Buf[BMP280_DATA_FRAME_TEMPERATURE_XLSB_BYTE] >> 4; + adc_t |= (uint32_t)rx_Buf[BMP280_DATA_FRAME_TEMPERATURE_LSB_BYTE] << 4; + adc_t |= (uint32_t)rx_Buf[BMP280_DATA_FRAME_TEMPERATURE_MSB_BYTE] << 12; + + adc_p = (uint32_t)rx_Buf[BMP280_DATA_FRAME_PRESSURE_XLSB_BYTE] >> 4; + adc_p |= (uint32_t)rx_Buf[BMP280_DATA_FRAME_PRESSURE_LSB_BYTE] << 4; + adc_p |= (uint32_t)rx_Buf[BMP280_DATA_FRAME_PRESSURE_MSB_BYTE] << 12; } - -float BMP280::getTemperature() + +//****************************************************************************** + +void BMP280::BMP280_ReadCalibrationParams(void) { - uint32_t temp_raw; - float tempf; - char cmd[4]; - - cmd[0] = 0xfa; // temp_msb - i2c.write(address, cmd, 1); - i2c.read(address, &cmd[1], 3); - - temp_raw = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4); - - int32_t temp; - - temp = - (((((temp_raw >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) + - ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12) * dig_T3) >> 14); - - t_fine = temp; - temp = (temp * 5 + 128) >> 8; - tempf = (float)temp; - - return (tempf/100.0f); + uint8_t lsb, msb; + + msb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T1_MSB_REG); + cal_param.dig_T1 = (uint16_t) msb; + lsb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG); + cal_param.dig_T1 = (cal_param.dig_T1 << 8) + lsb; + + + msb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T2_MSB_REG); + cal_param.dig_T2 = (int16_t) msb; + lsb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T2_LSB_REG); + cal_param.dig_T2 = (cal_param.dig_T2 << 8) + lsb; + + + msb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T3_MSB_REG); + cal_param.dig_T3 = (int16_t) msb; + lsb = readByte(BMP280_TEMPERATURE_CALIB_DIG_T3_LSB_REG); + cal_param.dig_T3 = (cal_param.dig_T3 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P1_MSB_REG); + cal_param.dig_P1 = (uint16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P1_LSB_REG); + cal_param.dig_P1 = (cal_param.dig_P1 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P2_MSB_REG); + cal_param.dig_P2 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P2_LSB_REG); + cal_param.dig_P2 = (cal_param.dig_P2 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P3_MSB_REG); + cal_param.dig_P3 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P3_LSB_REG); + cal_param.dig_P3 = (cal_param.dig_P3 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P4_MSB_REG); + cal_param.dig_P4 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P4_LSB_REG); + cal_param.dig_P4 = (cal_param.dig_P4 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P5_MSB_REG); + cal_param.dig_P5 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P5_LSB_REG); + cal_param.dig_P5 = (cal_param.dig_P5 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P6_MSB_REG); + cal_param.dig_P6 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P6_LSB_REG); + cal_param.dig_P6 = (cal_param.dig_P6 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P7_MSB_REG); + cal_param.dig_P7 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P7_LSB_REG); + cal_param.dig_P7 = (cal_param.dig_P7 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P8_MSB_REG); + cal_param.dig_P8 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P8_LSB_REG); + cal_param.dig_P8 = (cal_param.dig_P8 << 8) + lsb; + + + msb = readByte(BMP280_PRESSURE_CALIB_DIG_P9_MSB_REG); + cal_param.dig_P9 = (int16_t) msb; + lsb = readByte(BMP280_PRESSURE_CALIB_DIG_P9_LSB_REG); + cal_param.dig_P9 = (cal_param.dig_P9 << 8) + lsb; } - -float BMP280::getPressure() + +//****************************************************************************** + +void BMP280::BMP280_SetOversamplingPressure(uint8_t Value) +{ + uint8_t ctrlm; + + ctrlm = BMP280_GetCtrlMeasurement(); + ctrlm &= ~BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__MSK; + ctrlm |= Value << BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__POS; + + writeByte(BMP280_CTRL_MEAS_REG, ctrlm); + ctrlm = BMP280_GetCtrlMeasurement(); +} + +//****************************************************************************** + +void BMP280::BMP280_SetOversamplingTemperature(uint8_t Value) +{ + int8_t ctrlm; + + ctrlm = BMP280_GetCtrlMeasurement(); + ctrlm &= ~BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__MSK; + ctrlm |= Value << BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__POS; + + writeByte(BMP280_CTRL_MEAS_REG, ctrlm); +} + +//****************************************************************************** + +void BMP280::BMP280_SetPowerMode(BMP280_Mode_Type Value) { - uint32_t press_raw; - float pressf; - char cmd[4]; - - cmd[0] = 0xf7; // press_msb - i2c.write(address, cmd, 1); - i2c.read(address, &cmd[1], 3); - - press_raw = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4); - - int32_t var1, var2; - uint32_t press; - - var1 = (t_fine >> 1) - 64000; - var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6; - var2 = var2 + ((var1 * dig_P5) << 1); - var2 = (var2 >> 2) + (dig_P4 << 16); - var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18; - var1 = ((32768 + var1) * dig_P1) >> 15; - if (var1 == 0) { - return 0; - } - press = (((1048576 - press_raw) - (var2 >> 12))) * 3125; - if(press < 0x80000000) { - press = (press << 1) / var1; - } else { - press = (press / var1) * 2; - } - var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >> 12; - var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13; - press = (press + ((var1 + var2 + dig_P7) >> 4)); - - pressf = (float)press; - return (pressf/100.0f); -} \ No newline at end of file + uint8_t ctrlm; + + ctrlm = BMP280_GetCtrlMeasurement(); + ctrlm |= Value; + + writeByte(BMP280_CTRL_MEAS_REG, ctrlm); +} + +//****************************************************************************** + +void BMP280::BMP280_SetFilterCoefficient(BMP280_Filter_Coeff_Type Value) +{ + uint8_t cfgv; + + cfgv = BMP280_GetConfig(); + cfgv &= ~BMP280_CONFIG_REG_FILTER__MSK; + cfgv |= Value << BMP280_CONFIG_REG_FILTER__POS; +} + +//****************************************************************************** + +void BMP280::BMP280_SetStandbyTime(BMP280_Standby_Type Value) +{ + uint8_t cfgv; + + cfgv = BMP280_GetConfig(); + cfgv &= ~BMP280_CONFIG_REG_STANDBY_DURN__MSK; + cfgv |= Value << BMP280_CONFIG_REG_STANDBY_DURN__POS; +} + +//****************************************************************************** + +uint8_t BMP280::BMP280_IsMeasuring(void) +{ + uint8_t output; + + output = BMP280_GetStatus(); + return (output & BMP280_STATUS_REG_MEASURING__MSK); +} + +//****************************************************************************** + +int32_t BMP280::BMP280_Compensate_T(void) +{ + int32_t temp1, temp2, T; + + temp1 = ((((adc_t>>3) -((int32_t)cal_param.dig_T1<<1))) * ((int32_t)cal_param.dig_T2)) >> 11; + temp2 = (((((adc_t>>4) - ((int32_t)cal_param.dig_T1)) * ((adc_t>>4) - ((int32_t)cal_param.dig_T1))) >> 12) * ((int32_t)cal_param.dig_T3)) >> 14; + t_fine = temp1 + temp2; + T = (t_fine * 5 + 128) >> 8; + return T; +} + +//****************************************************************************** + +uint32_t BMP280::BMP280_Compensate_P() +{ + int32_t press1, press2; + uint32_t P; + + press1 = (((int32_t)t_fine)>>1) - (int32_t)64000; + press2 = (((press1>>2) * (press1>>2)) >> 11 ) * ((int32_t)cal_param.dig_P6); + press2 = press2 + ((press1*((int32_t)cal_param.dig_P5))<<1); + press2 = (press2>>2)+(((int32_t)cal_param.dig_P4)<<16); + press1 = (((cal_param.dig_P3 * (((press1>>2) * (press1>>2)) >> 13 )) >> 3) + ((((int32_t)cal_param.dig_P2) * press1)>>1))>>18; + press1 =((((32768+press1))*((int32_t)cal_param.dig_P1))>>15); + if (press1 == 0) + { + return 0; // avoid exception caused by division by zero + } + P = (((uint32_t)(((int32_t)1048576)-adc_p)-(press2>>12)))*3125; + if (P < 0x80000000) + { + P = (P << 1) / ((uint32_t)press1); + } + else + { + P = (P / (uint32_t)press1) * 2; + } + press1 = (((int32_t)cal_param.dig_P9) * ((int32_t)(((P>>3) * (P>>3))>>13)))>>12; + press2 = (((int32_t)(P>>2)) * ((int32_t)cal_param.dig_P8))>>13; + P = (uint32_t)((int32_t)P + ((press1 + press2 + cal_param.dig_P7) >> 4)); + return P; +} + +//****************************************************************************** + +void BMP280::BMP280_INIT(void) +{ + BMP280_SetStandbyTime(BMP280_STANDBY_TIME_1_MS); // Standby time 1ms + BMP280_SetFilterCoefficient(BMP280_FILTER_COEFF_16); // IIR Filter coefficient 16 + BMP280_SetOversamplingPressure(BMP280_OVERSAMP_16X); // Pressure x16 oversampling + BMP280_SetOversamplingTemperature(BMP280_OVERSAMP_2X); // Temperature x2 oversampling + BMP280_SetPowerMode(BMP280_NORMAL_MODE); +} + +//****************************************************************************** + +float BMP280::BMP280_GetTemperature(void) +{ + return BMP280_Compensate_T(); +} + +//****************************************************************************** + +float BMP280::BMP280_GetPressure(void) +{ + return BMP280_Compensate_P(); +}