Bhavin Darji / BMP280

Fork of BMP280 by Edwin Cho

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();
+}