|
|
View previous topic :: View next topic |
Author |
Message |
Cogitum
Joined: 22 Mar 2012 Posts: 70 Location: France (Paris)
|
Best way for Altitude calculation with MS5607 ? |
Posted: Mon Jun 24, 2013 10:03 am |
|
|
Of course the result is wrong with :
Code: |
const DOUBLE R = 287.052; // specific gas constant R*/M0
const DOUBLE g = 9.80665; // standard gravity
const DOUBLE t_grad = 0.0065; // gradient of temperature
const DOUBLE t0 = 273.15 + 15; // temperature at 0 altitude
const DOUBLE p0 = 1013.25; // pressure at 0 altitude
DOUBLE alti =(288.15/65)*(1 - exp(t_grad * (R / g)) * log(P / p0));
|
what can i do ?
µC : 18F25K80
Best regard
compiler 4.132 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Mon Jun 24, 2013 10:34 am |
|
|
The old phrase KISS.
The standard used by aircraft altimeters, is just 1"mercury/1000feet, or 100hectopascals per 800metres.
If you want altitude 'relative' to a starting point, then take a pressure reading at this point, and work relative to this (working from Qfe). If you want an altitude relative to sea level, then input the sea level pressure (Qnh), and work relative to this.
Unless you are intending to go very high, or through large temperature changes etc., don't get too complex.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Mon Jun 24, 2013 10:43 am |
|
|
also consider ...
DOUBLE alti =(288.15/65)*(1 - exp(t_grad * (R / g)) * log(P / p0));
If these are constants...
You do the math of (288.15/65) and use the result, saving PIC doing it
Same with the (R/g) term, also saves a lot of PIC runtime math.
And .. be sure the 'order' of calculation is correct. I find printing off 'partial terms' helps confirm/deny that my math is right!
hth
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 24, 2013 3:12 pm |
|
|
Of course, following the standard on this forum lately, you don't show us
your pressure value 'P' that you got from the MS5607 (for example, 9500).
You don't put it into the equation and show a test program where you
print out the result. You don't tell us your expected result from the
calculation, and compare it to what you are getting. These important
things are left to us, the forum helpers, as an exercise.
You could use the method suggested on page 7 of the Altimeter appnote:
http://www.parallax.com/tabid/768/productid/780/default.aspx
This program gives a result of 366. That's off by 1 from their result of 365.
That's because the code below doesn't round-off the result of the division.
This example below doesn't show the tables (arrays) of i and j that must
be created. The example also doesn't show interpolation of the pressure
to get the desired elements from the tables. It just shows the simple math.
Code: |
#include <18F4620.h>
#fuses INTRC_IO,NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//======================================
void main(void)
{
signed int16 h;
signed int16 j;
signed int16 i;
signed int16 P;
signed int16 Plower;
j = 805;
i = 1802;
P = 9700;
Plower = 9200;
h = j - (((P-Plower) * (signed int32)i) / 2048);
printf("altitude in meters = %ld \n\r", h);
while(1);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 24, 2013 4:20 pm |
|
|
temtronic wrote: | You do the math of (288.15/65) and use the result, saving PIC doing it |
Actually the compiler does pre-calculate expressions like that at compile-time.
This means it's calculated on your Windows PC and not by the PIC micro.
How to prove this ? Make a test program. Using Windows calculator
(or your casio calculator) get the result of 288.15/65, which is 4.4330769.
Then download this zip and drag the floatconv.exe onto your Windows
desktop:
http://www.piclist.com/images/floatconv10.zip
Start up floatconv, select Microchip 32 bit and type in 4.4330769 in the top
box and press Convert to Byte. That gives: 81 0D DB C4
Then compile the program shown below (with vs. 4.141) and look through
the .LST file, looking for those bytes to be loaded as literals. Bingo:
Code: |
00DB0: MOVFF 0C,FEA
00DB4: MOVFF 0B,FE9
00DB8: MOVLW C4 <===
00DBA: MOVWF 2B
00DBC: MOVLW DB <===
00DBE: MOVWF 2A
00DC0: MOVLW 0D <===
00DC2: MOVWF 29
00DC4: MOVLW 81 <===
00DC6: MOVWF 28
|
The result of 4.4330769 is inserted into the ASM code. The PIC itself
does not calculate it. It's done by CCS at compile-time.
Code: |
#include <18F4620.h>
#fuses INTRC_IO,NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#include <math.h>
//======================================
void main(void)
{
const DOUBLE R = 287.052; // specific gas constant R*/M0
const DOUBLE g = 9.80665; // standard gravity
const DOUBLE t_grad = 0.0065; // gradient of temperature
const DOUBLE t0 = 273.15 + 15; // temperature at 0 altitude
const DOUBLE p0 = 1013.25; // pressure at 0 altitude
signed int16 P = 9200;
DOUBLE alti;
alti =(288.15/65)*(1 - exp(t_grad * (R / g)) * log(P / p0));
while(1); |
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Jun 25, 2013 8:45 am |
|
|
That behaviour - of the compiler pre-calculating results of expressions which only involve constants - into an equivalent constant is often called "constant collapse". Not all compilers do it, CCS C does, which is nice.
There are limits to what can be "collapsed" in to equivalent constants, for example math expressions that call C functions, e.g. log(10) is a constant, i.e. about 2.30258, but can't be collapsed by many compilers; CCS C certainly doesn't. That's a pity, because it would sometimes be useful, and such functions take a lot of PIC power. Its partly, at least, a result of such maths being implemented by (library) functions in C, rather than as operators built into the language. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|