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