Skip to content

Commit cba8b4f

Browse files
Merge pull request #195 from ISSUIUC/feature/baro-altitude
Add altitude calculations to old MS5611 driver. PR looks good, Altitude works!
2 parents d16918c + 3bac74a commit cba8b4f

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

MIDAS/lib/MS5611/MS5611.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939

4040
#include "MS5611.h"
4141

42+
#define MINIMUM_PRESSURE 0.3734
43+
#define MAXIMUM_ALTITUDE 84852.0
44+
#define AIR_GAS_CONSTANT 287.053
45+
#define GRAVITATIONAL_ACCELERATION -9.90665
46+
47+
static const float H[7] = {0, 11000, 20000, 32000, 47000, 51000, 71000}; // base heights of each atmospheric layer (m)
48+
static const float P[7] = {101335, 22632.04, 5474.88, 868.016, 111.09, 66.9385, 3.95639}; // base pressures (Pa)
49+
static const float T[7] = {288.15, 216.65, 216.65, 228.65, 270.65, 270.65, 214.65}; // base temperatures (K)
50+
static const float Lapse_Rate[7] = {-0.0065, 0, 0.001, 0.0028, 0, -0.0028, -0.002}; // base lapse rates (K/m)
51+
// https://www.sensorsone.com/icao-standard-atmosphere-altitude-pressure-calculator/
52+
4253
#include <SPI.h>
4354
SPISettings settingsA(
4455
1000000, MSBFIRST,
@@ -228,4 +239,57 @@ uint32_t MS5611::readADC() {
228239
return val;
229240
}
230241

242+
// (from MS5837)
243+
// https://www.mide.com/air-pressure-at-altitude-calculator
244+
// https://community.bosch-sensortec.com/t5/Question-and-answers/How-to-calculate-the-altitude-from-the-pressure-sensor-data/qaq-p/5702 (stale link).
245+
// https://en.wikipedia.org/wiki/Pressure_altitude
246+
float MS5611::getAltitude(float airPressure)
247+
{
248+
// NOTE: _pressure is in Pascal (#44) and airPressure is in mBar.
249+
float ratio = _pressure * 0.01 / airPressure;
250+
return 44307.694 * (1 - pow(ratio, 0.190284));
251+
}
252+
253+
254+
float MS5611::getAltitudeExtendedModel() // altitude in meters
255+
{
256+
// New formula
257+
258+
// Using the ICAO standard atmospheric model
259+
// valid for altitudes 0-84 km
260+
// assumes a piecewise model of the atmosphere, where each
261+
// layer has a constant temperature lapse rate
262+
// Use pressure to find layer, and then altitude
263+
// TODO: Adjustment from actual temperature vs. expected
264+
// Adjust layer base values
265+
266+
https://www.sensorsone.com/icao-standard-atmosphere-altitude-pressure-calculator/
267+
268+
if(_pressure < MINIMUM_PRESSURE)
269+
{
270+
return MAXIMUM_ALTITUDE;
271+
}
272+
273+
int b = 0; // which layer are we in
274+
while(b < 6)
275+
{
276+
if(_pressure >= P[b + 1])
277+
{
278+
break;
279+
}
280+
++b;
281+
}
282+
if (b == 1 || b == 4) // isothermal, tropopause/stratopause
283+
{
284+
return H[b] + log(_pressure / P[b]) * AIR_GAS_CONSTANT * T[b] / GRAVITATIONAL_ACCELERATION;
285+
}
286+
else // constant temperature gradient
287+
{
288+
return H[b] + (pow(_pressure / P[b], Lapse_Rate[b] * AIR_GAS_CONSTANT / GRAVITATIONAL_ACCELERATION) - 1) * T[b] / Lapse_Rate[b];
289+
}
290+
}
291+
292+
231293
// END OF FILE
294+
295+

MIDAS/lib/MS5611/MS5611.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ class MS5611 {
2929

3030
void init();
3131
int read(uint8_t bits = 8);
32-
inline int32_t getTemperature() const { return _temperature; };
32+
inline float getTemperature() const { return static_cast<float>(_temperature)*0.01; };
3333
inline uint32_t getPressure() const { return _pressure; };
34+
float getAltitude(float airPressure = 1013.25);
35+
float getAltitudeExtendedModel();
3436
inline int getLastResult() const { return _result; };
3537
inline uint16_t getPromValue(uint8_t p) const { return C[p]; };
3638

MIDAS/src/hardware/Barometer.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ Barometer BarometerSensor::read() {
2626
* TODO: Switch to latest version of library (0.3.9) when we get hardware to verify
2727
* Equation derived from https://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_variation
2828
*/
29-
float pressure = static_cast<float>(MS.getPressure() * 0.01 + 26.03); // getPressure is in milibars so it's milibars * 0.01?
30-
float temperature = static_cast<float>(MS.getTemperature() * 0.01); // Celcius
31-
32-
33-
float altitude = static_cast<float>(-log(pressure * 0.000987) * (temperature + 273.15) * 29.254);
29+
uint32_t pressure = MS.getPressure(); // Pascals
30+
float temperature = MS.getTemperature(); // Celcius
31+
float altitude = MS.getAltitude();
3432

3533
return Barometer(temperature, pressure, altitude);
3634
}

MIDAS/src/sensor_data.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct euler_t {
7373
*/
7474
struct Barometer {
7575
float temperature = 0; // Temperature in Celcius
76-
float pressure = 0; // Pressure in millibars
76+
uint32_t pressure = 0; // Pressure in Pascals
7777
float altitude = 0; // Altitude in meters (above sea level?)
7878

7979
Barometer() = default;

0 commit comments

Comments
 (0)