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

Revision:
0:9c1a7a1f0d97
Child:
1:23942d7b7023
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP180.cpp	Sun Jun 15 03:28:26 2014 +0000
@@ -0,0 +1,210 @@
+/*
+ * mbed library program 
+ *  Control BMP180(Bosch) Pressure Sensor
+ *
+ * Copyright (c) 2014 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: August    14th, 2013   for STM32L152 
+ *      Changed: May       21st, 2014   mbed LPC1114
+ *      Revised: June      14th, 2014
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ *---------------- REFERENCE ----------------------------------------------------------------------
+ *  Bosch Sensortec BMP180 Datasheet : BST-BMP180-DS000-09 Revision: 2.5  Date: 5 April 2013
+ */
+
+#include "mbed.h"
+#include "BMP180.h"
+
+//  Barometer I2C ADDDRESS
+//  7bit address = 0b1110111(0x77) -> 8bit = 0b11101110(0xee) -> 0xef(Read) or 0xee(Write)
+#define BMP180ADDR  0xee        // No other choice
+
+//  Bosch barmeter ID
+#define BMP180_CHIP_ID          0x55
+#define UNKNOWN_ID              0
+
+//  register address
+#define BARO_PROM_ADDR          0xaa
+#define BARO_CHIP_ID_REG        0xd0
+#define BARO_VERSION_REG        0xd1
+#define BARO_CTRL_MEAS_REG      0xf4
+#define BARO_ADC_OUT_MSB_REG    0xf6
+#define BARO_ADC_OUT_LSB_REG    0xf7
+#define BARO_SOFT_RESET_REG     0xe0
+
+//  Calibration coefficients address
+#define B_AC1                   0xaa
+#define B_AC2                   0xac
+#define B_AC3                   0xae
+#define B_AC4                   0xb0
+#define B_AC5                   0xb2
+#define B_AC6                   0xb4
+#define B_B1                    0xb6
+#define B_B2                    0xb8
+#define B_MB                    0xba
+#define B_MC                    0xbc
+#define B_MD                    0xbe
+
+#define CONST_MG                3038
+#define CONST_MH                7357
+#define CONST_MI                3791
+
+//  Control data
+#define BARO_PROM_DATA__LEN     22
+#define B_TEMP_MEASURE          0x2e    // temperature measurent
+#define B_PRES_MEASURE          0x34    // pressure measurement
+#define B_PRES_MEASURE_OSS3     0xf4    // pressure /over sampling #3
+#define B_RESET_CMD             0xb6    // Reset chip command
+
+BMP180::BMP180 (PinName p_sda, PinName p_scl) : i2c(p_sda, p_scl) {
+    init();
+}
+
+BMP180::BMP180 (I2C& p_i2c) : i2c(p_i2c) { 
+    init();
+}
+
+float BMP180::read_temperature() {
+    return temperature;
+}
+
+float BMP180::read_pressure() {
+    return pressure;
+}
+
+uint8_t BMP180::read_baro_id() {
+    return id_number;
+}
+
+/*
+ *  Pressure Nomailzation
+ *      Reference: Bosch Sensortec  BMP180  Datasheet=BST-BMP180-DS000-09
+ *                  Revision: 2.5  Date: 5 April 2013  Page15   
+ *      http://www.bosch-sensortec.com/homepage/products_3/environmental_sensors_1/bmp180_1/bmp180
+ */
+void BMP180::normalize() {
+int32_t  raw_pres, raw_temp;
+int32_t  dt_x1 = 0, dt_x2 = 0, dt_x3, dt_b3, dt_b5 = 0, dt_b6;
+uint32_t dt_b4, dt_b7, dx;
+long long int d;
+
+    // start temprerature measurment
+    baro_dt[0] = BARO_CTRL_MEAS_REG;
+    baro_dt[1] = B_TEMP_MEASURE; 
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 2);    
+    wait(0.3);       // wait for convertion
+#if 0
+    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",
+                id_number,eep_ac1,eep_ac2,eep_ac3,eep_ac4,eep_ac5,eep_ac6);
+    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);
+#endif
+    // read temp.
+    baro_dt[0] = BARO_ADC_OUT_MSB_REG;    
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);        // not 3 but 2 (June 14th/Debug)
+    raw_temp = baro_dt[0] << 8 | baro_dt[1];
+#if 0
+    printf("temp_raw:0x%x\n\r",raw_temp);
+#endif
+    // start pressure measurement
+    baro_dt[0] = BARO_CTRL_MEAS_REG;
+    baro_dt[1] = B_PRES_MEASURE_OSS3; 
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 2);
+    wait(0.3);       // wait for convertion
+    // read pressure
+    baro_dt[0] = BARO_ADC_OUT_MSB_REG;    
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
+    i2c_read_n_bytes(BMP180_addr,baro_dt,3);
+    raw_pres = ( baro_dt[0] << 16 | baro_dt[1] << 8 | baro_dt[2] ) >> (8 - 3 );
+#if 0
+    printf("pres_raw:0x%x\n\r",raw_pres);
+#endif
+    // Normarization
+    //      temperature
+    if ( id_number == BMP180_CHIP_ID ){
+        dt_x1 = ( ( raw_temp - (int32_t)eep_ac6 ) * (int32_t)eep_ac5 ) >> 15;
+        dt_x2 = ( (int32_t)eep_mc << 11 ) / ( dt_x1 + (int32_t)eep_md );
+        dt_b5 = dt_x1 + dt_x2;
+    }
+    temperature = (float)( ( dt_b5 + 8 ) >> 4 )/10.0;    // temperature in 0.1 degC    
+    //      Pressure
+    dt_b6 = dt_b5 - 4000;
+    dt_x1 = ( dt_b6 * dt_b6 ) >> 12;
+    dt_x1 *= eep_b2;
+    dt_x1 >>= 11;
+    dt_x2 = ( eep_ac2 * dt_b6 );
+    dt_x2 >>= 11;
+    dt_x3 = dt_x1 + dt_x2;
+    dt_b3 = ( ((((long)eep_ac1) * 4 + dt_x3 ) << 3 ) + 2 ) >> 2;
+    dt_x1 = ( eep_ac3 * dt_b6 ) >> 13;
+    dt_x2 = ( eep_b1 * ( ( dt_b6 * dt_b6 ) >> 12 ) ) >> 16;
+    dt_x3 = ( ( dt_x1 + dt_x2 ) + 2 ) >> 2;
+    dt_b4 = ( eep_ac4 * (uint32_t)(dt_x3 + 32768)) >> 15;
+    dt_b7 = ( (uint32_t)( raw_pres - dt_b3 ) * ( 50000>> 3 ) );
+    if (dt_b7 < 0x80000000){
+        dx = (dt_b7 << 1) / dt_b4;
+    } else {
+        dx = (dt_b7 / dt_b4) << 1;
+    }
+    d = (long long int)dx;
+    d *= d;
+    dt_x1 = (int32_t)( d / 65536 );
+    dt_x1 = ( dt_x1 * CONST_MG ) >> 16;
+    dt_x2 = ( CONST_MH * dx ) >> 16;
+    dt_x2 *= -1;
+    // pressure in Pa
+    dx += ( dt_x1 + dt_x2 + CONST_MI ) >> 4;
+    pressure = (float)dx / 100.0;
+}
+
+void BMP180::init () {
+    BMP180_addr = BMP180ADDR;
+    // parameters AC1-AC6
+    baro_dt[0] = BARO_PROM_ADDR;
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac1 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac2 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac3 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac4 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac5 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_ac6 =  (baro_dt[0] << 8)  | baro_dt[1];
+    // parameters B1,B2
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_b1 =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_b2 =  (baro_dt[0] << 8)  | baro_dt[1];
+    // parameters MB,MC,MD
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_mb =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_mc =  (baro_dt[0] << 8)  | baro_dt[1];
+    i2c_read_n_bytes(BMP180_addr,baro_dt,2);
+    eep_md =  (baro_dt[0] << 8)  | baro_dt[1];
+    // Read ID
+    baro_dt[0] = BARO_CHIP_ID_REG;
+    i2c_write_n_bytes(BMP180_addr, baro_dt, 1);
+    i2c_read_n_bytes(BMP180_addr,baro_dt,1);
+    id_number = baro_dt[0];
+}
+
+void BMP180::i2c_read_n_bytes (int addr, char* dt, int n) {
+    i2c.read(addr, dt, 2);
+}
+
+void BMP180::i2c_write_n_bytes (int addr, char* dt, int n) {
+    i2c.write(addr, dt, 2);
+}