Implemented first Hangar-Service

Dependencies:   CalibrateMagneto QuaternionMath

Fork of SML2 by TobyRich GmbH

Committer:
pvaibhav
Date:
Wed Jan 14 17:57:11 2015 +0000
Revision:
2:3898208e02da
Parent:
1:c279bc3af90c
Child:
3:ee90a9ada112
Barometer improvements

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pvaibhav 1:c279bc3af90c 1 #include "Barometer.h"
pvaibhav 1:c279bc3af90c 2 #define DEBUG "BMP280"
pvaibhav 1:c279bc3af90c 3 #include "Logger.h"
pvaibhav 1:c279bc3af90c 4
pvaibhav 2:3898208e02da 5 // Calibration parameters stored on chip
pvaibhav 2:3898208e02da 6 static uint16_t dig_T1;
pvaibhav 2:3898208e02da 7 static int16_t dig_T2;
pvaibhav 2:3898208e02da 8 static int16_t dig_T3;
pvaibhav 2:3898208e02da 9 static uint16_t dig_P1;
pvaibhav 2:3898208e02da 10 static int16_t dig_P2;
pvaibhav 2:3898208e02da 11 static int16_t dig_P3;
pvaibhav 2:3898208e02da 12 static int16_t dig_P4;
pvaibhav 2:3898208e02da 13 static int16_t dig_P5;
pvaibhav 2:3898208e02da 14 static int16_t dig_P6;
pvaibhav 2:3898208e02da 15 static int16_t dig_P7;
pvaibhav 2:3898208e02da 16 static int16_t dig_P8;
pvaibhav 2:3898208e02da 17 static int16_t dig_P9;
pvaibhav 2:3898208e02da 18
pvaibhav 2:3898208e02da 19 void Barometer::bmp280_read_cal_reg(const uint8_t reg, char* val)
pvaibhav 2:3898208e02da 20 {
pvaibhav 2:3898208e02da 21 *val = read_reg(reg);
pvaibhav 2:3898208e02da 22 *(val + 1) = read_reg(reg + 1);
pvaibhav 2:3898208e02da 23 }
pvaibhav 2:3898208e02da 24
pvaibhav 2:3898208e02da 25 void Barometer::bmp280_read_calibration()
pvaibhav 2:3898208e02da 26 {
pvaibhav 2:3898208e02da 27 bmp280_read_cal_reg(0x88, (char*)&dig_T1);
pvaibhav 2:3898208e02da 28 bmp280_read_cal_reg(0x8A, (char*)&dig_T2);
pvaibhav 2:3898208e02da 29 bmp280_read_cal_reg(0x8C, (char*)&dig_T3);
pvaibhav 2:3898208e02da 30 bmp280_read_cal_reg(0x8E, (char*)&dig_P1);
pvaibhav 2:3898208e02da 31 bmp280_read_cal_reg(0x90, (char*)&dig_P2);
pvaibhav 2:3898208e02da 32 bmp280_read_cal_reg(0x92, (char*)&dig_P3);
pvaibhav 2:3898208e02da 33 bmp280_read_cal_reg(0x94, (char*)&dig_P4);
pvaibhav 2:3898208e02da 34 bmp280_read_cal_reg(0x96, (char*)&dig_P5);
pvaibhav 2:3898208e02da 35 bmp280_read_cal_reg(0x98, (char*)&dig_P6);
pvaibhav 2:3898208e02da 36 bmp280_read_cal_reg(0x9A, (char*)&dig_P7);
pvaibhav 2:3898208e02da 37 bmp280_read_cal_reg(0x9C, (char*)&dig_P8);
pvaibhav 2:3898208e02da 38 bmp280_read_cal_reg(0x9E, (char*)&dig_P9);
pvaibhav 2:3898208e02da 39 LOG("Calibration parameters: T=[%u, %d, %d] P=[%u, %d, %d, %d, %d, %d, %d, %d, %d]",
pvaibhav 2:3898208e02da 40 dig_T1, dig_T2, dig_T3,
pvaibhav 2:3898208e02da 41 dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
pvaibhav 2:3898208e02da 42 }
pvaibhav 2:3898208e02da 43
pvaibhav 2:3898208e02da 44 enum Oversampling {
pvaibhav 2:3898208e02da 45 kSkip = 0,
pvaibhav 2:3898208e02da 46 kOversample_1x = 1,
pvaibhav 2:3898208e02da 47 kOversample_2x = 2,
pvaibhav 2:3898208e02da 48 kOversample_4x = 3,
pvaibhav 2:3898208e02da 49 kOversample_8x = 4,
pvaibhav 2:3898208e02da 50 kOversample_16x = 5,
pvaibhav 2:3898208e02da 51 };
pvaibhav 2:3898208e02da 52
pvaibhav 2:3898208e02da 53 // Time taken to read the pressure at a particular oversampling
pvaibhav 2:3898208e02da 54 // cf. page 18
pvaibhav 2:3898208e02da 55 static float waitTime_ms[] = {
pvaibhav 2:3898208e02da 56 0, // skip
pvaibhav 2:3898208e02da 57 6.4, // 1x
pvaibhav 2:3898208e02da 58 8.7, // 2x
pvaibhav 2:3898208e02da 59 13.3, // 4x
pvaibhav 2:3898208e02da 60 22.5, // 8x
pvaibhav 2:3898208e02da 61 43.2, // 16x
pvaibhav 2:3898208e02da 62 };
pvaibhav 2:3898208e02da 63
pvaibhav 2:3898208e02da 64 enum Filtering {
pvaibhav 2:3898208e02da 65 kFilter_None = 0,
pvaibhav 2:3898208e02da 66 kFilter_2x = 1,
pvaibhav 2:3898208e02da 67 kFilter_4x = 2,
pvaibhav 2:3898208e02da 68 kFilter_8x = 3,
pvaibhav 2:3898208e02da 69 kFilter_16x = 4
pvaibhav 2:3898208e02da 70 };
pvaibhav 2:3898208e02da 71
pvaibhav 2:3898208e02da 72 void Barometer::setFilterCoefficient(const uint8_t iir)
pvaibhav 2:3898208e02da 73 {
pvaibhav 2:3898208e02da 74 write_reg(0xF5, (iir & 0x07) << 1);
pvaibhav 2:3898208e02da 75 INFO("Filter coefficient => %dx", 1 << iir);
pvaibhav 2:3898208e02da 76 }
pvaibhav 2:3898208e02da 77
pvaibhav 2:3898208e02da 78 void Barometer::takeMeasurement(const uint8_t tmpovr,
pvaibhav 2:3898208e02da 79 const uint8_t psrovr)
pvaibhav 2:3898208e02da 80 {
pvaibhav 2:3898208e02da 81 // Start a forced measurement
pvaibhav 2:3898208e02da 82 write_reg(0xF4,
pvaibhav 2:3898208e02da 83 ((tmpovr & 0x07) << 5) |
pvaibhav 2:3898208e02da 84 ((psrovr & 0x07) << 2) |
pvaibhav 2:3898208e02da 85 0x01 /* force reading mode */);
pvaibhav 2:3898208e02da 86
pvaibhav 2:3898208e02da 87 // wait until it's done
pvaibhav 2:3898208e02da 88 wait_ms(waitTime_ms[psrovr]); // XXX: what does this mean for BLE?
pvaibhav 2:3898208e02da 89 }
pvaibhav 2:3898208e02da 90
pvaibhav 2:3898208e02da 91 // Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
pvaibhav 2:3898208e02da 92 typedef int32_t BMP280_S32_t;
pvaibhav 2:3898208e02da 93 static BMP280_S32_t t_fine;
pvaibhav 2:3898208e02da 94 static double bmp280_val_to_Pa(BMP280_S32_t adc_P)
pvaibhav 2:3898208e02da 95 {
pvaibhav 2:3898208e02da 96 double var1, var2, p;
pvaibhav 2:3898208e02da 97 var1 = ((double)t_fine/2.0) - 64000.0;
pvaibhav 2:3898208e02da 98 var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
pvaibhav 2:3898208e02da 99 var2 = var2 + var1 * ((double)dig_P5) * 2.0;
pvaibhav 2:3898208e02da 100 var2 = (var2/4.0)+(((double)dig_P4) * 65536.0);
pvaibhav 2:3898208e02da 101 var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
pvaibhav 2:3898208e02da 102 var1 = (1.0 + var1 / 32768.0)*((double)dig_P1);
pvaibhav 2:3898208e02da 103 if (var1 == 0.0) {
pvaibhav 2:3898208e02da 104 return 0; // avoid exception caused by division by zero
pvaibhav 2:3898208e02da 105 }
pvaibhav 2:3898208e02da 106 p = 1048576.0 - (double)adc_P;
pvaibhav 2:3898208e02da 107 p = (p - (var2 / 4096.0)) * 6250.0 / var1;
pvaibhav 2:3898208e02da 108 var1 = ((double)dig_P9) * p * p / 2147483648.0;
pvaibhav 2:3898208e02da 109 var2 = p * ((double)dig_P8) / 32768.0;
pvaibhav 2:3898208e02da 110 p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
pvaibhav 2:3898208e02da 111 return p;
pvaibhav 2:3898208e02da 112 }
pvaibhav 2:3898208e02da 113
pvaibhav 2:3898208e02da 114 Barometer::Barometer(I2C &i2c) : I2CPeripheral(i2c, 0xEC /* address */)
pvaibhav 2:3898208e02da 115 {
pvaibhav 1:c279bc3af90c 116 write_reg(0xE0, 0xB6); // reset
pvaibhav 1:c279bc3af90c 117 wait_ms(2); // cf. datasheet page 8, t_startup
pvaibhav 1:c279bc3af90c 118 const uint8_t chip_id = read_reg(0xD0);
pvaibhav 1:c279bc3af90c 119 if (chip_id == 0x58) {
pvaibhav 2:3898208e02da 120 bmp280_read_calibration();
pvaibhav 2:3898208e02da 121 //setFilterCoefficient(kFilter_16x);
pvaibhav 1:c279bc3af90c 122 INFO("Bosch Sensortec BMP280 ready");
pvaibhav 1:c279bc3af90c 123 } else {
pvaibhav 1:c279bc3af90c 124 WARN("Bosch Sensortec BMP280 not found (chip ID=0x%02x, expected=0x58)", chip_id);
pvaibhav 1:c279bc3af90c 125 }
pvaibhav 1:c279bc3af90c 126 }
pvaibhav 1:c279bc3af90c 127
pvaibhav 2:3898208e02da 128 double Barometer::getPressure()
pvaibhav 2:3898208e02da 129 {
pvaibhav 2:3898208e02da 130 takeMeasurement(kSkip, kOversample_16x);
pvaibhav 2:3898208e02da 131 const uint8_t msb = read_reg(0xF7);
pvaibhav 2:3898208e02da 132 const uint8_t lsb = read_reg(0xF8);
pvaibhav 2:3898208e02da 133 const uint8_t xlsb = read_reg(0xF9);
pvaibhav 2:3898208e02da 134 const uint32_t val = (msb << 12) | (lsb << 4) | xlsb;
pvaibhav 2:3898208e02da 135 return bmp280_val_to_Pa(val) / 100.0;
pvaibhav 2:3898208e02da 136 }
pvaibhav 2:3898208e02da 137
pvaibhav 2:3898208e02da 138 double Barometer::getHeightFromPressure(const double p) {
pvaibhav 2:3898208e02da 139 const double R = 287.05; //general gas constant
pvaibhav 2:3898208e02da 140 const double g = 9.80665; // acceleration due to gravity
pvaibhav 2:3898208e02da 141 const double T = 24.0; // temperature
pvaibhav 2:3898208e02da 142 const double p0 = 1000.0; // hPa sea level
pvaibhav 2:3898208e02da 143 const double h = (R / g) * T * log(p0 / p);
pvaibhav 2:3898208e02da 144 return h;
pvaibhav 1:c279bc3af90c 145 }