Hello,
I am building my first real project using an Arduino Uno and the BMP08 and libraries from Adafruit.
I am loading these libraries in my sketch:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
Everything seems to be working fine. I am averaging mutliple readings and using smoothing to try to stabilize readings for an altimeter and Vario project for my ultralight aircraft.
It occurred to me that the following call to the library from my sketch might actually only be calling a math function instead of taking a reading and that I might actually be wasting Arduino time in doing multiple readings and averaging the results from it:
Alt1=(bmp.pressureToAltitude(seaLevelPressure,AvePress,TotTemp));
(The values being passed are the averages from my temperature and pressure readings)
Could you please clarify that for me?
P.S.- I am huge fan of the Adafruit products and company philosophy. This site, libraries you write, and products are making it much easier for a noob like me to feel like I can actually accomplish things with the Arduinio. When I look at forums on other company sites and see the difficulty users are having with the libraries and products it confirms that Adafruit is the place for me to buy from and support.
Thanks,
Lorrin
Is this call using the BMP085 library just for a math conver
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 2
- Joined: Tue Aug 05, 2014 7:17 am
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Is this call using the BMP085 library just for a math co
That function call is strictly a mathematical calculation. It does not take a reading. This is the source code from the library:
Code: Select all
/**************************************************************************/
/*!
Calculates the altitude (in meters) from the specified atmospheric
pressure (in hPa), sea-level pressure (in hPa), and temperature (in �C)
@param seaLevel Sea-level pressure in hPa
@param atmospheric Atmospheric pressure in hPa
@param temp Temperature in degrees Celsius
*/
/**************************************************************************/
float Adafruit_BMP085_Unified::pressureToAltitude(float seaLevel, float atmospheric, float temp)
{
/* Hyposometric formula: */
/* */
/* ((P0/P)^(1/5.257) - 1) * (T + 273.15) */
/* h = ------------------------------------- */
/* 0.0065 */
/* */
/* where: h = height (in meters) */
/* P0 = sea-level pressure (in hPa) */
/* P = atmospheric pressure (in hPa) */
/* T = temperature (in �C) */
return (((float)pow((seaLevel/atmospheric), 0.190223F) - 1.0F)
* (temp + 273.15F)) / 0.0065F;
}
-
- Posts: 2
- Joined: Tue Aug 05, 2014 7:17 am
Re: Is this call using the BMP085 library just for a math co
Thanks!
Lorrin
Lorrin
- jboyton
- Posts: 101
- Joined: Tue Sep 16, 2014 2:52 pm
Re: Is this call using the BMP085 library just for a math co
I want to start out by saying that the BMP180 sensor I have works well, the tutorials on the website are great, and the ready made library functions are really nice to have. It's almost too easy to put this stuff together.
But I have discovered that the Adafruit_BMP085_Unified library function "pressureToAltitude" doesn't work correctly. I searched the forums for discussion of this but maybe nobody else has noticed? It looks like the sparkfun library does the calculation properly.
Near sea level the calculated altitude appears fine. But when I took the sensor to 8000 feet it varied considerably, apparently with changing temperature, and despite a stable absolute pressure reading.
I looked more carefully at the library and example code and noticed a few things.
First, the comments refer to the "Hyposometric" (should be Hypsometric) formula, but that's not what is in the code. This is actually a good thing since it would be the wrong approach.
Second, the formula that is used is incorrect, possibly taken from the flawed wikipedia page (or one of its many internet clones) on the barometric formula. The adafruit function gives nearly identical results to the correct expression near sea level but it diverges at higher elevations. At 8000 feet it calculates a value 400 feet higher than the standard atmosphere formulation. At 12000 feet it would be over 1000 feet higher
Finally, the adafruit example code passes the current sensor temperature instead of the standard sea level base temperature. This is why the altitude varied with temperature even as the pressure remained constant.
Of course, the correct formula for the standard atmosphere doesn't necessarily produce the correct altitude either. But that's a different issue.
But I have discovered that the Adafruit_BMP085_Unified library function "pressureToAltitude" doesn't work correctly. I searched the forums for discussion of this but maybe nobody else has noticed? It looks like the sparkfun library does the calculation properly.
Near sea level the calculated altitude appears fine. But when I took the sensor to 8000 feet it varied considerably, apparently with changing temperature, and despite a stable absolute pressure reading.
I looked more carefully at the library and example code and noticed a few things.
First, the comments refer to the "Hyposometric" (should be Hypsometric) formula, but that's not what is in the code. This is actually a good thing since it would be the wrong approach.
Second, the formula that is used is incorrect, possibly taken from the flawed wikipedia page (or one of its many internet clones) on the barometric formula. The adafruit function gives nearly identical results to the correct expression near sea level but it diverges at higher elevations. At 8000 feet it calculates a value 400 feet higher than the standard atmosphere formulation. At 12000 feet it would be over 1000 feet higher
Finally, the adafruit example code passes the current sensor temperature instead of the standard sea level base temperature. This is why the altitude varied with temperature even as the pressure remained constant.
Of course, the correct formula for the standard atmosphere doesn't necessarily produce the correct altitude either. But that's a different issue.
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Is this call using the BMP085 library just for a math co
If you have a better calculation, please post it. We'll be happy to include it in the library. ;-)
- jboyton
- Posts: 101
- Joined: Tue Sep 16, 2014 2:52 pm
Re: Is this call using the BMP085 library just for a math co
The short answer is: Use what they're using in the sparkfun library.
Here's the long answer:
I was a little too quick to dismiss the Wikipedia entry. It's okay, it's just a little confusing since the lapse rate is a negative number. I think this is the source of one of the problems with the adafruit function.
The equation that the standard atmosphere uses is:
altitude = (T0/L) * [(P0/P)^(LR/Mg) - 1]
where
T0 = base temperature (defined as 288.15°K at sea level in the standard atmosphere)
L = lapse rate (defined as -0.0065 °K/m in the std atmosphere)
P0 = base pressure
P = pressure at altitude
R = gas constant = 8.314 J/K-mol
M = molecular wt of dry air = 28.95 g/mol = 0.02895 kg/mol
g = standard gravity = 9.807 m/s2
So the exponent LR/Mg = -0.1903
This is the same as in the adafruit function (the exact value for M varies depending on the source) except for the sign, which inverts the P0/P term. Similarly the negative value of L reverses the order of what's in the square brackets.
In other words:
altitude = (T0/(-0.0065)) * [(P0/P)^(-0.1903) - 1]
is the same as
altitude = (T0/0.0065) * [1 - (P/P0)^0.1903]
One error in the library function was to miss these negative signs. The other error is that the value T0 refers to the temperature at sea level, not the temperature at altitude. In practice it's often difficult to know T0 (or even P0) so the standard value is used and then an offset is added when calibrating the altimeter to a known elevation:
altitude = (T0/0.0065) * (1 - (P/P0)^0.1903] + offset
or just
altitude = 40331 * (1 - (P/P0)^0.1903] + offset
In Arduino language:
return(44331.0*(1-pow(atmospheric/seaLevel), 0.1903);
I'm pretty new programming the Arduino and I'm not sure if you really need the "F" and (float) that appear in the existing library function.
Here's the long answer:
I was a little too quick to dismiss the Wikipedia entry. It's okay, it's just a little confusing since the lapse rate is a negative number. I think this is the source of one of the problems with the adafruit function.
The equation that the standard atmosphere uses is:
altitude = (T0/L) * [(P0/P)^(LR/Mg) - 1]
where
T0 = base temperature (defined as 288.15°K at sea level in the standard atmosphere)
L = lapse rate (defined as -0.0065 °K/m in the std atmosphere)
P0 = base pressure
P = pressure at altitude
R = gas constant = 8.314 J/K-mol
M = molecular wt of dry air = 28.95 g/mol = 0.02895 kg/mol
g = standard gravity = 9.807 m/s2
So the exponent LR/Mg = -0.1903
This is the same as in the adafruit function (the exact value for M varies depending on the source) except for the sign, which inverts the P0/P term. Similarly the negative value of L reverses the order of what's in the square brackets.
In other words:
altitude = (T0/(-0.0065)) * [(P0/P)^(-0.1903) - 1]
is the same as
altitude = (T0/0.0065) * [1 - (P/P0)^0.1903]
One error in the library function was to miss these negative signs. The other error is that the value T0 refers to the temperature at sea level, not the temperature at altitude. In practice it's often difficult to know T0 (or even P0) so the standard value is used and then an offset is added when calibrating the altimeter to a known elevation:
altitude = (T0/0.0065) * (1 - (P/P0)^0.1903] + offset
or just
altitude = 40331 * (1 - (P/P0)^0.1903] + offset
In Arduino language:
return(44331.0*(1-pow(atmospheric/seaLevel), 0.1903);
I'm pretty new programming the Arduino and I'm not sure if you really need the "F" and (float) that appear in the existing library function.
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Is this call using the BMP085 library just for a math co
Thank you for breaking down the calculation. I'll pass this along to the folks who maintain the library.
- jboyton
- Posts: 101
- Joined: Tue Sep 16, 2014 2:52 pm
Re: Is this call using the BMP085 library just for a math co
The same formula is given on page 16 of the BMP180 datasheet:
http://www.adafruit.com/datasheets/BST- ... 000-09.pdf
http://www.adafruit.com/datasheets/BST- ... 000-09.pdf
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: Is this call using the BMP085 library just for a math co
Ah interesting, the non-unified driver version of the BMP library actually has the same calculation. Check out its readAltitude function:
I'm not sure why the unified sensor version is so different though. I'll take a closer look at it to see if there was a reason it went with the algorithm from Wikipedia.
Code: Select all
float Adafruit_BMP085::readAltitude(float sealevelPressure) {
float altitude;
float pressure = readPressure();
altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));
return altitude;
}
- tdicola
- Posts: 1074
- Joined: Thu Oct 17, 2013 9:11 pm
Re: Is this call using the BMP085 library just for a math co
Just updated the unified sensor version of the BMP085 library to use the same equation. I kept in the interface for the pressureToAltitude function which takes in temperature just to keep compability--the temp is no longer used and the equation from the BMP datasheet is used instead. Thanks for bringing up the issue and explaining it in great detail!
- _starcat
- Posts: 1
- Joined: Tue Nov 08, 2016 8:12 pm
Re: Is this call using the BMP085 library just for a math co
Also the formula changes for calculating altitude in the stratosphere. Up to 22632 Pa / 11 km the equation in the library will hold. When launching helium sounding balloons up to ~32 km I used the equation 3 from here: http://www.mide.com/pages/air-pressure- ... calculator. This assumes a constant temperature of 71.5 K below Sea-level temp and is inaccurate above 20km, but it's an improvement.
Please be positive and constructive with your questions and comments.