Library to control a BMP180 sensor.
BMP180.cpp@1:608e890e88e7, 2016-08-28 (annotated)
- Committer:
- Wosser1sProductions
- Date:
- Sun Aug 28 23:28:03 2016 +0000
- Revision:
- 1:608e890e88e7
- Parent:
- 0:373de0f4d5cd
Fixed calibration values not being stored correctly.
Who changed what in which revision?
User | Revision | Line number | New 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 | 1:608e890e88e7 | 41 | mc = (0xFFFF0000 | mc) << 11; // D1F6 << 11 == 0xFE8FB000 niet 0X68FB000 |
Wosser1sProductions | 0:373de0f4d5cd | 42 | |
Wosser1sProductions | 0:373de0f4d5cd | 43 | return errors == 0; // 0 = ACK = success |
Wosser1sProductions | 0:373de0f4d5cd | 44 | } |
Wosser1sProductions | 0:373de0f4d5cd | 45 | |
Wosser1sProductions | 1:608e890e88e7 | 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 | 1:608e890e88e7 | 107 | |
Wosser1sProductions | 0:373de0f4d5cd | 108 | x1 = ((ut - ac6) * ac5) >> 15; |
Wosser1sProductions | 1:608e890e88e7 | 109 | b5 = x1 + (mc / (x1 + md)); |
Wosser1sProductions | 0:373de0f4d5cd | 110 | |
Wosser1sProductions | 0:373de0f4d5cd | 111 | // convert to Celsius |
Wosser1sProductions | 1:608e890e88e7 | 112 | return ((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 | } |