Library to control a BMP180 sensor.

BMP180 sensor

Committer:
Wosser1sProductions
Date:
Fri Aug 26 00:19:21 2016 +0000
Revision:
0:373de0f4d5cd
Child:
1:608e890e88e7
Updated BMP180 class library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wosser1sProductions 0:373de0f4d5cd 1 /*
Wosser1sProductions 0:373de0f4d5cd 2 @file BMP180.cpp
Wosser1sProductions 0:373de0f4d5cd 3 @brief Barometric Pressure and Temperature Sensor BMP180 Breakout I2C Library
Wosser1sProductions 0:373de0f4d5cd 4 */
Wosser1sProductions 0:373de0f4d5cd 5
Wosser1sProductions 0:373de0f4d5cd 6 #include "BMP180.h"
Wosser1sProductions 0:373de0f4d5cd 7
Wosser1sProductions 0:373de0f4d5cd 8 BMP180::BMP180(I2C& i2c) : m_i2c(i2c) {
Wosser1sProductions 0:373de0f4d5cd 9 m_altitude = 0;
Wosser1sProductions 0:373de0f4d5cd 10 m_oss = STANDARD;
Wosser1sProductions 0:373de0f4d5cd 11 }
Wosser1sProductions 0:373de0f4d5cd 12
Wosser1sProductions 0:373de0f4d5cd 13 int BMP180::initialize(float altitude, OverSamplingSetting oss) {
Wosser1sProductions 0:373de0f4d5cd 14 char data[22];
Wosser1sProductions 0:373de0f4d5cd 15 int errors = 0;
Wosser1sProductions 0:373de0f4d5cd 16
Wosser1sProductions 0:373de0f4d5cd 17 m_altitude = altitude;
Wosser1sProductions 0:373de0f4d5cd 18 m_oss = oss;
Wosser1sProductions 0:373de0f4d5cd 19
Wosser1sProductions 0:373de0f4d5cd 20 // read calibration data
Wosser1sProductions 0:373de0f4d5cd 21 data[0]=0xAA;
Wosser1sProductions 0:373de0f4d5cd 22 errors = m_i2c.write(BMP180_I2C_ADDRESS, data, 1); // set the eeprom pointer position to 0xAA
Wosser1sProductions 0:373de0f4d5cd 23 errors += m_i2c.read(BMP180_I2C_ADDRESS, data, 22); // read 11 x 16 bits at this position
Wosser1sProductions 0:373de0f4d5cd 24 wait_ms(10);
Wosser1sProductions 0:373de0f4d5cd 25
Wosser1sProductions 0:373de0f4d5cd 26 // store calibration data for further calculus
Wosser1sProductions 0:373de0f4d5cd 27 ac1 = data[0] << 8 | data[1];
Wosser1sProductions 0:373de0f4d5cd 28 ac2 = data[2] << 8 | data[3];
Wosser1sProductions 0:373de0f4d5cd 29 ac3 = data[4] << 8 | data[5];
Wosser1sProductions 0:373de0f4d5cd 30 ac4 = data[6] << 8 | data[7];
Wosser1sProductions 0:373de0f4d5cd 31 ac5 = data[8] << 8 | data[9];
Wosser1sProductions 0:373de0f4d5cd 32 ac6 = data[10] << 8 | data[11];
Wosser1sProductions 0:373de0f4d5cd 33 b1 = data[12] << 8 | data[13];
Wosser1sProductions 0:373de0f4d5cd 34 b2 = data[14] << 8 | data[15];
Wosser1sProductions 0:373de0f4d5cd 35 //mb = data[16] << 8 | data[17]; // Not used?
Wosser1sProductions 0:373de0f4d5cd 36 mc = data[18] << 8 | data[19];
Wosser1sProductions 0:373de0f4d5cd 37 md = data[20] << 8 | data[21];
Wosser1sProductions 0:373de0f4d5cd 38
Wosser1sProductions 0:373de0f4d5cd 39 // Pre-calc
Wosser1sProductions 0:373de0f4d5cd 40 ac1 = ac1 << 2;
Wosser1sProductions 0:373de0f4d5cd 41 mc = mc << 11;
Wosser1sProductions 0:373de0f4d5cd 42
Wosser1sProductions 0:373de0f4d5cd 43 return errors == 0; // 0 = ACK = success
Wosser1sProductions 0:373de0f4d5cd 44 }
Wosser1sProductions 0:373de0f4d5cd 45
Wosser1sProductions 0:373de0f4d5cd 46 int BMP180::ReadData(float& pTemperature, float& pPressure) {
Wosser1sProductions 0:373de0f4d5cd 47 long t, p;
Wosser1sProductions 0:373de0f4d5cd 48
Wosser1sProductions 0:373de0f4d5cd 49 if (!ReadRawTemperature(&t) || !ReadRawPressure(&p))
Wosser1sProductions 0:373de0f4d5cd 50 return 0; // Error
Wosser1sProductions 0:373de0f4d5cd 51
Wosser1sProductions 0:373de0f4d5cd 52 pTemperature = TrueTemperature(t);
Wosser1sProductions 0:373de0f4d5cd 53 pPressure = TruePressure(p);
Wosser1sProductions 0:373de0f4d5cd 54
Wosser1sProductions 0:373de0f4d5cd 55 return 1;
Wosser1sProductions 0:373de0f4d5cd 56 }
Wosser1sProductions 0:373de0f4d5cd 57
Wosser1sProductions 0:373de0f4d5cd 58 int BMP180::ReadRawTemperature(long* pUt) {
Wosser1sProductions 0:373de0f4d5cd 59 int errors = 0;
Wosser1sProductions 0:373de0f4d5cd 60
Wosser1sProductions 0:373de0f4d5cd 61 // request temperature measurement
Wosser1sProductions 0:373de0f4d5cd 62 m_data[0] = 0xF4;
Wosser1sProductions 0:373de0f4d5cd 63 m_data[1] = 0x2E;
Wosser1sProductions 0:373de0f4d5cd 64 errors = m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // write 0XF2 into reg 0XF4
Wosser1sProductions 0:373de0f4d5cd 65
Wosser1sProductions 0:373de0f4d5cd 66 wait_ms(5);
Wosser1sProductions 0:373de0f4d5cd 67
Wosser1sProductions 0:373de0f4d5cd 68 // read raw temperature data
Wosser1sProductions 0:373de0f4d5cd 69 m_data[0] = 0xF6;
Wosser1sProductions 0:373de0f4d5cd 70 errors += m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // set eeprom pointer position to 0XF6
Wosser1sProductions 0:373de0f4d5cd 71 errors += m_i2c.read(BMP180_I2C_ADDRESS, m_data, 2); // get 16 bits at this position
Wosser1sProductions 0:373de0f4d5cd 72
Wosser1sProductions 0:373de0f4d5cd 73 if (errors) return 0;
Wosser1sProductions 0:373de0f4d5cd 74 *pUt = m_data[0] << 8 | m_data[1];
Wosser1sProductions 0:373de0f4d5cd 75
Wosser1sProductions 0:373de0f4d5cd 76 return 1;
Wosser1sProductions 0:373de0f4d5cd 77 }
Wosser1sProductions 0:373de0f4d5cd 78
Wosser1sProductions 0:373de0f4d5cd 79 int BMP180::ReadRawPressure(long* pUp) {
Wosser1sProductions 0:373de0f4d5cd 80 int errors = 0;
Wosser1sProductions 0:373de0f4d5cd 81
Wosser1sProductions 0:373de0f4d5cd 82 // request pressure measurement
Wosser1sProductions 0:373de0f4d5cd 83 m_data[0] = 0xF4;
Wosser1sProductions 0:373de0f4d5cd 84 m_data[1] = 0x34 + (m_oss << 6);
Wosser1sProductions 0:373de0f4d5cd 85 errors = m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // write 0x34 + (m_oss << 6) into reg 0XF4
Wosser1sProductions 0:373de0f4d5cd 86
Wosser1sProductions 0:373de0f4d5cd 87 switch (m_oss) { // Rounded up wait times to be safe
Wosser1sProductions 0:373de0f4d5cd 88 case ULTRA_LOW_POWER: wait_ms(5); break;
Wosser1sProductions 0:373de0f4d5cd 89 case STANDARD: wait_ms(8); break;
Wosser1sProductions 0:373de0f4d5cd 90 case HIGH_RESOLUTION: wait_ms(14); break;
Wosser1sProductions 0:373de0f4d5cd 91 case ULTRA_HIGH_RESOLUTION: wait_ms(26); break;
Wosser1sProductions 0:373de0f4d5cd 92 }
Wosser1sProductions 0:373de0f4d5cd 93
Wosser1sProductions 0:373de0f4d5cd 94 // read raw pressure data
Wosser1sProductions 0:373de0f4d5cd 95 m_data[0] = 0xF6;
Wosser1sProductions 0:373de0f4d5cd 96 errors += m_i2c.write(BMP180_I2C_ADDRESS, m_data, 1); // set eeprom pointer position to 0XF6
Wosser1sProductions 0:373de0f4d5cd 97 errors += m_i2c.read(BMP180_I2C_ADDRESS, m_data, 2); // get 16 bits at this position
Wosser1sProductions 0:373de0f4d5cd 98
Wosser1sProductions 0:373de0f4d5cd 99 if (errors) return 0;
Wosser1sProductions 0:373de0f4d5cd 100 *pUp = (m_data[0] << 16 | m_data[1] << 8) >> (8 - m_oss);
Wosser1sProductions 0:373de0f4d5cd 101
Wosser1sProductions 0:373de0f4d5cd 102 return 1;
Wosser1sProductions 0:373de0f4d5cd 103 }
Wosser1sProductions 0:373de0f4d5cd 104
Wosser1sProductions 0:373de0f4d5cd 105 float BMP180::TrueTemperature(long ut) {
Wosser1sProductions 0:373de0f4d5cd 106 // straight out from the documentation
Wosser1sProductions 0:373de0f4d5cd 107 x1 = ((ut - ac6) * ac5) >> 15;
Wosser1sProductions 0:373de0f4d5cd 108 x2 = mc / (x1 + md);
Wosser1sProductions 0:373de0f4d5cd 109 b5 = x1 + x2;
Wosser1sProductions 0:373de0f4d5cd 110
Wosser1sProductions 0:373de0f4d5cd 111 // convert to Celsius
Wosser1sProductions 0:373de0f4d5cd 112 return (long)((b5 + 8) >> 4) / 10.F;
Wosser1sProductions 0:373de0f4d5cd 113 }
Wosser1sProductions 0:373de0f4d5cd 114
Wosser1sProductions 0:373de0f4d5cd 115 float BMP180::TruePressure(long up) {
Wosser1sProductions 0:373de0f4d5cd 116 long p;
Wosser1sProductions 0:373de0f4d5cd 117
Wosser1sProductions 0:373de0f4d5cd 118 // straight out from the documentation
Wosser1sProductions 0:373de0f4d5cd 119 b6 = b5 - 4000;
Wosser1sProductions 0:373de0f4d5cd 120 x1 = (b2 * (b6 * b6 >> 12)) >> 11;
Wosser1sProductions 0:373de0f4d5cd 121 x2 = ac2 * b6 >> 11;
Wosser1sProductions 0:373de0f4d5cd 122 b3 = (((ac1 + x1 + x2) << m_oss) + 2) >> 2;
Wosser1sProductions 0:373de0f4d5cd 123 x1 = (ac3 * b6) >> 13;
Wosser1sProductions 0:373de0f4d5cd 124 x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
Wosser1sProductions 0:373de0f4d5cd 125 x3 = (x1 + x2 + 2) >> 2;
Wosser1sProductions 0:373de0f4d5cd 126 b4 = ac4 * (unsigned long)(x3 + 32768) >> 15;
Wosser1sProductions 0:373de0f4d5cd 127 b7 = ((unsigned long)up - b3)* (50000 >> m_oss);
Wosser1sProductions 0:373de0f4d5cd 128 if (b7 < 0x80000000) p = (b7 << 1) / b4;
Wosser1sProductions 0:373de0f4d5cd 129 else p = (b7 / b4) << 1;
Wosser1sProductions 0:373de0f4d5cd 130 x1 = (p >> 8) * (p >> 8);
Wosser1sProductions 0:373de0f4d5cd 131 x1 = (x1 * 3038) >> 16;
Wosser1sProductions 0:373de0f4d5cd 132 x2 = (-7357 * p) >> 16;
Wosser1sProductions 0:373de0f4d5cd 133 p = p + ((x1 + x2 + 3791) >> 4);
Wosser1sProductions 0:373de0f4d5cd 134
Wosser1sProductions 0:373de0f4d5cd 135 // convert to hPa and, if altitude has been initialized, to sea level pressure
Wosser1sProductions 0:373de0f4d5cd 136 return (m_altitude == 0.F) ? p / 100.F
Wosser1sProductions 0:373de0f4d5cd 137 : p / (100.F * pow((1.F - m_altitude / 44330.0L), 5.255L));
Wosser1sProductions 0:373de0f4d5cd 138 }