BMP180 is a digital barometric pressure sensor made by Bosch Sensortec (I2C Interface)

Dependents:   LPC1114_data_logger ProjectIOT Wether_Meter LPC1114_barometer_with_data_logging

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP180.cpp Source File

BMP180.cpp

00001 /*
00002  * mbed library program 
00003  *  Control BMP180(Bosch) Pressure Sensor
00004  *
00005  * Copyright (c) 2013,'14,'17 Kenji Arai / JH1PJL
00006  *  http://www.page.sannet.ne.jp/kenjia/index.html
00007  *  http://mbed.org/users/kenjiArai/
00008  *      Created: August     14th, 2013   for STM32L152 
00009  *      Changed: May        21st, 2014   mbed LPC1114
00010  *      Revised: August     23rd, 2017
00011  */
00012 /*
00013  *---------------- REFERENCE ----------------------------------------------------------------------
00014  *  Bosch Sensortec BMP180 Datasheet : BST-BMP180-DS000-09 Revision: 2.5  Date: 5 April 2013
00015  */
00016 
00017 #include "mbed.h"
00018 #include "BMP180.h"
00019 
00020 //  Barometer I2C ADDDRESS
00021 //  7bit address = 0b1110111(0x77) -> 8bit = 0b11101110(0xee) -> 0xef(Read) or 0xee(Write)
00022 #define BMP180ADDR  0xee        // No other choice
00023 
00024 //  register address
00025 #define BARO_PROM_ADDR          0xaa
00026 #define BARO_CHIP_ID_REG        0xd0
00027 #define BARO_VERSION_REG        0xd1
00028 #define BARO_CTRL_MEAS_REG      0xf4
00029 #define BARO_ADC_OUT_MSB_REG    0xf6
00030 #define BARO_ADC_OUT_LSB_REG    0xf7
00031 #define BARO_SOFT_RESET_REG     0xe0
00032 
00033 //  Calibration coefficients address
00034 #define B_AC1                   0xaa
00035 #define B_AC2                   0xac
00036 #define B_AC3                   0xae
00037 #define B_AC4                   0xb0
00038 #define B_AC5                   0xb2
00039 #define B_AC6                   0xb4
00040 #define B_B1                    0xb6
00041 #define B_B2                    0xb8
00042 #define B_MB                    0xba
00043 #define B_MC                    0xbc
00044 #define B_MD                    0xbe
00045 
00046 #define CONST_MG                3038
00047 #define CONST_MH                7357
00048 #define CONST_MI                3791
00049 
00050 //  Control data
00051 #define BARO_PROM_DATA__LEN     22
00052 #define B_TEMP_MEASURE          0x2e    // temperature measurent
00053 #define B_PRES_MEASURE          0x34    // pressure measurement
00054 #define B_PRES_MEASURE_OSS3     0xf4    // pressure /over sampling #3
00055 #define B_RESET_CMD             0xb6    // Reset chip command
00056 
00057 BMP180::BMP180 (PinName p_sda, PinName p_scl)
00058  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00059 {
00060     init();
00061 }
00062 
00063 BMP180::BMP180 (I2C& p_i2c)
00064  : _i2c(p_i2c)
00065 { 
00066     init();
00067 }
00068 
00069 float BMP180::read_temperature() {
00070     return temperature;
00071 }
00072 
00073 float BMP180::read_pressure() {
00074     return pressure;
00075 }
00076 
00077 uint8_t BMP180::read_baro_id() {
00078     return id_number;
00079 }
00080 
00081 /*
00082  *  Pressure Nomailzation
00083  *      Reference: Bosch Sensortec  BMP180  Datasheet=BST-BMP180-DS000-09
00084  *                  Revision: 2.5  Date: 5 April 2013  Page15   
00085  *      http://www.bosch-sensortec.com/homepage/products_3/environmental_sensors_1/bmp180_1/bmp180
00086  */
00087 void BMP180::normalize() {
00088 int32_t  raw_pres, raw_temp;
00089 int32_t  dt_x1 = 0, dt_x2 = 0, dt_x3, dt_b3, dt_b5 = 0, dt_b6;
00090 uint32_t dt_b4, dt_b7, dx;
00091 long long int d;
00092 
00093     // start temprerature measurment
00094     baro_dt[0] = BARO_CTRL_MEAS_REG;
00095     baro_dt[1] = B_TEMP_MEASURE; 
00096     _i2c_write_n_bytes(BMP180_addr, baro_dt, 2);    
00097     wait(0.3);       // wait for convertion
00098 #if 0
00099     printf("type:0x%x\r\nac1:0x%x,ac2:0x%x,ac3:0x%x,ac4:0x%x,ac5:0x%x,ac6:0x%x\n\r",
00100                 id_number,eep_ac1,eep_ac2,eep_ac3,eep_ac4,eep_ac5,eep_ac6);
00101     printf("b1:0x%x,b2:0x%x,mb:0x%x,mc:0x%x,md:0x%x\n\r",eep_b1,eep_b2,eep_mb,eep_mc,eep_md);
00102 #endif
00103     // read temp.
00104     baro_dt[0] = BARO_ADC_OUT_MSB_REG;    
00105     _i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
00106     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);        // not 3 but 2 (June 14th/Debug)
00107     raw_temp = baro_dt[0] << 8 | baro_dt[1];
00108 #if 0
00109     printf("temp_raw:0x%x\n\r",raw_temp);
00110 #endif
00111     // start pressure measurement
00112     baro_dt[0] = BARO_CTRL_MEAS_REG;
00113     baro_dt[1] = B_PRES_MEASURE_OSS3; 
00114     _i2c_write_n_bytes(BMP180_addr, baro_dt, 2);
00115     wait(0.3);       // wait for convertion
00116     // read pressure
00117     baro_dt[0] = BARO_ADC_OUT_MSB_REG;    
00118     _i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
00119     _i2c_read_n_bytes(BMP180_addr,baro_dt,3);
00120     raw_pres = ( baro_dt[0] << 16 | baro_dt[1] << 8 | baro_dt[2] ) >> (8 - 3 );
00121 #if 0
00122     printf("pres_raw:0x%x\n\r",raw_pres);
00123 #endif
00124     // Normarization
00125     //      temperature
00126     if ( id_number == BMP180_CHIP_ID ){
00127         dt_x1 = ( ( raw_temp - (int32_t)eep_ac6 ) * (int32_t)eep_ac5 ) >> 15;
00128         dt_x2 = ( (int32_t)eep_mc << 11 ) / ( dt_x1 + (int32_t)eep_md );
00129         dt_b5 = dt_x1 + dt_x2;
00130     }
00131     temperature = (float)( ( dt_b5 + 8 ) >> 4 )/10.0f;    // temperature in 0.1 degC    
00132     //      Pressure
00133     dt_b6 = dt_b5 - 4000;
00134     dt_x1 = ( dt_b6 * dt_b6 ) >> 12;
00135     dt_x1 *= eep_b2;
00136     dt_x1 >>= 11;
00137     dt_x2 = ( eep_ac2 * dt_b6 );
00138     dt_x2 >>= 11;
00139     dt_x3 = dt_x1 + dt_x2;
00140     dt_b3 = ( ((((long)eep_ac1) * 4 + dt_x3 ) << 3 ) + 2 ) >> 2;
00141     dt_x1 = ( eep_ac3 * dt_b6 ) >> 13;
00142     dt_x2 = ( eep_b1 * ( ( dt_b6 * dt_b6 ) >> 12 ) ) >> 16;
00143     dt_x3 = ( ( dt_x1 + dt_x2 ) + 2 ) >> 2;
00144     dt_b4 = ( eep_ac4 * (uint32_t)(dt_x3 + 32768)) >> 15;
00145     dt_b7 = ( (uint32_t)( raw_pres - dt_b3 ) * ( 50000>> 3 ) );
00146     if (dt_b7 < 0x80000000){
00147         dx = (dt_b7 << 1) / dt_b4;
00148     } else {
00149         dx = (dt_b7 / dt_b4) << 1;
00150     }
00151     d = (long long int)dx;
00152     d *= d;
00153     dt_x1 = (int32_t)( d / 65536 );
00154     dt_x1 = ( dt_x1 * CONST_MG ) >> 16;
00155     dt_x2 = ( CONST_MH * dx ) >> 16;
00156     dt_x2 *= -1;
00157     // pressure in Pa
00158     dx += ( dt_x1 + dt_x2 + CONST_MI ) >> 4;
00159     pressure = (float)dx / 100.0f;
00160 }
00161 
00162 void BMP180::init () {
00163     BMP180_addr = BMP180ADDR;
00164     // parameters AC1-AC6
00165     baro_dt[0] = BARO_PROM_ADDR;
00166     _i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
00167     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00168     eep_ac1 =  (baro_dt[0] << 8)  | baro_dt[1];
00169     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00170     eep_ac2 =  (baro_dt[0] << 8)  | baro_dt[1];
00171     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00172     eep_ac3 =  (baro_dt[0] << 8)  | baro_dt[1];
00173     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00174     eep_ac4 =  (baro_dt[0] << 8)  | baro_dt[1];
00175     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00176     eep_ac5 =  (baro_dt[0] << 8)  | baro_dt[1];
00177     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00178     eep_ac6 =  (baro_dt[0] << 8)  | baro_dt[1];
00179     // parameters B1,B2
00180     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00181     eep_b1 =  (baro_dt[0] << 8)  | baro_dt[1];
00182     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00183     eep_b2 =  (baro_dt[0] << 8)  | baro_dt[1];
00184     // parameters MB,MC,MD
00185     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00186     eep_mb =  (baro_dt[0] << 8)  | baro_dt[1];
00187     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00188     eep_mc =  (baro_dt[0] << 8)  | baro_dt[1];
00189     _i2c_read_n_bytes(BMP180_addr,baro_dt,2);
00190     eep_md =  (baro_dt[0] << 8)  | baro_dt[1];
00191     // Read ID
00192     baro_dt[0] = BARO_CHIP_ID_REG;
00193     _i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
00194     _i2c_read_n_bytes(BMP180_addr,baro_dt,1);
00195     id_number = baro_dt[0];
00196 }
00197 
00198 void BMP180::_i2c_read_n_bytes (int addr, char* dt, int n) {
00199     _i2c.read(addr, dt, n);
00200 }
00201 
00202 void BMP180::_i2c_write_n_bytes (int addr, char* dt, int n) {
00203     _i2c.write(addr, dt, n);
00204 }
00205