Class for using BMP180 Bosch Pressure sensor

Dependents:   ILI9341_Clock_Nucleo IoT-Polytech-Upmc

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP180.cpp Source File

BMP180.cpp

00001 #include "BMP180.h"
00002 
00003 BMP180::BMP180(PinName sda, PinName scl) : bmp180i2c(sda,scl)
00004 {
00005     bmp180i2c.frequency(BMP180FREQ);
00006     oversampling_setting = OVERSAMPLING_HIGH_RESOLUTION;
00007     rReg[0] = 0;
00008     rReg[1] = 0;
00009     rReg[2] = 0;
00010     wReg[0] = 0;
00011     wReg[1] = 0;
00012     w[0] = 0xF4;
00013     w[1] = 0xF4;
00014 
00015     cmd = CMD_READ_CALIBRATION; // EEPROM calibration command
00016     for (int i = 0; i < EEprom; i++) { // read the 22 registers of the EEPROM
00017         bmp180i2c.write(BMP180ADDR, &cmd, 1);
00018         bmp180i2c.read(BMP180ADDR, rReg, 1);
00019         data[i] = rReg[0];
00020         cmd += 1;
00021         wait_ms(10);
00022     }
00023 
00024     // parameters AC1-AC6
00025     //The calibration is partioned in 11 words of 16 bits, each of them representing a coefficient
00026     ac1 =  (data[0] <<8) | data[1]; // AC1(0xAA, 0xAB)... and so on
00027     ac2 =  (data[2] <<8) | data[3];
00028     ac3 =  (data[4] <<8) | data[5];
00029     ac4 =  (data[6] <<8) | data[7];
00030     ac5 =  (data[8] <<8) | data[9];
00031     ac6 = (data[10] <<8) | data[11];
00032     // parameters B1,B2
00033     b1 =  (data[12] <<8) | data[13];
00034     b2 =  (data[14] <<8) | data[15];
00035     // parameters MB,MC,MD
00036     mb =  (data[16] <<8) | data[17];
00037     mc =  (data[18] <<8) | data[19];
00038     md =  (data[20] <<8) | data[21];
00039 }
00040 
00041 BMP180::~BMP180()
00042 {
00043 }
00044 
00045 int BMP180::startTemperature()              // Start temperature measurement
00046 {
00047     int errors = 0;
00048     errors += bmp180i2c.write(BMP180ADDR, w, 2);
00049     wReg[0] = 0xF4;
00050     wReg[1] = 0x2E;
00051     errors += bmp180i2c.write(BMP180ADDR, wReg, 2);   // write 0x2E in reg 0XF4
00052     return(errors);
00053 }
00054 
00055 int BMP180::readTemperature(long *t)        // Get the temperature reading that was taken in startTemperature() but ensure 4.5 ms time has elapsed
00056 {
00057     int errors = 0;
00058     rReg[0] = 0;
00059     rReg[1] = 0;
00060     rReg[2] = 0;
00061     cmd = CMD_READ_VALUE;                           // 0xF6
00062     errors += bmp180i2c.write(BMP180ADDR, &cmd, 1); // set pointer on 0xF6 before reading it?
00063     errors += bmp180i2c.read(BMP180ADDR, rReg, 2);  // read 0xF6 (MSB) and 0xF7 (LSB)// rReg is 3 long though
00064     *t = (rReg[0] << 8) | rReg[1];                  // UT = MSB << 8 + LSB
00065     
00066     x1 = (((long) *t - (long) ac6) * (long) ac5) >> 15; // aka (ut-ac6) * ac5/pow(2,15)
00067     x2 = ((long) mc << 11) / (x1 + md);                 // aka mc * pow(2, 11) / (x1 + md)
00068     b5 = x1 + x2;
00069     *t = ((b5 + 8) >> 4);                               // (b5+8)/pow(2, 4)
00070     return(errors);
00071 }
00072 
00073 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!
00074 {
00075     int errors = 0;
00076     oversampling_setting = BMP180::oversampleCheck(oversample);
00077     int uncomp_pressure_cmd = 0x34 + (oversampling_setting<<6);
00078     errors = bmp180i2c.write(BMP180ADDR, w, 2);
00079     wReg[0] = 0xF4;
00080     wReg[1] = uncomp_pressure_cmd;
00081     errors += bmp180i2c.write(BMP180ADDR, wReg, 2);
00082     return(errors);
00083 }
00084 
00085 int BMP180::readPressure(long *p)   // Get the pressure reading that was taken in startPressure() but ensure time for the measurement to complete
00086 {
00087     int errors = 0;
00088     rReg[0] = 0;
00089     rReg[1] = 0;
00090     rReg[2] = 0;
00091     cmd = CMD_READ_VALUE;                           // 0xF6
00092     errors += bmp180i2c.write(BMP180ADDR, &cmd, 1);
00093     errors += bmp180i2c.read(BMP180ADDR, rReg, 3);  // read 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB)
00094     *p = ((rReg[0] << 16) | (rReg[1] << 8) | rReg[2]) >> (8 - oversampling_setting);
00095     
00096     b6 = b5 - 4000;             // realize b5 is set in readTemperature() function so that needs to be done first before this function! 
00097     x1 = (b6*b6) >> 12;         // full formula(b2*(b6*b6)/pow(2,12))/pow(2,11)
00098     x1 *= b2;
00099     x1 >>= 11;
00100 
00101     x2 = (ac2*b6);
00102     x2 >>= 11;
00103 
00104     x3 = x1 + x2;
00105 
00106     b3 = (((((long)ac1 )*4 + x3) <<oversampling_setting) + 2) >> 2; 
00107 
00108     x1 = (ac3* b6) >> 13;
00109     x2 = (b1 * ((b6*b6) >> 12) ) >> 16;
00110     x3 = ((x1 + x2) + 2) >> 2;
00111     b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
00112 
00113     b7 = ((unsigned long) *p - b3) * (50000>>oversampling_setting);
00114     if (b7 < 0x80000000) {
00115         *p = (b7 << 1) / b4;
00116     } else {
00117         *p = (b7 / b4) << 1;
00118     }
00119 
00120     x1 = *p >> 8;
00121     x1 *= x1;                               // pressure/pow(2,8) * pressure/pow(2, 8)
00122     x1 = (x1 * 3038) >> 16;
00123     x2 = ( *p * -7357) >> 16;
00124     *p += (x1 + x2 + 3791) >> 4;            // pressure in Pa
00125     return(errors);
00126 }
00127 
00128 int BMP180::readTP(long *t, long *p, int oversample)  // get both temperature and pressure calculations that are compensated
00129 {
00130     int errors = 0;
00131     errors += BMP180::startTemperature();
00132     wait_ms(4.5);
00133     errors += BMP180::readTemperature(t);
00134     errors += BMP180::startPressure(oversample);
00135     switch (oversample) {
00136         case OVERSAMPLING_ULTRA_LOW_POWER:
00137             wait_ms(4.5);
00138             break;
00139         case OVERSAMPLING_STANDARD:
00140             wait_ms(7.5);
00141             break;
00142         case OVERSAMPLING_HIGH_RESOLUTION:
00143             wait_ms(13.5);
00144             break;
00145         case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
00146             wait_ms(25.5);
00147             break;
00148     }
00149     errors += BMP180::readPressure(p);
00150     return(errors);
00151 }
00152 
00153 int BMP180::oversampleCheck(int oversample)
00154 {
00155     switch(oversample) {
00156         case OVERSAMPLING_ULTRA_LOW_POWER:
00157             break;
00158         case OVERSAMPLING_STANDARD:
00159             break;
00160         case OVERSAMPLING_HIGH_RESOLUTION:
00161             break;
00162         case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
00163             break;
00164         default:
00165             oversample = OVERSAMPLING_ULTRA_HIGH_RESOLUTION;
00166             break;
00167     }
00168     return(oversample);
00169 }