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

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?

UserRevisionLine numberNew 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 }