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
BMP180.cpp@4:37fed112956c, 2017-08-23 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed Aug 23 09:23:32 2017 +0000
- Revision:
- 4:37fed112956c
- Parent:
- 2:b81e7659be7a
countermeasure for NonCopyable
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:9c1a7a1f0d97 | 1 | /* |
kenjiArai | 0:9c1a7a1f0d97 | 2 | * mbed library program |
kenjiArai | 0:9c1a7a1f0d97 | 3 | * Control BMP180(Bosch) Pressure Sensor |
kenjiArai | 0:9c1a7a1f0d97 | 4 | * |
kenjiArai | 4:37fed112956c | 5 | * Copyright (c) 2013,'14,'17 Kenji Arai / JH1PJL |
kenjiArai | 0:9c1a7a1f0d97 | 6 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 0:9c1a7a1f0d97 | 7 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 4:37fed112956c | 8 | * Created: August 14th, 2013 for STM32L152 |
kenjiArai | 4:37fed112956c | 9 | * Changed: May 21st, 2014 mbed LPC1114 |
kenjiArai | 4:37fed112956c | 10 | * Revised: August 23rd, 2017 |
kenjiArai | 0:9c1a7a1f0d97 | 11 | */ |
kenjiArai | 0:9c1a7a1f0d97 | 12 | /* |
kenjiArai | 0:9c1a7a1f0d97 | 13 | *---------------- REFERENCE ---------------------------------------------------------------------- |
kenjiArai | 0:9c1a7a1f0d97 | 14 | * Bosch Sensortec BMP180 Datasheet : BST-BMP180-DS000-09 Revision: 2.5 Date: 5 April 2013 |
kenjiArai | 0:9c1a7a1f0d97 | 15 | */ |
kenjiArai | 0:9c1a7a1f0d97 | 16 | |
kenjiArai | 0:9c1a7a1f0d97 | 17 | #include "mbed.h" |
kenjiArai | 0:9c1a7a1f0d97 | 18 | #include "BMP180.h" |
kenjiArai | 0:9c1a7a1f0d97 | 19 | |
kenjiArai | 0:9c1a7a1f0d97 | 20 | // Barometer I2C ADDDRESS |
kenjiArai | 0:9c1a7a1f0d97 | 21 | // 7bit address = 0b1110111(0x77) -> 8bit = 0b11101110(0xee) -> 0xef(Read) or 0xee(Write) |
kenjiArai | 0:9c1a7a1f0d97 | 22 | #define BMP180ADDR 0xee // No other choice |
kenjiArai | 0:9c1a7a1f0d97 | 23 | |
kenjiArai | 0:9c1a7a1f0d97 | 24 | // register address |
kenjiArai | 0:9c1a7a1f0d97 | 25 | #define BARO_PROM_ADDR 0xaa |
kenjiArai | 0:9c1a7a1f0d97 | 26 | #define BARO_CHIP_ID_REG 0xd0 |
kenjiArai | 0:9c1a7a1f0d97 | 27 | #define BARO_VERSION_REG 0xd1 |
kenjiArai | 0:9c1a7a1f0d97 | 28 | #define BARO_CTRL_MEAS_REG 0xf4 |
kenjiArai | 0:9c1a7a1f0d97 | 29 | #define BARO_ADC_OUT_MSB_REG 0xf6 |
kenjiArai | 0:9c1a7a1f0d97 | 30 | #define BARO_ADC_OUT_LSB_REG 0xf7 |
kenjiArai | 0:9c1a7a1f0d97 | 31 | #define BARO_SOFT_RESET_REG 0xe0 |
kenjiArai | 0:9c1a7a1f0d97 | 32 | |
kenjiArai | 0:9c1a7a1f0d97 | 33 | // Calibration coefficients address |
kenjiArai | 0:9c1a7a1f0d97 | 34 | #define B_AC1 0xaa |
kenjiArai | 0:9c1a7a1f0d97 | 35 | #define B_AC2 0xac |
kenjiArai | 0:9c1a7a1f0d97 | 36 | #define B_AC3 0xae |
kenjiArai | 0:9c1a7a1f0d97 | 37 | #define B_AC4 0xb0 |
kenjiArai | 0:9c1a7a1f0d97 | 38 | #define B_AC5 0xb2 |
kenjiArai | 0:9c1a7a1f0d97 | 39 | #define B_AC6 0xb4 |
kenjiArai | 0:9c1a7a1f0d97 | 40 | #define B_B1 0xb6 |
kenjiArai | 0:9c1a7a1f0d97 | 41 | #define B_B2 0xb8 |
kenjiArai | 0:9c1a7a1f0d97 | 42 | #define B_MB 0xba |
kenjiArai | 0:9c1a7a1f0d97 | 43 | #define B_MC 0xbc |
kenjiArai | 0:9c1a7a1f0d97 | 44 | #define B_MD 0xbe |
kenjiArai | 0:9c1a7a1f0d97 | 45 | |
kenjiArai | 0:9c1a7a1f0d97 | 46 | #define CONST_MG 3038 |
kenjiArai | 0:9c1a7a1f0d97 | 47 | #define CONST_MH 7357 |
kenjiArai | 0:9c1a7a1f0d97 | 48 | #define CONST_MI 3791 |
kenjiArai | 0:9c1a7a1f0d97 | 49 | |
kenjiArai | 0:9c1a7a1f0d97 | 50 | // Control data |
kenjiArai | 0:9c1a7a1f0d97 | 51 | #define BARO_PROM_DATA__LEN 22 |
kenjiArai | 0:9c1a7a1f0d97 | 52 | #define B_TEMP_MEASURE 0x2e // temperature measurent |
kenjiArai | 0:9c1a7a1f0d97 | 53 | #define B_PRES_MEASURE 0x34 // pressure measurement |
kenjiArai | 0:9c1a7a1f0d97 | 54 | #define B_PRES_MEASURE_OSS3 0xf4 // pressure /over sampling #3 |
kenjiArai | 0:9c1a7a1f0d97 | 55 | #define B_RESET_CMD 0xb6 // Reset chip command |
kenjiArai | 0:9c1a7a1f0d97 | 56 | |
kenjiArai | 4:37fed112956c | 57 | BMP180::BMP180 (PinName p_sda, PinName p_scl) |
kenjiArai | 4:37fed112956c | 58 | : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p) |
kenjiArai | 4:37fed112956c | 59 | { |
kenjiArai | 0:9c1a7a1f0d97 | 60 | init(); |
kenjiArai | 0:9c1a7a1f0d97 | 61 | } |
kenjiArai | 0:9c1a7a1f0d97 | 62 | |
kenjiArai | 4:37fed112956c | 63 | BMP180::BMP180 (I2C& p_i2c) |
kenjiArai | 4:37fed112956c | 64 | : _i2c(p_i2c) |
kenjiArai | 4:37fed112956c | 65 | { |
kenjiArai | 0:9c1a7a1f0d97 | 66 | init(); |
kenjiArai | 0:9c1a7a1f0d97 | 67 | } |
kenjiArai | 0:9c1a7a1f0d97 | 68 | |
kenjiArai | 0:9c1a7a1f0d97 | 69 | float BMP180::read_temperature() { |
kenjiArai | 0:9c1a7a1f0d97 | 70 | return temperature; |
kenjiArai | 0:9c1a7a1f0d97 | 71 | } |
kenjiArai | 0:9c1a7a1f0d97 | 72 | |
kenjiArai | 0:9c1a7a1f0d97 | 73 | float BMP180::read_pressure() { |
kenjiArai | 0:9c1a7a1f0d97 | 74 | return pressure; |
kenjiArai | 0:9c1a7a1f0d97 | 75 | } |
kenjiArai | 0:9c1a7a1f0d97 | 76 | |
kenjiArai | 0:9c1a7a1f0d97 | 77 | uint8_t BMP180::read_baro_id() { |
kenjiArai | 0:9c1a7a1f0d97 | 78 | return id_number; |
kenjiArai | 0:9c1a7a1f0d97 | 79 | } |
kenjiArai | 0:9c1a7a1f0d97 | 80 | |
kenjiArai | 0:9c1a7a1f0d97 | 81 | /* |
kenjiArai | 0:9c1a7a1f0d97 | 82 | * Pressure Nomailzation |
kenjiArai | 0:9c1a7a1f0d97 | 83 | * Reference: Bosch Sensortec BMP180 Datasheet=BST-BMP180-DS000-09 |
kenjiArai | 0:9c1a7a1f0d97 | 84 | * Revision: 2.5 Date: 5 April 2013 Page15 |
kenjiArai | 0:9c1a7a1f0d97 | 85 | * http://www.bosch-sensortec.com/homepage/products_3/environmental_sensors_1/bmp180_1/bmp180 |
kenjiArai | 0:9c1a7a1f0d97 | 86 | */ |
kenjiArai | 0:9c1a7a1f0d97 | 87 | void BMP180::normalize() { |
kenjiArai | 0:9c1a7a1f0d97 | 88 | int32_t raw_pres, raw_temp; |
kenjiArai | 0:9c1a7a1f0d97 | 89 | int32_t dt_x1 = 0, dt_x2 = 0, dt_x3, dt_b3, dt_b5 = 0, dt_b6; |
kenjiArai | 0:9c1a7a1f0d97 | 90 | uint32_t dt_b4, dt_b7, dx; |
kenjiArai | 0:9c1a7a1f0d97 | 91 | long long int d; |
kenjiArai | 0:9c1a7a1f0d97 | 92 | |
kenjiArai | 0:9c1a7a1f0d97 | 93 | // start temprerature measurment |
kenjiArai | 0:9c1a7a1f0d97 | 94 | baro_dt[0] = BARO_CTRL_MEAS_REG; |
kenjiArai | 0:9c1a7a1f0d97 | 95 | baro_dt[1] = B_TEMP_MEASURE; |
kenjiArai | 4:37fed112956c | 96 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 2); |
kenjiArai | 0:9c1a7a1f0d97 | 97 | wait(0.3); // wait for convertion |
kenjiArai | 0:9c1a7a1f0d97 | 98 | #if 0 |
kenjiArai | 0:9c1a7a1f0d97 | 99 | 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", |
kenjiArai | 0:9c1a7a1f0d97 | 100 | id_number,eep_ac1,eep_ac2,eep_ac3,eep_ac4,eep_ac5,eep_ac6); |
kenjiArai | 0:9c1a7a1f0d97 | 101 | 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); |
kenjiArai | 0:9c1a7a1f0d97 | 102 | #endif |
kenjiArai | 0:9c1a7a1f0d97 | 103 | // read temp. |
kenjiArai | 0:9c1a7a1f0d97 | 104 | baro_dt[0] = BARO_ADC_OUT_MSB_REG; |
kenjiArai | 4:37fed112956c | 105 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 1); |
kenjiArai | 4:37fed112956c | 106 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); // not 3 but 2 (June 14th/Debug) |
kenjiArai | 0:9c1a7a1f0d97 | 107 | raw_temp = baro_dt[0] << 8 | baro_dt[1]; |
kenjiArai | 0:9c1a7a1f0d97 | 108 | #if 0 |
kenjiArai | 0:9c1a7a1f0d97 | 109 | printf("temp_raw:0x%x\n\r",raw_temp); |
kenjiArai | 0:9c1a7a1f0d97 | 110 | #endif |
kenjiArai | 0:9c1a7a1f0d97 | 111 | // start pressure measurement |
kenjiArai | 0:9c1a7a1f0d97 | 112 | baro_dt[0] = BARO_CTRL_MEAS_REG; |
kenjiArai | 0:9c1a7a1f0d97 | 113 | baro_dt[1] = B_PRES_MEASURE_OSS3; |
kenjiArai | 4:37fed112956c | 114 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 2); |
kenjiArai | 0:9c1a7a1f0d97 | 115 | wait(0.3); // wait for convertion |
kenjiArai | 0:9c1a7a1f0d97 | 116 | // read pressure |
kenjiArai | 0:9c1a7a1f0d97 | 117 | baro_dt[0] = BARO_ADC_OUT_MSB_REG; |
kenjiArai | 4:37fed112956c | 118 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 1); |
kenjiArai | 4:37fed112956c | 119 | _i2c_read_n_bytes(BMP180_addr,baro_dt,3); |
kenjiArai | 0:9c1a7a1f0d97 | 120 | raw_pres = ( baro_dt[0] << 16 | baro_dt[1] << 8 | baro_dt[2] ) >> (8 - 3 ); |
kenjiArai | 0:9c1a7a1f0d97 | 121 | #if 0 |
kenjiArai | 0:9c1a7a1f0d97 | 122 | printf("pres_raw:0x%x\n\r",raw_pres); |
kenjiArai | 0:9c1a7a1f0d97 | 123 | #endif |
kenjiArai | 0:9c1a7a1f0d97 | 124 | // Normarization |
kenjiArai | 0:9c1a7a1f0d97 | 125 | // temperature |
kenjiArai | 0:9c1a7a1f0d97 | 126 | if ( id_number == BMP180_CHIP_ID ){ |
kenjiArai | 0:9c1a7a1f0d97 | 127 | dt_x1 = ( ( raw_temp - (int32_t)eep_ac6 ) * (int32_t)eep_ac5 ) >> 15; |
kenjiArai | 0:9c1a7a1f0d97 | 128 | dt_x2 = ( (int32_t)eep_mc << 11 ) / ( dt_x1 + (int32_t)eep_md ); |
kenjiArai | 0:9c1a7a1f0d97 | 129 | dt_b5 = dt_x1 + dt_x2; |
kenjiArai | 0:9c1a7a1f0d97 | 130 | } |
kenjiArai | 4:37fed112956c | 131 | temperature = (float)( ( dt_b5 + 8 ) >> 4 )/10.0f; // temperature in 0.1 degC |
kenjiArai | 0:9c1a7a1f0d97 | 132 | // Pressure |
kenjiArai | 0:9c1a7a1f0d97 | 133 | dt_b6 = dt_b5 - 4000; |
kenjiArai | 0:9c1a7a1f0d97 | 134 | dt_x1 = ( dt_b6 * dt_b6 ) >> 12; |
kenjiArai | 0:9c1a7a1f0d97 | 135 | dt_x1 *= eep_b2; |
kenjiArai | 0:9c1a7a1f0d97 | 136 | dt_x1 >>= 11; |
kenjiArai | 0:9c1a7a1f0d97 | 137 | dt_x2 = ( eep_ac2 * dt_b6 ); |
kenjiArai | 0:9c1a7a1f0d97 | 138 | dt_x2 >>= 11; |
kenjiArai | 0:9c1a7a1f0d97 | 139 | dt_x3 = dt_x1 + dt_x2; |
kenjiArai | 0:9c1a7a1f0d97 | 140 | dt_b3 = ( ((((long)eep_ac1) * 4 + dt_x3 ) << 3 ) + 2 ) >> 2; |
kenjiArai | 0:9c1a7a1f0d97 | 141 | dt_x1 = ( eep_ac3 * dt_b6 ) >> 13; |
kenjiArai | 0:9c1a7a1f0d97 | 142 | dt_x2 = ( eep_b1 * ( ( dt_b6 * dt_b6 ) >> 12 ) ) >> 16; |
kenjiArai | 0:9c1a7a1f0d97 | 143 | dt_x3 = ( ( dt_x1 + dt_x2 ) + 2 ) >> 2; |
kenjiArai | 0:9c1a7a1f0d97 | 144 | dt_b4 = ( eep_ac4 * (uint32_t)(dt_x3 + 32768)) >> 15; |
kenjiArai | 0:9c1a7a1f0d97 | 145 | dt_b7 = ( (uint32_t)( raw_pres - dt_b3 ) * ( 50000>> 3 ) ); |
kenjiArai | 0:9c1a7a1f0d97 | 146 | if (dt_b7 < 0x80000000){ |
kenjiArai | 0:9c1a7a1f0d97 | 147 | dx = (dt_b7 << 1) / dt_b4; |
kenjiArai | 0:9c1a7a1f0d97 | 148 | } else { |
kenjiArai | 0:9c1a7a1f0d97 | 149 | dx = (dt_b7 / dt_b4) << 1; |
kenjiArai | 0:9c1a7a1f0d97 | 150 | } |
kenjiArai | 0:9c1a7a1f0d97 | 151 | d = (long long int)dx; |
kenjiArai | 0:9c1a7a1f0d97 | 152 | d *= d; |
kenjiArai | 0:9c1a7a1f0d97 | 153 | dt_x1 = (int32_t)( d / 65536 ); |
kenjiArai | 0:9c1a7a1f0d97 | 154 | dt_x1 = ( dt_x1 * CONST_MG ) >> 16; |
kenjiArai | 0:9c1a7a1f0d97 | 155 | dt_x2 = ( CONST_MH * dx ) >> 16; |
kenjiArai | 0:9c1a7a1f0d97 | 156 | dt_x2 *= -1; |
kenjiArai | 0:9c1a7a1f0d97 | 157 | // pressure in Pa |
kenjiArai | 0:9c1a7a1f0d97 | 158 | dx += ( dt_x1 + dt_x2 + CONST_MI ) >> 4; |
kenjiArai | 4:37fed112956c | 159 | pressure = (float)dx / 100.0f; |
kenjiArai | 0:9c1a7a1f0d97 | 160 | } |
kenjiArai | 0:9c1a7a1f0d97 | 161 | |
kenjiArai | 0:9c1a7a1f0d97 | 162 | void BMP180::init () { |
kenjiArai | 0:9c1a7a1f0d97 | 163 | BMP180_addr = BMP180ADDR; |
kenjiArai | 0:9c1a7a1f0d97 | 164 | // parameters AC1-AC6 |
kenjiArai | 0:9c1a7a1f0d97 | 165 | baro_dt[0] = BARO_PROM_ADDR; |
kenjiArai | 4:37fed112956c | 166 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 1); |
kenjiArai | 4:37fed112956c | 167 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 168 | eep_ac1 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 169 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 170 | eep_ac2 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 171 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 172 | eep_ac3 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 173 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 174 | eep_ac4 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 175 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 176 | eep_ac5 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 177 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 178 | eep_ac6 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 0:9c1a7a1f0d97 | 179 | // parameters B1,B2 |
kenjiArai | 4:37fed112956c | 180 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 181 | eep_b1 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 182 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 183 | eep_b2 = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 0:9c1a7a1f0d97 | 184 | // parameters MB,MC,MD |
kenjiArai | 4:37fed112956c | 185 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 186 | eep_mb = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 187 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 188 | eep_mc = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 4:37fed112956c | 189 | _i2c_read_n_bytes(BMP180_addr,baro_dt,2); |
kenjiArai | 0:9c1a7a1f0d97 | 190 | eep_md = (baro_dt[0] << 8) | baro_dt[1]; |
kenjiArai | 0:9c1a7a1f0d97 | 191 | // Read ID |
kenjiArai | 0:9c1a7a1f0d97 | 192 | baro_dt[0] = BARO_CHIP_ID_REG; |
kenjiArai | 4:37fed112956c | 193 | _i2c_write_n_bytes(BMP180_addr, baro_dt, 1); |
kenjiArai | 4:37fed112956c | 194 | _i2c_read_n_bytes(BMP180_addr,baro_dt,1); |
kenjiArai | 0:9c1a7a1f0d97 | 195 | id_number = baro_dt[0]; |
kenjiArai | 0:9c1a7a1f0d97 | 196 | } |
kenjiArai | 0:9c1a7a1f0d97 | 197 | |
kenjiArai | 4:37fed112956c | 198 | void BMP180::_i2c_read_n_bytes (int addr, char* dt, int n) { |
kenjiArai | 4:37fed112956c | 199 | _i2c.read(addr, dt, n); |
kenjiArai | 0:9c1a7a1f0d97 | 200 | } |
kenjiArai | 0:9c1a7a1f0d97 | 201 | |
kenjiArai | 4:37fed112956c | 202 | void BMP180::_i2c_write_n_bytes (int addr, char* dt, int n) { |
kenjiArai | 4:37fed112956c | 203 | _i2c.write(addr, dt, n); |
kenjiArai | 0:9c1a7a1f0d97 | 204 | } |
kenjiArai | 4:37fed112956c | 205 |