Class for using BMP180 Bosch Pressure sensor
Dependents: ILI9341_Clock_Nucleo IoT-Polytech-Upmc
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 }
Generated on Tue Jul 26 2022 21:55:39 by 1.7.2