Leon Wehmeier / Mbed OS fiasco_max32630

Dependencies:   SoftSerial MAX14690 Buffer

Fork of rtos_threading_with_callback by mbed_example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP180.cpp Source File

BMP180.cpp

00001 /*
00002   @file BMP180.cpp
00003 
00004   @brief Barometric Pressure and Temperature Sensor BMP180 Breakout I2C Library
00005 
00006   @Author spiridion (http://mailme.spiridion.net)
00007 
00008   Tested on LPC1768 and FRDM-KL25Z
00009 
00010   Copyright (c) 2014 spiridion
00011   Released under the MIT License (see http://mbed.org/license/mit)
00012 
00013   Documentation regarding the BMP180 can be found here:
00014   http://mbed.org/media/uploads/spiridion/bst-bmp180-ds000-09.pdf
00015 */
00016 
00017 #include "BMP180.h"
00018 #include "mbed.h"
00019 
00020 
00021 BMP180::BMP180(I2C *i2c, int address)
00022    : m_i2c(i2c), m_addr(address)
00023 {
00024     m_altitude = 0;
00025     m_oss = BMP180_OSS_NORMAL; 
00026     m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
00027     m_pressure = UNSET_BMP180_PRESSURE_VALUE;  
00028 }
00029 
00030 double BMP180::ReadAltitude(double sealevelPressure)
00031 {
00032     m_altitude = 44330 * (1.0 - pow(m_pressure /sealevelPressure,0.1903));
00033     return m_altitude;
00034 }
00035 int  BMP180::Initialize(float altitude, int overSamplingSetting)
00036 {
00037     char data[22];
00038     int errors = 0;
00039         
00040     m_altitude = altitude;
00041     m_oss = overSamplingSetting; 
00042     m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
00043     m_pressure = UNSET_BMP180_PRESSURE_VALUE;  
00044     
00045     // read calibration data
00046     data[0]=0xAA;
00047     errors = m_i2c->write(m_addr, data, 1);  // set the eeprom pointer position to 0xAA
00048     errors += m_i2c->read(m_addr, data, 22); // read 11 x 16 bits at this position 
00049     wait_ms(10);
00050     
00051     // store calibration data for further calculus  
00052     ac1 = data[0]  << 8 | data[1];
00053     ac2 = data[2]  << 8 | data[3];
00054     ac3 = data[4]  << 8 | data[5];
00055     ac4 = data[6]  << 8 | data[7];
00056     ac5 = data[8]  << 8 | data[9];
00057     ac6 = data[10] << 8 | data[11];
00058     b1  = data[12] << 8 | data[13];
00059     b2  = data[14] << 8 | data[15];
00060     mb  = data[16] << 8 | data[17];
00061     mc  = data[18] << 8 | data[19];
00062     md  = data[20] << 8 | data[21];
00063 
00064 #ifdef BMP180_TEST_FORMULA
00065     ac1 = 408;
00066     ac2 = -72;
00067     ac3 = -14383;
00068     ac4 = 32741;
00069     ac5 = 32757;
00070     ac6 = 23153;
00071     b1 = 6190;
00072     b2 = 4;
00073     mb = -32768;
00074     mc = -8711;
00075     md = 2868;
00076     m_oss = 0;
00077     errors = 0;
00078 #endif // #ifdef BMP180_TEST_FORMULA
00079 
00080     return errors? 0 : 1;
00081 }
00082 
00083 int BMP180::ReadData(float* pTemperature, float* pPressure)
00084 {
00085     long t, p;
00086 
00087     if (!ReadRawTemperature(&t) || !ReadRawPressure(&p))
00088     {
00089         m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
00090         m_pressure = UNSET_BMP180_PRESSURE_VALUE;  
00091         return 0;
00092     }
00093 
00094     m_temperature = TrueTemperature(t);
00095     m_pressure = TruePressure(p);
00096 
00097     if (pPressure)
00098         *pPressure = m_pressure;
00099     if (pTemperature)
00100         *pTemperature = m_temperature;
00101 
00102     return 1;
00103 }
00104 
00105 int BMP180::ReadRawTemperature(long* pUt)
00106 {
00107     int errors = 0;
00108     char data[2];
00109     
00110     // request temperature measurement
00111     data[0] = 0xF4;
00112     data[1] = 0x2E;
00113     errors = m_i2c->write(m_addr, data, 2); // write 0XF2 into reg 0XF4
00114 
00115     wait_ms(4.5F);
00116 
00117     // read raw temperature data
00118     data[0] = 0xF6;
00119     errors += m_i2c->write(m_addr, data, 2); // set eeprom pointer position to 0XF6
00120     errors += m_i2c->read(m_addr, data, 2);  // get 16 bits at this position 
00121     
00122 #ifdef BMP180_TEST_FORMULA
00123     errors = 0;
00124 #endif // #ifdef BMP180_TEST_FORMULA
00125 
00126     if (errors)
00127         return 0;
00128     else
00129         *pUt = data[0] << 8 | data[1];
00130 
00131 #ifdef BMP180_TEST_FORMULA
00132     *pUt = 27898;
00133 #endif // #ifdef BMP180_TEST_FORMULA
00134     
00135     return 1;
00136 }
00137 
00138 int BMP180::ReadRawPressure(long* pUp)
00139 {
00140     int errors = 0;
00141     char data[2];
00142     
00143     // request pressure measurement
00144     data[0] = 0xF4;
00145     data[1] = 0x34 + (m_oss << 6);
00146     errors = m_i2c->write(m_addr, data, 2); // write 0x34 + (m_oss << 6) into reg 0XF4
00147 
00148     switch (m_oss)
00149     {
00150         case BMP180_OSS_ULTRA_LOW_POWER:        wait_ms(4.5); break;
00151         case BMP180_OSS_NORMAL:                 wait_ms(7.5); break;
00152         case BMP180_OSS_HIGH_RESOLUTION:        wait_ms(13.5); break;
00153         case BMP180_OSS_ULTRA_HIGH_RESOLUTION:  wait_ms(25.5); break;
00154     }
00155 
00156     // read raw pressure data
00157     data[0] = 0xF6;
00158     errors += m_i2c->write(m_addr, data, 1); // set eeprom pointer position to 0XF6
00159     errors += m_i2c->read(m_addr, data, 2);  // get 16 bits at this position     
00160     
00161 #ifdef BMP180_TEST_FORMULA
00162     errors = 0;
00163 #endif // #ifdef BMP180_TEST_FORMULA
00164 
00165     if (errors)
00166         return 0;
00167     else
00168         *pUp = (data[0] << 16 | data[1] << 8) >> (8 - m_oss);
00169 #ifdef BMP180_TEST_FORMULA
00170         *pUp = 23843;
00171 #endif // #ifdef BMP180_TEST_FORMULA
00172 
00173     return 1;
00174 }
00175 
00176 float BMP180::TrueTemperature(long ut)
00177 {
00178     long t;
00179     
00180     // straight out from the documentation
00181     x1 = ((ut - ac6) * ac5) >> 15;
00182     x2 = ((long)mc << 11) / (x1 + md);
00183     b5 = x1 + x2;
00184     t = (b5 + 8) >> 4;
00185 
00186     // convert to celcius
00187     return t / 10.F;
00188 }
00189 
00190 float BMP180::TruePressure(long up)
00191 {
00192     long p;
00193     
00194     // straight out from the documentation
00195     b6 = b5 - 4000;
00196     x1 = (b2 * (b6 * b6 >> 12)) >> 11;
00197     x2 = ac2 * b6 >> 11;
00198     x3 = x1 + x2;
00199     b3 = (((ac1 * 4 + x3) << m_oss) + 2) >> 2;
00200     x1 = (ac3 * b6) >> 13;
00201     x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
00202     x3 = ((x1 + x2) + 2) >> 2;
00203     b4 = ac4 * (unsigned long)(x3 + 32768) >> 15;
00204     b7 = ((unsigned long)up - b3)* (50000 >> m_oss);
00205     if (b7 < 0x80000000)
00206         p = (b7 << 1) / b4;
00207     else
00208         p = (b7 / b4) << 1;
00209     x1 = (p >> 8) * (p >> 8);
00210     x1 = (x1 * 3038) >> 16;
00211     x2 = (-7357 * p) >> 16;
00212     p = p + ((x1 + x2 + 3791) >> 4);
00213 
00214     // convert to hPa and, if altitude has been initialized, to sea level pressure  
00215     //if (m_altitude == 0.F)
00216         return p / 100.F;
00217     //else
00218     //    return  p / (100.F * pow((1.F - m_altitude / 44330.0L), 5.255L)); 
00219 }