Arduino Altimeter
This is a revisit to the CanSat project to share some tips on how to use a simple MPX4115A pressure sensor as an altimeter. In a previous post I shared how to set up the sensor to detect ambient pressure, so now that we have that data, how do we estimate our altitude?
The First Attempt
A somewhat simplistic equation for relating height to pressure is given as:
P=101325(12.25577 x 10^{5}h)^{5.25588}
Here, pressure (P) is given in Pascals, while height (h) is given in meters. We can calculate P from our pressure sensor. We need to rearrange this equation to isolate h.
For simplicity sake, lets replace the coefficients:
Let A = 101325
Let B = 2.25577 x 10^{5}
Let C = 5.25588
Our equation then becomes:
Dividing both sides by A gives:
Raising both sides by 1/C gives:
This can be simplified to:
Subtract 1 from both sides:
Finally divide by B to reveal:
Now that we’ve isolated ‘h’ we can implement a the function in code to calculate it from the sensor pressure reading, and the constant coefficients:
// Read Pressure in Pascals int pressureValue = analogRead(A1); float pressure=((pressureValue/1024.0)+0.095)/0.000009; // Calculate Height using formula above float height = 0.0; float A = 101325.0; float B = 2.25577E05; float C = 5.25588; height = (((pow((pressure/A),1/C))1)/B);
Testing
Testing this code on an Arduino with pressure sensor gave readings of 987.72 hPa ( 98771.71 Pa) and an estimated height of 214.74 meters. This was compared to the local weather station, which gave pressure as 991.4 hPa. Using the GPS feature of my smart phone, it estimated height at between 76 and 84 meters.
As our results show, there are wide discrepancies. These are due to the natural air pressure variation due to weather systems. The first formula doesn’t take atmospheric pressure into account, so even at the same height we could miscalculate our altitude due to high or low pressure weather systems. Although this first attempt is simplistic, it may not be of sufficient accuracy to be useful.
Using the Barometric Function.
The barometric formula is a more sophisticated model of how pressure relates to height. It also takes into account the launch temperature and pressure, so we can calculate a relativistic height (height above/below launch), rather than an absolute one.
The barometric formula is given as:
Where:

h: height in meters

h_{1}: height in meters at launch

T_{1}: Temperature at launch in Kelvin

a: temperature gradient. Constant of 0.0065 Kelvin per meter.

p: Pressure in Pascals

p_{1}: Pressure at launch in Pascals

R: Gas Constant of 287.06 J/kg*K

g: Acceleration due to gravity. Constant of 9.81 m/s^{2}.
This gives us an estimate of altitude based on existing pressure and temperature conditions at launch. To get an accurate measure of altitude we will need to set h_{1} to our height at launch. Otherwise we can assume h_{1} to be zero and we would then be calculating a relative height, with reference to the launch height.
Coding
Assuming we can read the ambient temperature, we can calculate the height relative to launch height, using this Arduino sketch:
float launchTemp; float launchPressure; float launchHeight; // Constants float G = 9.81; float R = 287.06; float A = 0.0065; void setup() { Serial.begin(9600); launchTemp = readTemp(A0); Serial.print("Launch temperature: "); Serial.print(launchTemp); Serial.println(" Kelvin"); launchPressure = readPressure(A1); Serial.print("Launch Pressure: "); Serial.print(launchPressure/100.0); Serial.println(" hPa"); launchHeight = 0.0; } void loop(){ float temperature = readTemp(A0); float pressure = readPressure(A1); float height = getHeight(pressure); float millibars = pressure/100; Serial.println(); Serial.print("Temperature = "); Serial.print(temperature); Serial.println(" K"); Serial.print("Pressure = "); Serial.print(pressure); Serial.println(" pascals"); Serial.print("Pressure = "); Serial.print(millibars); Serial.println(" millibars"); Serial.print("Height = "); Serial.print(height); Serial.println(" meters"); delay(1000); } /* Reads pressure from the given pin. * Returns a value in Pascals */ float readPressure(int pin){ int pressureValue = analogRead(pin); // Serial.print("Vp: "); // Serial.println(pressureValue); float pressure=(((pressureValue/1024.0)+0.095)/0.000009); return pressure; } /* Translates pressure (in Pascals) to height (in meters) */ float getHeight(float pressure){ float height = 0.0; float arg = (A*R)/G; height = (launchTemp/A)*(pow(pressure/launchPressure, arg)1) + launchHeight; return height; } /* * Reads the temperature of a thermister, at the given pin. * Return the temperature as Kelvin */ float readTemp(int pin){ int Vo; // Integer value of voltage reading float Rf = 9830.0; // Fixed resistance in the voltage divider /* * SteinhartHart Equation coefficients. * Calculated from datasheet reference temps/resistances. */ float c1 = 1.3084634E03; float c2 = 2.344772E04; float c3 = 1.04177209450756E07; float logRt,Rt,T; Vo = 1023  analogRead(pin); // Read thermister voltage Rt = Rf*( 1023.0 / (float)Vo  1.0 ); // Calculate thermister resistance logRt = log(Rt); // Apply SteinhartHart equation. T = ( 1.0 / (c1 + c2*logRt + c3*logRt*logRt*logRt ) ); return T; } float kelvinToCelcius(float temp){ return temp  273.15; }
Testing
On testing, we receive output similar to:
Launch temperature: 295.46 Kelvin Launch Pressure: 986.63 hPa Pressure = 98663.20 pascals Pressure = 986.63 millibars Height = 0.00 meters Pressure = 98771.71 pascals Pressure = 987.72 millibars Height = 9.50 meters
As we can see, the signal from the pressure sensor seems noisy. Our rate of error is frequent, and puts us out by close to 10 meters, which is significant. Further approaches to calibration, and reducing the errors will have to be considered to improve sensor resolution.
Tags: Altimeter, Arduino, barometer, CanSat, computer, electronics, engineering, Firmware, How To, IoT, Open Source, pressure, software, Temperature, Ubiquitous Computing
Search
Copyright Notice.
Blog entries are licensed under a Creative Commons AttributionShare Alike 3.0 Unported License. Blog comments are copyright to their respective authors.
Top Posts
 Testing SD Cards with Linux
 How To Measure Air Pressure with Arduino
 How to change date formats on Ubuntu
 How to Share a Folder on Raspberry Pi
 A Brief History of XML
 Getting Subversion Revision in Ant
 Unified Process vs Agile Processes
 Temperature Sensing with Arduino
 Introduction to the Zachman Framework
 History of SQL
Archives
 July 2017
 March 2016
 January 2016
 July 2015
 May 2015
 April 2015
 March 2015
 February 2015
 January 2015
 August 2014
 March 2014
 January 2014
 December 2013
 February 2013
 January 2012
 March 2011
 January 2010
 October 2009
 July 2009
 April 2009
 March 2009
 February 2009
 January 2009
 November 2008
 October 2008
 June 2008
 March 2008
 February 2008
 January 2008
 December 2007
 November 2007
 October 2007
 July 2007
 June 2007
 May 2007
 November 2006
 October 2006
 September 2006
Recent Comments