Class for using BMP180 Bosch Pressure sensor

Dependents:   ILI9341_Clock_Nucleo IoT-Polytech-Upmc

Committer:
harrypowers
Date:
Tue Nov 26 19:56:05 2013 +0000
Revision:
2:4749ef781396
Parent:
1:4c6b41f1203d
Documentation updated and code is mostly final.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
harrypowers 0:b899fe37ce17 1 #include "BMP180.h"
harrypowers 0:b899fe37ce17 2
harrypowers 0:b899fe37ce17 3 BMP180::BMP180(PinName sda, PinName scl) : bmp180i2c(sda,scl)
harrypowers 0:b899fe37ce17 4 {
harrypowers 0:b899fe37ce17 5 bmp180i2c.frequency(BMP180FREQ);
harrypowers 0:b899fe37ce17 6 oversampling_setting = OVERSAMPLING_HIGH_RESOLUTION;
harrypowers 0:b899fe37ce17 7 rReg[0] = 0;
harrypowers 0:b899fe37ce17 8 rReg[1] = 0;
harrypowers 0:b899fe37ce17 9 rReg[2] = 0;
harrypowers 0:b899fe37ce17 10 wReg[0] = 0;
harrypowers 0:b899fe37ce17 11 wReg[1] = 0;
harrypowers 0:b899fe37ce17 12 w[0] = 0xF4;
harrypowers 0:b899fe37ce17 13 w[1] = 0xF4;
harrypowers 1:4c6b41f1203d 14
harrypowers 0:b899fe37ce17 15 cmd = CMD_READ_CALIBRATION; // EEPROM calibration command
harrypowers 0:b899fe37ce17 16 for (int i = 0; i < EEprom; i++) { // read the 22 registers of the EEPROM
harrypowers 0:b899fe37ce17 17 bmp180i2c.write(BMP180ADDR, &cmd, 1);
harrypowers 0:b899fe37ce17 18 bmp180i2c.read(BMP180ADDR, rReg, 1);
harrypowers 0:b899fe37ce17 19 data[i] = rReg[0];
harrypowers 0:b899fe37ce17 20 cmd += 1;
harrypowers 0:b899fe37ce17 21 wait_ms(10);
harrypowers 0:b899fe37ce17 22 }
harrypowers 0:b899fe37ce17 23
harrypowers 0:b899fe37ce17 24 // parameters AC1-AC6
harrypowers 0:b899fe37ce17 25 //The calibration is partioned in 11 words of 16 bits, each of them representing a coefficient
harrypowers 0:b899fe37ce17 26 ac1 = (data[0] <<8) | data[1]; // AC1(0xAA, 0xAB)... and so on
harrypowers 0:b899fe37ce17 27 ac2 = (data[2] <<8) | data[3];
harrypowers 0:b899fe37ce17 28 ac3 = (data[4] <<8) | data[5];
harrypowers 0:b899fe37ce17 29 ac4 = (data[6] <<8) | data[7];
harrypowers 0:b899fe37ce17 30 ac5 = (data[8] <<8) | data[9];
harrypowers 0:b899fe37ce17 31 ac6 = (data[10] <<8) | data[11];
harrypowers 0:b899fe37ce17 32 // parameters B1,B2
harrypowers 0:b899fe37ce17 33 b1 = (data[12] <<8) | data[13];
harrypowers 0:b899fe37ce17 34 b2 = (data[14] <<8) | data[15];
harrypowers 0:b899fe37ce17 35 // parameters MB,MC,MD
harrypowers 0:b899fe37ce17 36 mb = (data[16] <<8) | data[17];
harrypowers 0:b899fe37ce17 37 mc = (data[18] <<8) | data[19];
harrypowers 0:b899fe37ce17 38 md = (data[20] <<8) | data[21];
harrypowers 0:b899fe37ce17 39 }
harrypowers 0:b899fe37ce17 40
harrypowers 0:b899fe37ce17 41 BMP180::~BMP180()
harrypowers 0:b899fe37ce17 42 {
harrypowers 0:b899fe37ce17 43 }
harrypowers 0:b899fe37ce17 44
harrypowers 0:b899fe37ce17 45 int BMP180::startTemperature() // Start temperature measurement
harrypowers 0:b899fe37ce17 46 {
harrypowers 0:b899fe37ce17 47 int errors = 0;
harrypowers 0:b899fe37ce17 48 errors += bmp180i2c.write(BMP180ADDR, w, 2);
harrypowers 0:b899fe37ce17 49 wReg[0] = 0xF4;
harrypowers 0:b899fe37ce17 50 wReg[1] = 0x2E;
harrypowers 0:b899fe37ce17 51 errors += bmp180i2c.write(BMP180ADDR, wReg, 2); // write 0x2E in reg 0XF4
harrypowers 0:b899fe37ce17 52 return(errors);
harrypowers 0:b899fe37ce17 53 }
harrypowers 0:b899fe37ce17 54
harrypowers 0:b899fe37ce17 55 int BMP180::readTemperature(long *t) // Get the temperature reading that was taken in startTemperature() but ensure 4.5 ms time has elapsed
harrypowers 0:b899fe37ce17 56 {
harrypowers 0:b899fe37ce17 57 int errors = 0;
harrypowers 1:4c6b41f1203d 58 rReg[0] = 0;
harrypowers 1:4c6b41f1203d 59 rReg[1] = 0;
harrypowers 1:4c6b41f1203d 60 rReg[2] = 0;
harrypowers 0:b899fe37ce17 61 cmd = CMD_READ_VALUE; // 0xF6
harrypowers 0:b899fe37ce17 62 errors += bmp180i2c.write(BMP180ADDR, &cmd, 1); // set pointer on 0xF6 before reading it?
harrypowers 0:b899fe37ce17 63 errors += bmp180i2c.read(BMP180ADDR, rReg, 2); // read 0xF6 (MSB) and 0xF7 (LSB)// rReg is 3 long though
harrypowers 0:b899fe37ce17 64 *t = (rReg[0] << 8) | rReg[1]; // UT = MSB << 8 + LSB
harrypowers 1:4c6b41f1203d 65
harrypowers 1:4c6b41f1203d 66 x1 = (((long) *t - (long) ac6) * (long) ac5) >> 15; // aka (ut-ac6) * ac5/pow(2,15)
harrypowers 1:4c6b41f1203d 67 x2 = ((long) mc << 11) / (x1 + md); // aka mc * pow(2, 11) / (x1 + md)
harrypowers 1:4c6b41f1203d 68 b5 = x1 + x2;
harrypowers 1:4c6b41f1203d 69 *t = ((b5 + 8) >> 4); // (b5+8)/pow(2, 4)
harrypowers 0:b899fe37ce17 70 return(errors);
harrypowers 0:b899fe37ce17 71 }
harrypowers 0:b899fe37ce17 72
harrypowers 0:b899fe37ce17 73 int BMP180::startPressure(int oversample) // Start pressure measurement! Note oversample will vary the time to complete this measurement. See defines above for oversampling constants to use!
harrypowers 0:b899fe37ce17 74 {
harrypowers 0:b899fe37ce17 75 int errors = 0;
harrypowers 1:4c6b41f1203d 76 oversampling_setting = BMP180::oversampleCheck(oversample);
harrypowers 1:4c6b41f1203d 77 int uncomp_pressure_cmd = 0x34 + (oversampling_setting<<6);
harrypowers 0:b899fe37ce17 78 errors = bmp180i2c.write(BMP180ADDR, w, 2);
harrypowers 0:b899fe37ce17 79 wReg[0] = 0xF4;
harrypowers 0:b899fe37ce17 80 wReg[1] = uncomp_pressure_cmd;
harrypowers 0:b899fe37ce17 81 errors += bmp180i2c.write(BMP180ADDR, wReg, 2);
harrypowers 0:b899fe37ce17 82 return(errors);
harrypowers 0:b899fe37ce17 83 }
harrypowers 0:b899fe37ce17 84
harrypowers 1:4c6b41f1203d 85 int BMP180::readPressure(long *p) // Get the pressure reading that was taken in startPressure() but ensure time for the measurement to complete
harrypowers 0:b899fe37ce17 86 {
harrypowers 0:b899fe37ce17 87 int errors = 0;
harrypowers 1:4c6b41f1203d 88 rReg[0] = 0;
harrypowers 1:4c6b41f1203d 89 rReg[1] = 0;
harrypowers 1:4c6b41f1203d 90 rReg[2] = 0;
harrypowers 0:b899fe37ce17 91 cmd = CMD_READ_VALUE; // 0xF6
harrypowers 0:b899fe37ce17 92 errors += bmp180i2c.write(BMP180ADDR, &cmd, 1);
harrypowers 0:b899fe37ce17 93 errors += bmp180i2c.read(BMP180ADDR, rReg, 3); // read 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB)
harrypowers 0:b899fe37ce17 94 *p = ((rReg[0] << 16) | (rReg[1] << 8) | rReg[2]) >> (8 - oversampling_setting);
harrypowers 1:4c6b41f1203d 95
harrypowers 1:4c6b41f1203d 96 b6 = b5 - 4000; // realize b5 is set in readTemperature() function so that needs to be done first before this function!
harrypowers 1:4c6b41f1203d 97 x1 = (b6*b6) >> 12; // full formula(b2*(b6*b6)/pow(2,12))/pow(2,11)
harrypowers 1:4c6b41f1203d 98 x1 *= b2;
harrypowers 1:4c6b41f1203d 99 x1 >>= 11;
harrypowers 1:4c6b41f1203d 100
harrypowers 1:4c6b41f1203d 101 x2 = (ac2*b6);
harrypowers 1:4c6b41f1203d 102 x2 >>= 11;
harrypowers 1:4c6b41f1203d 103
harrypowers 1:4c6b41f1203d 104 x3 = x1 + x2;
harrypowers 1:4c6b41f1203d 105
harrypowers 1:4c6b41f1203d 106 b3 = (((((long)ac1 )*4 + x3) <<oversampling_setting) + 2) >> 2;
harrypowers 1:4c6b41f1203d 107
harrypowers 1:4c6b41f1203d 108 x1 = (ac3* b6) >> 13;
harrypowers 1:4c6b41f1203d 109 x2 = (b1 * ((b6*b6) >> 12) ) >> 16;
harrypowers 1:4c6b41f1203d 110 x3 = ((x1 + x2) + 2) >> 2;
harrypowers 1:4c6b41f1203d 111 b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
harrypowers 1:4c6b41f1203d 112
harrypowers 1:4c6b41f1203d 113 b7 = ((unsigned long) *p - b3) * (50000>>oversampling_setting);
harrypowers 1:4c6b41f1203d 114 if (b7 < 0x80000000) {
harrypowers 1:4c6b41f1203d 115 *p = (b7 << 1) / b4;
harrypowers 1:4c6b41f1203d 116 } else {
harrypowers 1:4c6b41f1203d 117 *p = (b7 / b4) << 1;
harrypowers 1:4c6b41f1203d 118 }
harrypowers 1:4c6b41f1203d 119
harrypowers 1:4c6b41f1203d 120 x1 = *p >> 8;
harrypowers 1:4c6b41f1203d 121 x1 *= x1; // pressure/pow(2,8) * pressure/pow(2, 8)
harrypowers 1:4c6b41f1203d 122 x1 = (x1 * 3038) >> 16;
harrypowers 1:4c6b41f1203d 123 x2 = ( *p * -7357) >> 16;
harrypowers 1:4c6b41f1203d 124 *p += (x1 + x2 + 3791) >> 4; // pressure in Pa
harrypowers 0:b899fe37ce17 125 return(errors);
harrypowers 0:b899fe37ce17 126 }
harrypowers 0:b899fe37ce17 127
harrypowers 1:4c6b41f1203d 128 int BMP180::readTP(long *t, long *p, int oversample) // get both temperature and pressure calculations that are compensated
harrypowers 0:b899fe37ce17 129 {
harrypowers 0:b899fe37ce17 130 int errors = 0;
harrypowers 1:4c6b41f1203d 131 errors += BMP180::startTemperature();
harrypowers 0:b899fe37ce17 132 wait_ms(4.5);
harrypowers 1:4c6b41f1203d 133 errors += BMP180::readTemperature(t);
harrypowers 1:4c6b41f1203d 134 errors += BMP180::startPressure(oversample);
harrypowers 1:4c6b41f1203d 135 switch (oversample) {
harrypowers 0:b899fe37ce17 136 case OVERSAMPLING_ULTRA_LOW_POWER:
harrypowers 0:b899fe37ce17 137 wait_ms(4.5);
harrypowers 0:b899fe37ce17 138 break;
harrypowers 0:b899fe37ce17 139 case OVERSAMPLING_STANDARD:
harrypowers 0:b899fe37ce17 140 wait_ms(7.5);
harrypowers 0:b899fe37ce17 141 break;
harrypowers 0:b899fe37ce17 142 case OVERSAMPLING_HIGH_RESOLUTION:
harrypowers 0:b899fe37ce17 143 wait_ms(13.5);
harrypowers 0:b899fe37ce17 144 break;
harrypowers 0:b899fe37ce17 145 case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
harrypowers 0:b899fe37ce17 146 wait_ms(25.5);
harrypowers 0:b899fe37ce17 147 break;
harrypowers 0:b899fe37ce17 148 }
harrypowers 1:4c6b41f1203d 149 errors += BMP180::readPressure(p);
harrypowers 0:b899fe37ce17 150 return(errors);
harrypowers 1:4c6b41f1203d 151 }
harrypowers 2:4749ef781396 152
harrypowers 1:4c6b41f1203d 153 int BMP180::oversampleCheck(int oversample)
harrypowers 0:b899fe37ce17 154 {
harrypowers 1:4c6b41f1203d 155 switch(oversample) {
harrypowers 0:b899fe37ce17 156 case OVERSAMPLING_ULTRA_LOW_POWER:
harrypowers 0:b899fe37ce17 157 break;
harrypowers 0:b899fe37ce17 158 case OVERSAMPLING_STANDARD:
harrypowers 0:b899fe37ce17 159 break;
harrypowers 0:b899fe37ce17 160 case OVERSAMPLING_HIGH_RESOLUTION:
harrypowers 0:b899fe37ce17 161 break;
harrypowers 0:b899fe37ce17 162 case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
harrypowers 1:4c6b41f1203d 163 break;
harrypowers 1:4c6b41f1203d 164 default:
harrypowers 1:4c6b41f1203d 165 oversample = OVERSAMPLING_ULTRA_HIGH_RESOLUTION;
harrypowers 0:b899fe37ce17 166 break;
harrypowers 0:b899fe37ce17 167 }
harrypowers 1:4c6b41f1203d 168 return(oversample);
harrypowers 0:b899fe37ce17 169 }