#ifndef __BMP085_H__
#define __BMP085_H__
//----------------------------
#define BMP085_ADDRESS (0x77<<1) // I2C address of BMP085
#define OSS 3 // Oversampling Setting //const unsigned char
#define BARO_TAB_SIZE 21
// Calibration values
int ac1 =0,ac2 =0,ac3 =0;
unsigned int ac4 =0,ac5 =0,ac6 =0;
int b1 =0,b2 =0,mb =0,mc =0,md =0;
long b5 =0;
float temperature =0, pressure =0, pressure_sum =0, Hpressure =0, atm =0, altitude =0, baroPressureSum =0;
uint16_t calibratingB = 10;
float temperature0 =0, pressure0 =0, atm0 =0, altitude0 =0, baro_first=1;
// loop()
// {
//// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
//// so ...Temperature(...) must be called before ...Pressure(...).
// float temperature = bmp085GetTemperature(bmp085ReadUT()); //MUST be called first
// float pressure = bmp085GetPressure(bmp085ReadUP());
// float atm = pressure / 101325; // "standard atmosphere"
// float altitude = calcAltitude(pressure); //Uncompensated caculation - in Meters
// }
void bmp085Calibration(void);
float bmp085GetTemperature(unsigned int ut);
long bmp085GetPressure(unsigned long up);
void bmp085TrigUT(void);
unsigned int bmp085ReadUT(void);
void bmp085TrigUP(void);
unsigned long bmp085ReadUP(void);
float calcAltitude(float pressure);
void Baro_Common(void);
void getEstAltitude(void);
#endif
// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
ac1 = read16_rev(BMP085_ADDRESS,0xAA); //_rev
ac2 = read16_rev(BMP085_ADDRESS,0xAC);
ac3 = read16_rev(BMP085_ADDRESS,0xAE);
ac4 = read16_rev(BMP085_ADDRESS,0xB0);
ac5 = read16_rev(BMP085_ADDRESS,0xB2);
ac6 = read16_rev(BMP085_ADDRESS,0xB4);
b1 = read16_rev(BMP085_ADDRESS,0xB6);
b2 = read16_rev(BMP085_ADDRESS,0xB8);
mb = read16_rev(BMP085_ADDRESS,0xBA);
mc = read16_rev(BMP085_ADDRESS,0xBC);
md = read16_rev(BMP085_ADDRESS,0xBE);
}
// Calculate temperature in deg C
float bmp085GetTemperature(unsigned int ut){
long x1, x2;
float temp;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;
temp = ((b5 + 8)>>4);
temp = temp /10;
// temp = (b5 * 10 + 8) >> 4; // in 0.01 degC (same as MS561101BA temperature)
return temp;
}
long bmp085GetPressure(unsigned long up){
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;
long temp;
b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
// b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
// Calculate B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
b7 = ((unsigned long)(up - b3) * (50000>>OSS));
// b7 = ((unsigned long)(up >> (8-OSS)) - b3) * (50000>>OSS);
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
temp = p;
return temp;
}
// Trig for start temprature conversion
void bmp085TrigUT(){
// Write 0x2E into Register 0xF4
// This requests a temperature reading
writeRegister(BMP085_ADDRESS, 0xF4, 0x2E);
// Wait at least 4.5ms
// delay_ms(5);
}
// Read the uncompensated temperature value
unsigned int bmp085ReadUT(){
unsigned int ut;
// writeRegister(BMP085_ADDRESS, 0xF4, 0x2E);
// delay_ms(5);
// Read two bytes from registers 0xF6 and 0xF7
ut = read16_rev(BMP085_ADDRESS,0xF6); //_rev
return ut;
}
// Trig for start uncompensated pressure conversion
void bmp085TrigUP(){
// Write 0x34+(OSS<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
writeRegister(BMP085_ADDRESS, 0xF4, 0x34 + (OSS<<6));
// Wait for conversion, delay time dependent on OSS
// delay_ms(2 + (3<<OSS));
}
// Read the uncompensated pressure value
unsigned long bmp085ReadUP(){
unsigned long up = 0;
// writeRegister(BMP085_ADDRESS, 0xF4, 0x34 + (OSS<<6));
// delay_ms(5 + (3<<OSS));
// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
up = read24_rev(BMP085_ADDRESS, 0xF6); //_rev
return up;
}
float calcAltitude(float pressure){
float A, B, C;
A = pressure/101325;
B = 1/5.25588;
C = pow(A,B);
C = 1 - C;
C = C /0.0000225577;
return C;
}
void Baro_Common() {
static int32_t baroHistTab[BARO_TAB_SIZE];
static uint8_t baroHistIdx;
uint8_t indexplus1;
indexplus1 = (baroHistIdx + 1);
if (indexplus1 == BARO_TAB_SIZE) indexplus1 = 0;
baroHistTab[baroHistIdx] = pressure;
baroPressureSum += baroHistTab[baroHistIdx];
baroPressureSum -= baroHistTab[indexplus1];
baroHistIdx = indexplus1;
}
void getEstAltitude()
{
int32_t BaroAlt;
static float baroGroundTemperatureScale,logBaroGroundPressureSum;
if(calibratingB > 0) {
logBaroGroundPressureSum = log(baroPressureSum);
baroGroundTemperatureScale = (temperature + 27315) * 29.271267f;
calibratingB--;
}
// baroGroundPressureSum is not supposed to be 0 here
// see: https://code.google.com/p/ardupilot-mega/source/browse/libraries/AP_Baro/AP_Baro.cpp
BaroAlt = ( logBaroGroundPressureSum - log(baroPressureSum) ) * baroGroundTemperatureScale;
altitude = ((int)altitude * 6 + BaroAlt * 2) >> 3; // additional LPF to reduce baro noise (faster by 30 µs)
}