// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++ Get Altitude from Barometric Pressure +++++++++++
// Last Update: 13-09-2022
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //======== Function Read-Altitude with BMP-280 =============
// This code works with the BMP-280 barometric pressure sensor
// Note: right shift >>n is divide by 2**n
// Note: left shift < 21,3316 m afname.
//========================================================
//========= Function get_baro_altitude =============
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Latest Update: 31-07-2022
//
float get_baro_altitude()
{
float _baro_altitude;
// based onthe assumption: 1 mbar = 8m valid up to 1000m
actual_baropressure = Call_baro_pressure();
_baro_altitude = (start_baropressure - actual_baropressure)*8; //m
return _baro_altitude;
}
//========= Function Read BMP280 AirPressure =============
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Latest Update: 13-09-2022
//
// Code based on Bosch BMP280 Datasheet
// Note: 1 mbar = 1 hPa, range 0-1000m etwa 1 mbar/8m afname.
// Note: 2mmHg = 2,66645 mbar => 21,3316 m afname.
//void Call_BMP280AirPressure()
float Call_baro_pressure()
{
float _pressure;
if (AltitudeFlag==0)
{
Read_BMP280_EPROM_values();
}
writeTo(BMP280_Addr, 0xE0, 0x00); //0xB6 reset register
delay(3);
writeTo(BMP280_Addr, 0xF4, 0b01101111); //ctrl-measure register
// osrs_t | osrs_p | mode => 0b 011 | 011 | 11 See Datasheet
// I2C.write(0b 011 011 11); // send 0b01101111 to register
delay(3);
// uint8_t data[6];
I2C.beginTransmission(BMP280_Addr); // Start I2C Transmission
I2C.write(0xF7); // F7 Select data register
I2C.endTransmission(); // Stop I2C Transmission
I2C.requestFrom(BMP280_Addr, 6); // Request 2 bytes of data
for (count = 0; count <3; count++)
{
delay(10);
data[count] = I2C.read(); //Read actual Temperature Data
// Serial.print("Tdata");
// Serial.print(count);
// Serial.print("= ");
// Serial.print(data[count]);
// Serial.print(" ");
}
// Serial.println();
for (count = 3; count <6; count++)
{
delay(10);
data[count] = I2C.read(); //Read actual Pressure Data
// Serial.print("Pdata");
// Serial.print(count);
// Serial.print("= ");
// Serial.print(data[count]);
// Serial.print(" ");
}
// Serial.println();
int32_t adcTemp = (int32_t)data[3] << 12 | (int32_t)data[4] << 4 | (int32_t)data[5] >> 4; // Copy the temperature and pressure data into the adc variables
int32_t adcPres = (int32_t)data[0] << 12 | (int32_t)data[1] << 4 | (int32_t)data[2] >> 4;
// Serial.print("adcTemp 519888= ");
// Serial.print(adcTemp);
// Serial.print(" ");
// Serial.print("adcPres 415148= ");
// Serial.print(adcPres);
// Serial.println();
// delay(5000);
// Temperature compensation (function from BMP280 datasheet)
float temp = bmp280_compensate_T_double(adcTemp);
temperature = (float)temp; // Calculate the temperature in degrees Celsius
// Pressure compensation (function from BMP280 datasheet)
double pres = bmp280_compensate_P_double(adcPres);
return _pressure = (float)pres; // pressure in millibar
}
// ================= Start Reading BMP280-EPROM ===================
void Read_BMP280_EPROM_values()
{
// uint16_t dig_T1;
// int16_t dig_T2, dig_T3;
// uint16_t dig_P1;
// int16_t dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9;
Serial.println();
Serial.println("Reading calib.coefficients stored in BMP-280 EPROM.");
for (count = 0; count <12; count++)
{
I2C.beginTransmission(BMP280_Addr); // Start I2C Transmission
I2C.write(0x88 + (2 * count)); // F7 Select data register
I2C.endTransmission(); // Stop I2C Transmission
I2C.requestFrom(BMP280_Addr, 2); // Request 2 bytes of data
if(I2C.available() == 2) // Read 2 bytes of data dwz Coff msb, Coff lsb
{
delay(150);
data[0] = I2C.read(); //LSB
// Serial.print("LSB= ");
// Serial.print(data[0]);
delay(150);
data[1] = I2C.read(); //MSB
// Serial.print(" MSB= ");
// Serial.print(data[1]);
// Serial.println();
}
Coff[count] = ((data[1] * 256) + data[0]); // Convert the data
// Serial.print("Test Coff-");
// Serial.print(count);
// Serial.print("= ");
// Serial.print(Coff[count]);
// Serial.println();
delay(100);
}
Serial.println();
dig_T1 = Coff[0];
Serial.print("dig_T1 27504= ");
Serial.println(dig_T1);
dig_T2 = Coff[1];
Serial.print("dig_T2 26435= ");
Serial.println(dig_T2);
dig_T3 = Coff[2];
Serial.print("dig_T3 -1000= ");
Serial.println(dig_T3);
Serial.println();
dig_P1 = Coff[3];
Serial.print("dig_P1 36477= ");
Serial.println(dig_P1);
dig_P2 = Coff[4];
Serial.print("dig_P2 -10685= ");
Serial.println(dig_P2);
dig_P3 = Coff[5];
Serial.print("dig_P3 3024= ");
Serial.println(dig_P3);
dig_P4 = Coff[6];
Serial.print("dig_P4 2855= ");
Serial.println(dig_P4);
dig_P5 = Coff[7];
Serial.print("dig_P5 140= ");
Serial.println(dig_P5);
dig_P6 = Coff[8];
Serial.print("dig_P6 -7= ");
Serial.println(dig_P6);
dig_P7 = Coff[9];
Serial.print("dig_P7 15500= ");
Serial.println(dig_P7);
dig_P8 = Coff[10];
Serial.print("dig_P8 -14600= ");
Serial.println(dig_P8);
dig_P9 = Coff[ 11];
Serial.print("dig_P9 6000= ");
Serial.println(dig_P9);
Serial.println();
AltitudeFlag=1;
}
// ================== End Reading BMP280-EPROM ===================
//////////////////////////////////////////////////////////////////
// Begin Bosch BMP280 Functions from Data-Sheet
//////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
// This Bosch Function Returns Temperature as double.
// uint16_t dig_T1;
// int16_t dig_T2, dig_T3;
double bmp280_compensate_T_double(int32_t adc_T)
{
double h1, h2, h3, h4, var1, var2, T;
// var1 = (((double)adc_T)/16384.0 – ((double)dig_T1)/1024.0) * ((double)dig_T2); //checked en OK
h1= ((double)adc_T)/16384.0;
h2= ((double)dig_T1)/1024.0;
h3= (double)dig_T2;
var1 = (h1 - h2)*h3;
// var2 = ( ( (adc_T)/131072.0 – (dig_T1)/8192.0 ) * ( (adc_T)/131072.0 – ( dig_T1)/8192.0) ) * (dig_T3); //checked en OK
// var2 = ( (h1 – h2) * (h1 – h2) ) * h3;
h1= ((double)adc_T)/131072.0;
h2= ((double)dig_T1)/8192.0;
h3= (double)dig_T3;
/*
Serial.print("h1= ");
Serial.print(h1,4);
Serial.print(" ");
Serial.print("h2= ");
Serial.print(h2,4);
Serial.print(" ");
Serial.print("h3= ");
Serial.print(h3,4);
Serial.println();
// delay(5000);
*/
h4= ((double)h1)- ((double)h2);
var2= ( h4 * h4 ) * h3;
t_fine = (int32_t)(var1 + var2); //checked en OK
T = (var1 + var2) / 5120.0; //Checked en OK
return T;
}
//---------------------------------------------------------
///////////////////////////////////////////////////////////
//.........................................................
// This Bosch Function Returns pressure as double in mbar.
double bmp280_compensate_P_double(int32_t adc_P)
{
// Press. Calibration data from barometric BMP280 EEProm
// uint16_t dig_P1 =0;
// int16_t dig_P2 =0;
// int16_t dig_P3 =0;
// int16_t dig_P4 =0;
// int16_t dig_P5 =0;
// int16_t dig_P6 =0;
// int16_t dig_P7 =0;
// int16_t dig_P8 =0;
// int16_t dig_P9 =0;
double k1, k2, var1, var2, p;
// var1 = ((double)t_fine/2.0) – 64000.0; //checked en OK
k1= ((double)t_fine/2.0);
var1 = k1 ;
var1 -= 64000.0;
// Serial.println();
// Serial.print("var1 211,1435029= ");
// Serial.print(var1,4);
// var2 = var1 * var1 * ((double)dig_P6) / 32768.0; //checked en OK
k2 = ((double)dig_P6) / 32768.0;
var2 = var1 * var1 * k2;
// Serial.println();
// Serial.print("var2 -9.523652701= ");
// Serial.print(var2,6);
var2 = var2 + var1 * ((double)dig_P5) * 2.0; //checked en OK
// Serial.println();
// Serial.print("var2 59110.65716= ");
// Serial.print(var2,4);
var2 = (var2/4.0)+(((double)dig_P4) * 65536.0); //checked en OK
// Serial.println();
// Serial.print("var2 187120057.7= ");
// Serial.print(var2,1);
var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0; //checked en OK
// Serial.println();
// Serial.print("var1 -4.302618389= ");
// Serial.print(var1,6);
var1 = (1.0 + var1 / 32768.0)*((double)dig_P1); //checked en OK
// Serial.println();
// Serial.print("var1 36472.21037= ");
// Serial.print(var1,4);
if (var1 == 0.0)
{
return 0; // avoid exception caused by division by zero
}
// p = 1048576.0 – (double)adc_P; //checked en OK
k1 = ((double)adc_P);
k2 = 1048576.0;
p = k2 - k1;
// Serial.println();
// Serial.print("p 33428= ");
// Serial.print(p,0);
// p = (p – (var2 / 4096.0)) * 6250.0 / var1; //checked en OK
k1 = (var2 / 4096.0);
k2 = 6250.0 / var1;
p = (p - k1) * k2;;
// Serial.println();
// Serial.print("p 100717.8456= ");
// Serial.print(p,4);
var1 = ((double)dig_P9) * p * p / 2147483648.0; //checked en OK
// Serial.println();
// Serial.print("var1 28342.24444= ");
// Serial.print(var1,5);
var2 = p * ((double)dig_P8) / 32768.0; //checked en OK
// Serial.println();
// Serial.print("var2 -44857.50492= ");
// Serial.print(var2,5);
p = p + (var1 + var2 + ((double)dig_P7)) / 16.0; //checked en OK
// Serial.println();
// Serial.print("p 100653,27= ");
// Serial.print(p,2);
// Serial.println();
// divide p by 99.5 to get mbar values aligned with internet values
p=p/99.5; //mbar
return p;
}
// .............................................................
// /////////////////////////////////////////////////////////////
// End Bosch BMP280 Functions from Data-Sheet
// /////////////////////////////////////////////////////////////
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++ End Source Code Get Altitude from Barometric Pressure +++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++