bring up code for the Bosch barometer and thermometer BMP085. This code is forked from http://mbed.org/users/tkreyche/notebook/bmp085-pressure-sensor/ but with a lot more comments and links to references. The extraction of the altitude via 2 methods is also implemented. Overall temperature seems way off (but implementation is correct). Altitude is off too (but implementation is correct).

Dependencies:   mbed

Committer:
Rom
Date:
Fri Dec 28 06:09:46 2012 +0000
Revision:
0:184eb17ff158
Bring up program of the Bosch Barometer + temperature. Absolute values are wrong despite correct implementation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rom 0:184eb17ff158 1 #include "mbed.h"
Rom 0:184eb17ff158 2
Rom 0:184eb17ff158 3 /* sample code for the barometer BMP085 as provided on the breakout board from sparkfun.
Rom 0:184eb17ff158 4 Pull up resistors for I2C are already provided (aka already on the board).
Rom 0:184eb17ff158 5 Link to sparkfun board: https://www.sparkfun.com/products/11282?
Rom 0:184eb17ff158 6
Rom 0:184eb17ff158 7 Datasheet of barometer: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Pressure/BST-BMP085-DS000-06.pdf
Rom 0:184eb17ff158 8
Rom 0:184eb17ff158 9 Comments:
Rom 0:184eb17ff158 10 - pressure values returned by the moving average seems believable (1090 Hecto Pascal on 12/18/2012)
Rom 0:184eb17ff158 11 - Temperature seems to oscillate between 365 and 87 and seems totally wrong.
Rom 0:184eb17ff158 12 - Altitude is off (obviously fluctates with weather) but roughly speaking
Rom 0:184eb17ff158 13 indicates -800m when altitude should be 0m
Rom 0:184eb17ff158 14
Rom 0:184eb17ff158 15 Example of output in the terminal:
Rom 0:184eb17ff158 16
Rom 0:184eb17ff158 17 Temperature: 87 (raw value (uncomp): 61184)
Rom 0:184eb17ff158 18 Pressure (Pa): 106626 (raw: 249856) Mov Avg: 62353
Rom 0:184eb17ff158 19 altitude is (m): -432.270721
Rom 0:184eb17ff158 20 wikipedia altitude (m): -432.061523
Rom 0:184eb17ff158 21
Rom 0:184eb17ff158 22 Temperature: 365 (raw value (uncomp): 62464)
Rom 0:184eb17ff158 23 Pressure (Pa): 109312 (raw: 244736) Mov Avg: 67558
Rom 0:184eb17ff158 24 altitude is (m): -644.688416
Rom 0:184eb17ff158 25 wikipedia altitude (m): -644.382446
Rom 0:184eb17ff158 26
Rom 0:184eb17ff158 27 Temperature: 365 (raw value (uncomp): 62464)
Rom 0:184eb17ff158 28 Pressure (Pa): 111417 (raw: 249856) Mov Avg: 72864
Rom 0:184eb17ff158 29 altitude is (m): -808.229309
Rom 0:184eb17ff158 30 wikipedia altitude (m): -807.841614
Rom 0:184eb17ff158 31
Rom 0:184eb17ff158 32 */
Rom 0:184eb17ff158 33
Rom 0:184eb17ff158 34 #define EE 22 //The EEPROM has 176bits of calibration data (176/8 = 22 Bytes)
Rom 0:184eb17ff158 35 #define BMP085ADDR 0xEF // I2C address of the barometer
Rom 0:184eb17ff158 36
Rom 0:184eb17ff158 37 //Calibration variables
Rom 0:184eb17ff158 38 long b5;
Rom 0:184eb17ff158 39 short ac1;
Rom 0:184eb17ff158 40 short ac2;
Rom 0:184eb17ff158 41 short ac3;
Rom 0:184eb17ff158 42 unsigned short ac4;
Rom 0:184eb17ff158 43 unsigned short ac5;
Rom 0:184eb17ff158 44 unsigned short ac6;
Rom 0:184eb17ff158 45 short b1;
Rom 0:184eb17ff158 46 short b2;
Rom 0:184eb17ff158 47 short mb;
Rom 0:184eb17ff158 48 short mc;
Rom 0:184eb17ff158 49 short md;
Rom 0:184eb17ff158 50
Rom 0:184eb17ff158 51 // Function to compute the human interpretable values
Rom 0:184eb17ff158 52 int calcPress(int upp, int oversampling_setting);
Rom 0:184eb17ff158 53 int calcTemp(int ut);
Rom 0:184eb17ff158 54 float calcAltitude(int pressure);
Rom 0:184eb17ff158 55 float calcWikipediaAltitude(int pressure);
Rom 0:184eb17ff158 56
Rom 0:184eb17ff158 57 //Moving average variables
Rom 0:184eb17ff158 58 #define COEFZ 21 // 21 bits used for computing the moving average
Rom 0:184eb17ff158 59 static int k[COEFZ]; // an array used for the moving average
Rom 0:184eb17ff158 60 static int movAvgIntZ (int input);
Rom 0:184eb17ff158 61
Rom 0:184eb17ff158 62 //address of commands
Rom 0:184eb17ff158 63 #define CMD_READ_VALUE 0xF6
Rom 0:184eb17ff158 64 #define CMD_READ_CALIBRATION 0xAA
Rom 0:184eb17ff158 65
Rom 0:184eb17ff158 66 #define OVERSAMPLING_ULTRA_LOW_POWER 0
Rom 0:184eb17ff158 67 #define OVERSAMPLING_STANDARD 1
Rom 0:184eb17ff158 68 #define OVERSAMPLING_HIGH_RESOLUTION 2
Rom 0:184eb17ff158 69 #define OVERSAMPLING_ULTRA_HIGH_RESOLUTION 3
Rom 0:184eb17ff158 70
Rom 0:184eb17ff158 71 const float ALTITUDE_EXPONENT = 1/5.255;
Rom 0:184eb17ff158 72 const float ALTITUDE_PRESSURE_REFERENCE = 101325.0; // In Pa
Rom 0:184eb17ff158 73 const float ALTITUDE_COEFF = 44330.0;
Rom 0:184eb17ff158 74
Rom 0:184eb17ff158 75 const float TEMPERATURE_LAPSE_RATE = 0.0065; // in K/m
Rom 0:184eb17ff158 76 const float SEA_LEVEL_STANDARD_TEMPERATURE = 288.15; // in Kelvins
Rom 0:184eb17ff158 77 const float GRAVITATIONAL_ACCELERATION = 9.81; // in m/(s*s)
Rom 0:184eb17ff158 78 const float MOLAR_MASS_AIR = 0.0289644; // in Kg/mol
Rom 0:184eb17ff158 79 const float R = 8.31447; // in J/(mol*K) universal gas constant
Rom 0:184eb17ff158 80
Rom 0:184eb17ff158 81 const float WIKIPEDIA_EXPONENT = GRAVITATIONAL_ACCELERATION * MOLAR_MASS_AIR/ (R * TEMPERATURE_LAPSE_RATE);
Rom 0:184eb17ff158 82
Rom 0:184eb17ff158 83
Rom 0:184eb17ff158 84 I2C i2c(p28, p27); // sda, scl
Rom 0:184eb17ff158 85 InterruptIn dr(p26); // EOC, conversion notification
Rom 0:184eb17ff158 86 // Note that XCLR is floating = not connected (power for analog portion?)
Rom 0:184eb17ff158 87
Rom 0:184eb17ff158 88 uint32_t drFlag;
Rom 0:184eb17ff158 89
Rom 0:184eb17ff158 90 void cvt(); // Send I2C command to start pressure conversion (?)
Rom 0:184eb17ff158 91 void drSub(); // set a flag to one. Pretty poorly written code IMO.
Rom 0:184eb17ff158 92
Rom 0:184eb17ff158 93 Serial pc(USBTX, USBRX); // tx, rx
Rom 0:184eb17ff158 94
Rom 0:184eb17ff158 95 int main() {
Rom 0:184eb17ff158 96
Rom 0:184eb17ff158 97 // let hardware settle
Rom 0:184eb17ff158 98 wait(1);
Rom 0:184eb17ff158 99
Rom 0:184eb17ff158 100 /////////////////////////////////////////////////
Rom 0:184eb17ff158 101 // set up timer to trigger pressure conversion
Rom 0:184eb17ff158 102 /////////////////////////////////////////////////
Rom 0:184eb17ff158 103 Ticker convert;
Rom 0:184eb17ff158 104 convert.attach_us(&cvt, 50000); // 50 ms, 20 Hz //Pointer to a void function
Rom 0:184eb17ff158 105
Rom 0:184eb17ff158 106 /////////////////////////////////////////////////
Rom 0:184eb17ff158 107 // set up data ready interrupts
Rom 0:184eb17ff158 108 /////////////////////////////////////////////////
Rom 0:184eb17ff158 109 // set up interrupts
Rom 0:184eb17ff158 110 __disable_irq();
Rom 0:184eb17ff158 111 // ADC data ready
Rom 0:184eb17ff158 112 drFlag = 0;
Rom 0:184eb17ff158 113 dr.mode(PullDown);
Rom 0:184eb17ff158 114 dr.rise(&drSub);
Rom 0:184eb17ff158 115
Rom 0:184eb17ff158 116 /////////////////////////////////////////////////
Rom 0:184eb17ff158 117 // set up i2c
Rom 0:184eb17ff158 118 /////////////////////////////////////////////////
Rom 0:184eb17ff158 119 char addr = BMP085ADDR; // define the I2C Address
Rom 0:184eb17ff158 120 int oversampling_setting = OVERSAMPLING_HIGH_RESOLUTION; // called oss in the documentation
Rom 0:184eb17ff158 121 // read page 12 of doc. 3 is ultra high precision and it requires a lot of time for the device to do the conversion
Rom 0:184eb17ff158 122 char rReg[3] = {0,0,0}; // read registers for I2C
Rom 0:184eb17ff158 123 char wReg[2] = {0,0}; // write registers for I2C
Rom 0:184eb17ff158 124 char cmd = 0x00;
Rom 0:184eb17ff158 125
Rom 0:184eb17ff158 126 /////////////////////////////////////////////////
Rom 0:184eb17ff158 127 // get EEPROM calibration parameters
Rom 0:184eb17ff158 128 /////////////////////////////////////////////////
Rom 0:184eb17ff158 129
Rom 0:184eb17ff158 130 char data[EE];
Rom 0:184eb17ff158 131 cmd = CMD_READ_CALIBRATION; // EEPROM calibration command
Rom 0:184eb17ff158 132
Rom 0:184eb17ff158 133 for (int i = 0; i < EE; i++) { // read over the 22 registers of the EEPROM
Rom 0:184eb17ff158 134 i2c.write(addr, &cmd, 1);
Rom 0:184eb17ff158 135 i2c.read(addr, rReg, 1); // rReg is array? of size 3. We only read the 1st register???
Rom 0:184eb17ff158 136 data[i] = rReg[0];
Rom 0:184eb17ff158 137 cmd += 1;
Rom 0:184eb17ff158 138 wait_ms(10);
Rom 0:184eb17ff158 139 }
Rom 0:184eb17ff158 140
Rom 0:184eb17ff158 141 // parameters AC1-AC6
Rom 0:184eb17ff158 142 //The calibration is partioned in 11 words of 16 bits, each of them representing a coefficient
Rom 0:184eb17ff158 143 ac1 = (data[0] <<8) | data[1]; // AC1(0xAA, 0xAB)... and so on
Rom 0:184eb17ff158 144 ac2 = (data[2] <<8) | data[3];
Rom 0:184eb17ff158 145 ac3 = (data[4] <<8) | data[5];
Rom 0:184eb17ff158 146 ac4 = (data[6] <<8) | data[7];
Rom 0:184eb17ff158 147 ac5 = (data[8] <<8) | data[9];
Rom 0:184eb17ff158 148 ac6 = (data[10] <<8) | data[11];
Rom 0:184eb17ff158 149 // parameters B1,B2
Rom 0:184eb17ff158 150 b1 = (data[12] <<8) | data[13];
Rom 0:184eb17ff158 151 b2 = (data[14] <<8) | data[15];
Rom 0:184eb17ff158 152 // parameters MB,MC,MD
Rom 0:184eb17ff158 153 mb = (data[16] <<8) | data[17];
Rom 0:184eb17ff158 154 mc = (data[18] <<8) | data[19];
Rom 0:184eb17ff158 155 md = (data[20] <<8) | data[21];
Rom 0:184eb17ff158 156
Rom 0:184eb17ff158 157 // ready to start sampling loop
Rom 0:184eb17ff158 158 __enable_irq();
Rom 0:184eb17ff158 159
Rom 0:184eb17ff158 160 // END OF INITIALIZATION
Rom 0:184eb17ff158 161
Rom 0:184eb17ff158 162 /////////////////////////////////////////////////
Rom 0:184eb17ff158 163 // main
Rom 0:184eb17ff158 164 /////////////////////////////////////////////////
Rom 0:184eb17ff158 165 pc.printf("Starting barometer main()!!\n\r");
Rom 0:184eb17ff158 166 while (1) {
Rom 0:184eb17ff158 167 if (drFlag == 1) {
Rom 0:184eb17ff158 168 // Documentation recommend the following chronology:
Rom 0:184eb17ff158 169 // read uncomp temp, read uncomp pressure, compute true temp,
Rom 0:184eb17ff158 170 // compute true pressure
Rom 0:184eb17ff158 171
Rom 0:184eb17ff158 172 /////////////////////////////////////////////////
Rom 0:184eb17ff158 173 // uncomp temperature
Rom 0:184eb17ff158 174 /////////////////////////////////////////////////
Rom 0:184eb17ff158 175 wReg[0] = 0xF4;
Rom 0:184eb17ff158 176 wReg[1] = 0x2E;
Rom 0:184eb17ff158 177 i2c.write(addr, wReg, 2); // write 0x2E in reg 0XF4
Rom 0:184eb17ff158 178 wait_ms(4.5);
Rom 0:184eb17ff158 179 cmd = CMD_READ_VALUE; // 0xF6
Rom 0:184eb17ff158 180 i2c.write(addr, &cmd, 1); // set pointer on 0xF6 before reading it?
Rom 0:184eb17ff158 181 i2c.read(addr, rReg, 2); // read 0xF6 (MSB) and 0xF7 (LSB)// rReg is 3 long though
Rom 0:184eb17ff158 182 int uncomp_temperature = (rReg[0] << 8) | rReg[1]; // UT = MSB << 8 + LSB
Rom 0:184eb17ff158 183
Rom 0:184eb17ff158 184 /////////////////////////////////////////////////
Rom 0:184eb17ff158 185 // uncomp pressure
Rom 0:184eb17ff158 186 /////////////////////////////////////////////////
Rom 0:184eb17ff158 187
Rom 0:184eb17ff158 188 //write 0x34 + (oss<<6) into reg 0xF4, wait (waiting time not specified in doc)
Rom 0:184eb17ff158 189 int uncomp_pressure_cmd = 0x34 + (oversampling_setting<<6);
Rom 0:184eb17ff158 190 wReg[0] = 0xF4;
Rom 0:184eb17ff158 191 wReg[1] = uncomp_pressure_cmd;
Rom 0:184eb17ff158 192 i2c.write(addr, wReg, 2);
Rom 0:184eb17ff158 193 // See page 12 of documentation
Rom 0:184eb17ff158 194 switch (oversampling_setting) {
Rom 0:184eb17ff158 195 case OVERSAMPLING_ULTRA_LOW_POWER:
Rom 0:184eb17ff158 196 wait_ms(4.5);
Rom 0:184eb17ff158 197 break;
Rom 0:184eb17ff158 198 case OVERSAMPLING_STANDARD:
Rom 0:184eb17ff158 199 wait_ms(7.5);
Rom 0:184eb17ff158 200 break;
Rom 0:184eb17ff158 201 case OVERSAMPLING_HIGH_RESOLUTION:
Rom 0:184eb17ff158 202 wait_ms(13.5);
Rom 0:184eb17ff158 203 break;
Rom 0:184eb17ff158 204 case OVERSAMPLING_ULTRA_HIGH_RESOLUTION:
Rom 0:184eb17ff158 205 wait_ms(25.5);
Rom 0:184eb17ff158 206 break;
Rom 0:184eb17ff158 207 }
Rom 0:184eb17ff158 208
Rom 0:184eb17ff158 209 cmd = CMD_READ_VALUE; // 0xF6
Rom 0:184eb17ff158 210 i2c.write(addr, &cmd, 1);
Rom 0:184eb17ff158 211 i2c.read(addr, rReg, 3); // read 0xF6 (MSB), 0xF7 (LSB), 0xF8 (XLSB)
Rom 0:184eb17ff158 212 int uncomp_pressure = ((rReg[0] << 16) | (rReg[1] << 8) | rReg[2]) >> (8 - oversampling_setting);
Rom 0:184eb17ff158 213 // UP = (MSB<<16 + LSB<<8 + XLSB)>>(8-oss)
Rom 0:184eb17ff158 214
Rom 0:184eb17ff158 215 // true temperature
Rom 0:184eb17ff158 216 int temperature = calcTemp(uncomp_temperature);
Rom 0:184eb17ff158 217 pc.printf("Temperature: %d (raw value (uncomp): %d)\n\r", temperature, uncomp_temperature);
Rom 0:184eb17ff158 218 // even though implementation seems right,
Rom 0:184eb17ff158 219 //returned value is wrong hostilating between 87 and 365 (i.e. 8.7C and 36.5C)
Rom 0:184eb17ff158 220
Rom 0:184eb17ff158 221 // True pressure
Rom 0:184eb17ff158 222 int pressure = calcPress(uncomp_pressure, oversampling_setting);
Rom 0:184eb17ff158 223 int avg_pressure = movAvgIntZ(pressure);
Rom 0:184eb17ff158 224 pc.printf("Pressure (Pa): %d (raw: %d) Mov Avg: %d\n\r", pressure, uncomp_pressure, avg_pressure);
Rom 0:184eb17ff158 225
Rom 0:184eb17ff158 226 //Compute an estimate of altitude
Rom 0:184eb17ff158 227 // see page 15 of manual
Rom 0:184eb17ff158 228 float altitude = calcAltitude(pressure);
Rom 0:184eb17ff158 229 pc.printf("altitude is (m): %f\n\r", altitude); // note that the implementation is correct but returns wrong absolute numbers
Rom 0:184eb17ff158 230
Rom 0:184eb17ff158 231 float wiki_altitude = calcWikipediaAltitude(pressure);
Rom 0:184eb17ff158 232 pc.printf("wikipedia altitude (m): %f\n\r", wiki_altitude); // results are VERY similar and therefore not
Rom 0:184eb17ff158 233
Rom 0:184eb17ff158 234 /////////////////////////////////////////////////
Rom 0:184eb17ff158 235 // data ready cleanup tasks
Rom 0:184eb17ff158 236 /////////////////////////////////////////////////
Rom 0:184eb17ff158 237 drFlag = 0; // This should stop the while loop... but it does not!
Rom 0:184eb17ff158 238 pc.printf("\n\r");
Rom 0:184eb17ff158 239 }
Rom 0:184eb17ff158 240 wait(3); // just to make reading in the terminal easier
Rom 0:184eb17ff158 241 } //end while
Rom 0:184eb17ff158 242 }
Rom 0:184eb17ff158 243
Rom 0:184eb17ff158 244 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 245 // start pressure conversion
Rom 0:184eb17ff158 246 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 247 void cvt() { //This is only called once during the initialization phase!
Rom 0:184eb17ff158 248 char w[2] = {0xF4, 0xF4};
Rom 0:184eb17ff158 249 i2c.write(BMP085ADDR, w, 2);
Rom 0:184eb17ff158 250 }
Rom 0:184eb17ff158 251
Rom 0:184eb17ff158 252 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 253 // Handle data ready interrupt, just sets data ready flag
Rom 0:184eb17ff158 254 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 255 void drSub() {
Rom 0:184eb17ff158 256 drFlag = 1;
Rom 0:184eb17ff158 257 }
Rom 0:184eb17ff158 258
Rom 0:184eb17ff158 259 /////////////////////////////////////////////////
Rom 0:184eb17ff158 260 // calculate compensated pressure
Rom 0:184eb17ff158 261 /////////////////////////////////////////////////
Rom 0:184eb17ff158 262 int calcPress(int upp, int oversampling_setting) {
Rom 0:184eb17ff158 263 // Return the pressure in Pa (Pascals)
Rom 0:184eb17ff158 264
Rom 0:184eb17ff158 265 long pressure, x1, x2, x3, b3, b6;
Rom 0:184eb17ff158 266 unsigned long b4, b7;
Rom 0:184eb17ff158 267 // read page 12 of doc. This is ultra high precision and it requires a lot of time for the device to do the conversion
Rom 0:184eb17ff158 268
Rom 0:184eb17ff158 269 unsigned long up = (unsigned long)upp;
Rom 0:184eb17ff158 270
Rom 0:184eb17ff158 271 b6 = b5 - 4000;
Rom 0:184eb17ff158 272 // calculate B3
Rom 0:184eb17ff158 273 x1 = (b6*b6) >> 12; // full formula(b2*(b6*b6)/pow(2,12))/pow(2,11)
Rom 0:184eb17ff158 274 x1 *= b2;
Rom 0:184eb17ff158 275 x1 >>= 11;
Rom 0:184eb17ff158 276
Rom 0:184eb17ff158 277 x2 = (ac2*b6);
Rom 0:184eb17ff158 278 x2 >>= 11;
Rom 0:184eb17ff158 279
Rom 0:184eb17ff158 280 x3 = x1 + x2;
Rom 0:184eb17ff158 281
Rom 0:184eb17ff158 282 b3 = (((((long)ac1 )*4 + x3) <<oversampling_setting) + 2) >> 2; // doc says /4!
Rom 0:184eb17ff158 283
Rom 0:184eb17ff158 284 // calculate B4
Rom 0:184eb17ff158 285 x1 = (ac3* b6) >> 13;
Rom 0:184eb17ff158 286 x2 = (b1 * ((b6*b6) >> 12) ) >> 16;
Rom 0:184eb17ff158 287 x3 = ((x1 + x2) + 2) >> 2;
Rom 0:184eb17ff158 288 b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15;
Rom 0:184eb17ff158 289
Rom 0:184eb17ff158 290 b7 = ((unsigned long) up - b3) * (50000>>oversampling_setting);
Rom 0:184eb17ff158 291 if (b7 < 0x80000000) {
Rom 0:184eb17ff158 292 pressure = (b7 << 1) / b4;
Rom 0:184eb17ff158 293 } else {
Rom 0:184eb17ff158 294 pressure = (b7 / b4) << 1;
Rom 0:184eb17ff158 295 }
Rom 0:184eb17ff158 296
Rom 0:184eb17ff158 297 x1 = pressure >> 8;
Rom 0:184eb17ff158 298 x1 *= x1; // pressure/pow(2,8) * pressure/pow(2, 8)
Rom 0:184eb17ff158 299 x1 = (x1 * 3038) >> 16;
Rom 0:184eb17ff158 300 x2 = (pressure * -7357) >> 16;
Rom 0:184eb17ff158 301 pressure += (x1 + x2 + 3791) >> 4; // pressure in Pa
Rom 0:184eb17ff158 302
Rom 0:184eb17ff158 303 return (pressure);
Rom 0:184eb17ff158 304 }
Rom 0:184eb17ff158 305
Rom 0:184eb17ff158 306 /////////////////////////////////////////////////
Rom 0:184eb17ff158 307 // calculate compensated temp from uncompensated
Rom 0:184eb17ff158 308 /////////////////////////////////////////////////
Rom 0:184eb17ff158 309 int calcTemp(int ut) {
Rom 0:184eb17ff158 310 // Returns the temperature in °C
Rom 0:184eb17ff158 311
Rom 0:184eb17ff158 312 int temp;
Rom 0:184eb17ff158 313 long x1, x2;
Rom 0:184eb17ff158 314
Rom 0:184eb17ff158 315 x1 = (((long) ut - (long) ac6) * (long) ac5) >> 15; // aka (ut-ac6) * ac5/pow(2,15)
Rom 0:184eb17ff158 316 x2 = ((long) mc << 11) / (x1 + md); // aka mc * pow(2, 11) / (x1 + md)
Rom 0:184eb17ff158 317 b5 = x1 + x2;
Rom 0:184eb17ff158 318 temp = ((b5 + 8) >> 4); // (b5+8)/pow(2, 4)
Rom 0:184eb17ff158 319 // temperature in 0.1°C (aka 1903 = 190.3°C)
Rom 0:184eb17ff158 320 return (temp);
Rom 0:184eb17ff158 321 }
Rom 0:184eb17ff158 322
Rom 0:184eb17ff158 323 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 324 // int version of moving average filter
Rom 0:184eb17ff158 325 ////////////////////////////////////////////////////////////////////////////////////
Rom 0:184eb17ff158 326
Rom 0:184eb17ff158 327 static int movAvgIntZ (int input) {
Rom 0:184eb17ff158 328 int cum = 0;
Rom 0:184eb17ff158 329 for (int i = 0; i < COEFZ; i++) {
Rom 0:184eb17ff158 330 k[i] = k[i+1]; // do we really need k as a global variable?
Rom 0:184eb17ff158 331 }
Rom 0:184eb17ff158 332 k[COEFZ - 1] = input;
Rom 0:184eb17ff158 333 for (int i = 0; i < COEFZ; i++) {
Rom 0:184eb17ff158 334 cum += k[i];
Rom 0:184eb17ff158 335 }
Rom 0:184eb17ff158 336 return (cum/COEFZ) ;
Rom 0:184eb17ff158 337 }
Rom 0:184eb17ff158 338
Rom 0:184eb17ff158 339 float calcAltitude(int pressure) {
Rom 0:184eb17ff158 340 //Compute an estimate of altitude
Rom 0:184eb17ff158 341 // see page 15 of manual
Rom 0:184eb17ff158 342 float float_comp_pressure = (float) pressure;
Rom 0:184eb17ff158 343 float altitude = float_comp_pressure/ALTITUDE_PRESSURE_REFERENCE;
Rom 0:184eb17ff158 344 altitude = pow(altitude, ALTITUDE_EXPONENT);
Rom 0:184eb17ff158 345 altitude = 1.0 - altitude;
Rom 0:184eb17ff158 346 altitude *= ALTITUDE_COEFF;
Rom 0:184eb17ff158 347 // formula is: altitude = 44330 * (1-pow((p/p0), 1/5.255))
Rom 0:184eb17ff158 348 return altitude;
Rom 0:184eb17ff158 349 }
Rom 0:184eb17ff158 350
Rom 0:184eb17ff158 351 float calcWikipediaAltitude(int pressure) {
Rom 0:184eb17ff158 352 // compute the altitude in meters
Rom 0:184eb17ff158 353 // per: http://en.wikipedia.org/wiki/Atmospheric_pressure
Rom 0:184eb17ff158 354 float float_comp_pressure = (float) pressure;
Rom 0:184eb17ff158 355
Rom 0:184eb17ff158 356 float altitude = float_comp_pressure/ALTITUDE_PRESSURE_REFERENCE;
Rom 0:184eb17ff158 357 float exponent = 1.0/WIKIPEDIA_EXPONENT;
Rom 0:184eb17ff158 358 altitude = pow(altitude, exponent);
Rom 0:184eb17ff158 359 altitude = 1.0 - altitude;
Rom 0:184eb17ff158 360 altitude *= (SEA_LEVEL_STANDARD_TEMPERATURE/TEMPERATURE_LAPSE_RATE);
Rom 0:184eb17ff158 361
Rom 0:184eb17ff158 362 return altitude;
Rom 0:184eb17ff158 363 }