Class for using BMP180 Bosch Pressure sensor
Dependents: ILI9341_Clock_Nucleo IoT-Polytech-Upmc
BMP180.cpp@2:4749ef781396, 2013-11-26 (annotated)
- 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?
User | Revision | Line number | New 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 | } |