ロケット用プログラム
Dependencies: mbed
BMP180/BMP180.cpp@0:d58274531d38, 2019-09-11 (annotated)
- Committer:
- ishiyamayuto
- Date:
- Wed Sep 11 06:37:20 2019 +0000
- Revision:
- 0:d58274531d38
BMP180,MPU6050
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ishiyamayuto | 0:d58274531d38 | 1 | /* |
ishiyamayuto | 0:d58274531d38 | 2 | @file BMP180.cpp |
ishiyamayuto | 0:d58274531d38 | 3 | |
ishiyamayuto | 0:d58274531d38 | 4 | @brief Barometric Pressure and Temperature Sensor BMP180 Breakout I2C Library |
ishiyamayuto | 0:d58274531d38 | 5 | |
ishiyamayuto | 0:d58274531d38 | 6 | @Author spiridion (http://mailme.spiridion.net) |
ishiyamayuto | 0:d58274531d38 | 7 | |
ishiyamayuto | 0:d58274531d38 | 8 | Tested on LPC1768 and FRDM-KL25Z |
ishiyamayuto | 0:d58274531d38 | 9 | |
ishiyamayuto | 0:d58274531d38 | 10 | Copyright (c) 2014 spiridion |
ishiyamayuto | 0:d58274531d38 | 11 | Released under the MIT License (see http://mbed.org/license/mit) |
ishiyamayuto | 0:d58274531d38 | 12 | |
ishiyamayuto | 0:d58274531d38 | 13 | Documentation regarding the BMP180 can be found here: |
ishiyamayuto | 0:d58274531d38 | 14 | http://mbed.org/media/uploads/spiridion/bst-bmp180-ds000-09.pdf |
ishiyamayuto | 0:d58274531d38 | 15 | */ |
ishiyamayuto | 0:d58274531d38 | 16 | |
ishiyamayuto | 0:d58274531d38 | 17 | #include "BMP180.h" |
ishiyamayuto | 0:d58274531d38 | 18 | #include "mbed.h" |
ishiyamayuto | 0:d58274531d38 | 19 | |
ishiyamayuto | 0:d58274531d38 | 20 | // Uncomment to test the documentation algorithm against the documentation example |
ishiyamayuto | 0:d58274531d38 | 21 | // Result should be 699.64 hPa and 15°C |
ishiyamayuto | 0:d58274531d38 | 22 | // #define BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 23 | |
ishiyamayuto | 0:d58274531d38 | 24 | BMP180::BMP180(PinName sda, PinName scl, int address) |
ishiyamayuto | 0:d58274531d38 | 25 | : m_i2c(sda,scl), m_addr(address) |
ishiyamayuto | 0:d58274531d38 | 26 | { |
ishiyamayuto | 0:d58274531d38 | 27 | m_altitude = 0; |
ishiyamayuto | 0:d58274531d38 | 28 | m_oss = BMP180_OSS_NORMAL; |
ishiyamayuto | 0:d58274531d38 | 29 | m_temperature = UNSET_BMP180_TEMPERATURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 30 | m_pressure = UNSET_BMP180_PRESSURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 31 | } |
ishiyamayuto | 0:d58274531d38 | 32 | |
ishiyamayuto | 0:d58274531d38 | 33 | BMP180::BMP180(I2C& i2c, int address) |
ishiyamayuto | 0:d58274531d38 | 34 | : m_i2c(i2c), m_addr(address) |
ishiyamayuto | 0:d58274531d38 | 35 | { |
ishiyamayuto | 0:d58274531d38 | 36 | m_altitude = 0; |
ishiyamayuto | 0:d58274531d38 | 37 | m_oss = BMP180_OSS_NORMAL; |
ishiyamayuto | 0:d58274531d38 | 38 | m_temperature = UNSET_BMP180_TEMPERATURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 39 | m_pressure = UNSET_BMP180_PRESSURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 40 | } |
ishiyamayuto | 0:d58274531d38 | 41 | |
ishiyamayuto | 0:d58274531d38 | 42 | int BMP180::Initialize(float altitude, int overSamplingSetting) |
ishiyamayuto | 0:d58274531d38 | 43 | { |
ishiyamayuto | 0:d58274531d38 | 44 | char data[22]; |
ishiyamayuto | 0:d58274531d38 | 45 | int errors = 0; |
ishiyamayuto | 0:d58274531d38 | 46 | |
ishiyamayuto | 0:d58274531d38 | 47 | m_altitude = altitude; |
ishiyamayuto | 0:d58274531d38 | 48 | m_oss = overSamplingSetting; |
ishiyamayuto | 0:d58274531d38 | 49 | m_temperature = UNSET_BMP180_TEMPERATURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 50 | m_pressure = UNSET_BMP180_PRESSURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 51 | |
ishiyamayuto | 0:d58274531d38 | 52 | // read calibration data |
ishiyamayuto | 0:d58274531d38 | 53 | data[0]=0xAA; |
ishiyamayuto | 0:d58274531d38 | 54 | errors = m_i2c.write(m_addr, data, 1); // set the eeprom pointer position to 0xAA |
ishiyamayuto | 0:d58274531d38 | 55 | errors += m_i2c.read(m_addr, data, 22); // read 11 x 16 bits at this position |
ishiyamayuto | 0:d58274531d38 | 56 | wait_ms(10); |
ishiyamayuto | 0:d58274531d38 | 57 | |
ishiyamayuto | 0:d58274531d38 | 58 | // store calibration data for further calculus |
ishiyamayuto | 0:d58274531d38 | 59 | ac1 = data[0] << 8 | data[1]; |
ishiyamayuto | 0:d58274531d38 | 60 | ac2 = data[2] << 8 | data[3]; |
ishiyamayuto | 0:d58274531d38 | 61 | ac3 = data[4] << 8 | data[5]; |
ishiyamayuto | 0:d58274531d38 | 62 | ac4 = data[6] << 8 | data[7]; |
ishiyamayuto | 0:d58274531d38 | 63 | ac5 = data[8] << 8 | data[9]; |
ishiyamayuto | 0:d58274531d38 | 64 | ac6 = data[10] << 8 | data[11]; |
ishiyamayuto | 0:d58274531d38 | 65 | b1 = data[12] << 8 | data[13]; |
ishiyamayuto | 0:d58274531d38 | 66 | b2 = data[14] << 8 | data[15]; |
ishiyamayuto | 0:d58274531d38 | 67 | mb = data[16] << 8 | data[17]; |
ishiyamayuto | 0:d58274531d38 | 68 | mc = data[18] << 8 | data[19]; |
ishiyamayuto | 0:d58274531d38 | 69 | md = data[20] << 8 | data[21]; |
ishiyamayuto | 0:d58274531d38 | 70 | |
ishiyamayuto | 0:d58274531d38 | 71 | #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 72 | ac1 = 408; |
ishiyamayuto | 0:d58274531d38 | 73 | ac2 = -72; |
ishiyamayuto | 0:d58274531d38 | 74 | ac3 = -14383; |
ishiyamayuto | 0:d58274531d38 | 75 | ac4 = 32741; |
ishiyamayuto | 0:d58274531d38 | 76 | ac5 = 32757; |
ishiyamayuto | 0:d58274531d38 | 77 | ac6 = 23153; |
ishiyamayuto | 0:d58274531d38 | 78 | b1 = 6190; |
ishiyamayuto | 0:d58274531d38 | 79 | b2 = 4; |
ishiyamayuto | 0:d58274531d38 | 80 | mb = -32768; |
ishiyamayuto | 0:d58274531d38 | 81 | mc = -8711; |
ishiyamayuto | 0:d58274531d38 | 82 | md = 2868; |
ishiyamayuto | 0:d58274531d38 | 83 | m_oss = 0; |
ishiyamayuto | 0:d58274531d38 | 84 | errors = 0; |
ishiyamayuto | 0:d58274531d38 | 85 | #endif // #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 86 | |
ishiyamayuto | 0:d58274531d38 | 87 | return errors? 0 : 1; |
ishiyamayuto | 0:d58274531d38 | 88 | } |
ishiyamayuto | 0:d58274531d38 | 89 | |
ishiyamayuto | 0:d58274531d38 | 90 | int BMP180::ReadData(float* pTemperature, float* pPressure) |
ishiyamayuto | 0:d58274531d38 | 91 | { |
ishiyamayuto | 0:d58274531d38 | 92 | long t, p; |
ishiyamayuto | 0:d58274531d38 | 93 | |
ishiyamayuto | 0:d58274531d38 | 94 | if (!ReadRawTemperature(&t) || !ReadRawPressure(&p)) |
ishiyamayuto | 0:d58274531d38 | 95 | { |
ishiyamayuto | 0:d58274531d38 | 96 | m_temperature = UNSET_BMP180_TEMPERATURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 97 | m_pressure = UNSET_BMP180_PRESSURE_VALUE; |
ishiyamayuto | 0:d58274531d38 | 98 | return 0; |
ishiyamayuto | 0:d58274531d38 | 99 | } |
ishiyamayuto | 0:d58274531d38 | 100 | |
ishiyamayuto | 0:d58274531d38 | 101 | m_temperature = TrueTemperature(t); |
ishiyamayuto | 0:d58274531d38 | 102 | m_pressure = TruePressure(p); |
ishiyamayuto | 0:d58274531d38 | 103 | |
ishiyamayuto | 0:d58274531d38 | 104 | if (pPressure) |
ishiyamayuto | 0:d58274531d38 | 105 | *pPressure = m_pressure; |
ishiyamayuto | 0:d58274531d38 | 106 | if (pTemperature) |
ishiyamayuto | 0:d58274531d38 | 107 | *pTemperature = m_temperature; |
ishiyamayuto | 0:d58274531d38 | 108 | |
ishiyamayuto | 0:d58274531d38 | 109 | return 1; |
ishiyamayuto | 0:d58274531d38 | 110 | } |
ishiyamayuto | 0:d58274531d38 | 111 | |
ishiyamayuto | 0:d58274531d38 | 112 | int BMP180::ReadRawTemperature(long* pUt) |
ishiyamayuto | 0:d58274531d38 | 113 | { |
ishiyamayuto | 0:d58274531d38 | 114 | int errors = 0; |
ishiyamayuto | 0:d58274531d38 | 115 | char data[2]; |
ishiyamayuto | 0:d58274531d38 | 116 | |
ishiyamayuto | 0:d58274531d38 | 117 | // request temperature measurement |
ishiyamayuto | 0:d58274531d38 | 118 | data[0] = 0xF4; |
ishiyamayuto | 0:d58274531d38 | 119 | data[1] = 0x2E; |
ishiyamayuto | 0:d58274531d38 | 120 | errors = m_i2c.write(m_addr, data, 2); // write 0XF2 into reg 0XF4 |
ishiyamayuto | 0:d58274531d38 | 121 | |
ishiyamayuto | 0:d58274531d38 | 122 | wait_ms(4.5F); |
ishiyamayuto | 0:d58274531d38 | 123 | |
ishiyamayuto | 0:d58274531d38 | 124 | // read raw temperature data |
ishiyamayuto | 0:d58274531d38 | 125 | data[0] = 0xF6; |
ishiyamayuto | 0:d58274531d38 | 126 | errors += m_i2c.write(m_addr, data, 2); // set eeprom pointer position to 0XF6 |
ishiyamayuto | 0:d58274531d38 | 127 | errors += m_i2c.read(m_addr, data, 2); // get 16 bits at this position |
ishiyamayuto | 0:d58274531d38 | 128 | |
ishiyamayuto | 0:d58274531d38 | 129 | #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 130 | errors = 0; |
ishiyamayuto | 0:d58274531d38 | 131 | #endif // #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 132 | |
ishiyamayuto | 0:d58274531d38 | 133 | if (errors) |
ishiyamayuto | 0:d58274531d38 | 134 | return 0; |
ishiyamayuto | 0:d58274531d38 | 135 | else |
ishiyamayuto | 0:d58274531d38 | 136 | *pUt = data[0] << 8 | data[1]; |
ishiyamayuto | 0:d58274531d38 | 137 | |
ishiyamayuto | 0:d58274531d38 | 138 | #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 139 | *pUt = 27898; |
ishiyamayuto | 0:d58274531d38 | 140 | #endif // #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 141 | |
ishiyamayuto | 0:d58274531d38 | 142 | return 1; |
ishiyamayuto | 0:d58274531d38 | 143 | } |
ishiyamayuto | 0:d58274531d38 | 144 | |
ishiyamayuto | 0:d58274531d38 | 145 | int BMP180::ReadRawPressure(long* pUp) |
ishiyamayuto | 0:d58274531d38 | 146 | { |
ishiyamayuto | 0:d58274531d38 | 147 | int errors = 0; |
ishiyamayuto | 0:d58274531d38 | 148 | char data[2]; |
ishiyamayuto | 0:d58274531d38 | 149 | |
ishiyamayuto | 0:d58274531d38 | 150 | // request pressure measurement |
ishiyamayuto | 0:d58274531d38 | 151 | data[0] = 0xF4; |
ishiyamayuto | 0:d58274531d38 | 152 | data[1] = 0x34 + (m_oss << 6); |
ishiyamayuto | 0:d58274531d38 | 153 | errors = m_i2c.write(m_addr, data, 2); // write 0x34 + (m_oss << 6) into reg 0XF4 |
ishiyamayuto | 0:d58274531d38 | 154 | |
ishiyamayuto | 0:d58274531d38 | 155 | switch (m_oss) |
ishiyamayuto | 0:d58274531d38 | 156 | { |
ishiyamayuto | 0:d58274531d38 | 157 | case BMP180_OSS_ULTRA_LOW_POWER: wait_ms(4.5); break; |
ishiyamayuto | 0:d58274531d38 | 158 | case BMP180_OSS_NORMAL: wait_ms(7.5); break; |
ishiyamayuto | 0:d58274531d38 | 159 | case BMP180_OSS_HIGH_RESOLUTION: wait_ms(13.5); break; |
ishiyamayuto | 0:d58274531d38 | 160 | case BMP180_OSS_ULTRA_HIGH_RESOLUTION: wait_ms(25.5); break; |
ishiyamayuto | 0:d58274531d38 | 161 | } |
ishiyamayuto | 0:d58274531d38 | 162 | |
ishiyamayuto | 0:d58274531d38 | 163 | // read raw pressure data |
ishiyamayuto | 0:d58274531d38 | 164 | data[0] = 0xF6; |
ishiyamayuto | 0:d58274531d38 | 165 | errors += m_i2c.write(m_addr, data, 1); // set eeprom pointer position to 0XF6 |
ishiyamayuto | 0:d58274531d38 | 166 | errors += m_i2c.read(m_addr, data, 2); // get 16 bits at this position |
ishiyamayuto | 0:d58274531d38 | 167 | |
ishiyamayuto | 0:d58274531d38 | 168 | #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 169 | errors = 0; |
ishiyamayuto | 0:d58274531d38 | 170 | #endif // #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 171 | |
ishiyamayuto | 0:d58274531d38 | 172 | if (errors) |
ishiyamayuto | 0:d58274531d38 | 173 | return 0; |
ishiyamayuto | 0:d58274531d38 | 174 | else |
ishiyamayuto | 0:d58274531d38 | 175 | *pUp = (data[0] << 16 | data[1] << 8) >> (8 - m_oss); |
ishiyamayuto | 0:d58274531d38 | 176 | #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 177 | *pUp = 23843; |
ishiyamayuto | 0:d58274531d38 | 178 | #endif // #ifdef BMP180_TEST_FORMULA |
ishiyamayuto | 0:d58274531d38 | 179 | |
ishiyamayuto | 0:d58274531d38 | 180 | return 1; |
ishiyamayuto | 0:d58274531d38 | 181 | } |
ishiyamayuto | 0:d58274531d38 | 182 | |
ishiyamayuto | 0:d58274531d38 | 183 | float BMP180::TrueTemperature(long ut) |
ishiyamayuto | 0:d58274531d38 | 184 | { |
ishiyamayuto | 0:d58274531d38 | 185 | long t; |
ishiyamayuto | 0:d58274531d38 | 186 | |
ishiyamayuto | 0:d58274531d38 | 187 | // straight out from the documentation |
ishiyamayuto | 0:d58274531d38 | 188 | x1 = ((ut - ac6) * ac5) >> 15; |
ishiyamayuto | 0:d58274531d38 | 189 | x2 = ((long)mc << 11) / (x1 + md); |
ishiyamayuto | 0:d58274531d38 | 190 | b5 = x1 + x2; |
ishiyamayuto | 0:d58274531d38 | 191 | t = (b5 + 8) >> 4; |
ishiyamayuto | 0:d58274531d38 | 192 | |
ishiyamayuto | 0:d58274531d38 | 193 | // convert to celcius |
ishiyamayuto | 0:d58274531d38 | 194 | return t / 10.F; |
ishiyamayuto | 0:d58274531d38 | 195 | } |
ishiyamayuto | 0:d58274531d38 | 196 | |
ishiyamayuto | 0:d58274531d38 | 197 | float BMP180::TruePressure(long up) |
ishiyamayuto | 0:d58274531d38 | 198 | { |
ishiyamayuto | 0:d58274531d38 | 199 | long p; |
ishiyamayuto | 0:d58274531d38 | 200 | |
ishiyamayuto | 0:d58274531d38 | 201 | // straight out from the documentation |
ishiyamayuto | 0:d58274531d38 | 202 | b6 = b5 - 4000; |
ishiyamayuto | 0:d58274531d38 | 203 | x1 = (b2 * (b6 * b6 >> 12)) >> 11; |
ishiyamayuto | 0:d58274531d38 | 204 | x2 = ac2 * b6 >> 11; |
ishiyamayuto | 0:d58274531d38 | 205 | x3 = x1 + x2; |
ishiyamayuto | 0:d58274531d38 | 206 | b3 = (((ac1 * 4 + x3) << m_oss) + 2) >> 2; |
ishiyamayuto | 0:d58274531d38 | 207 | x1 = (ac3 * b6) >> 13; |
ishiyamayuto | 0:d58274531d38 | 208 | x2 = (b1 * ((b6 * b6) >> 12)) >> 16; |
ishiyamayuto | 0:d58274531d38 | 209 | x3 = ((x1 + x2) + 2) >> 2; |
ishiyamayuto | 0:d58274531d38 | 210 | b4 = ac4 * (unsigned long)(x3 + 32768) >> 15; |
ishiyamayuto | 0:d58274531d38 | 211 | b7 = ((unsigned long)up - b3)* (50000 >> m_oss); |
ishiyamayuto | 0:d58274531d38 | 212 | if (b7 < 0x80000000) |
ishiyamayuto | 0:d58274531d38 | 213 | p = (b7 << 1) / b4; |
ishiyamayuto | 0:d58274531d38 | 214 | else |
ishiyamayuto | 0:d58274531d38 | 215 | p = (b7 / b4) << 1; |
ishiyamayuto | 0:d58274531d38 | 216 | x1 = (p >> 8) * (p >> 8); |
ishiyamayuto | 0:d58274531d38 | 217 | x1 = (x1 * 3038) >> 16; |
ishiyamayuto | 0:d58274531d38 | 218 | x2 = (-7357 * p) >> 16; |
ishiyamayuto | 0:d58274531d38 | 219 | p = p + ((x1 + x2 + 3791) >> 4); |
ishiyamayuto | 0:d58274531d38 | 220 | |
ishiyamayuto | 0:d58274531d38 | 221 | // convert to hPa and, if altitude has been initialized, to sea level pressure |
ishiyamayuto | 0:d58274531d38 | 222 | if (m_altitude == 0.F) |
ishiyamayuto | 0:d58274531d38 | 223 | return p / 100.F; |
ishiyamayuto | 0:d58274531d38 | 224 | else |
ishiyamayuto | 0:d58274531d38 | 225 | return p / (100.F * pow((1.F - m_altitude / 44330.0L), 5.255L)); |
ishiyamayuto | 0:d58274531d38 | 226 | } |