Shop OBEX P1 Docs P2 Docs Learn Events
Parallax's New Altimeter/Barometer Module — Parallax Forums

Parallax's New Altimeter/Barometer Module

Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
edited 2013-08-08 16:36 in Accessories
For the past couple weeks I've been privileged to work with Parallax's Kevin Cook on the Propeller software for Parallax's new altimeter/barometer module (#29124). Ken suggested that I share my experiences with this module and the object I wrote for it here. So I shall try to describe Parallax's module and what I did with the software (and why) in the paragraphs that follow.

Here's a sneak peek at the module itself:
attachment.php?attachmentid=85403&d=1317065645

It is based on the Measurement Specialties MS5607 temperature and pressure sensor chip (the little white thing with the two holes in it). Basically, the chip provides raw temperature and pressure data through either an SPI or I2C interface. It also provides chip-specific factory calibration data from an internal PROM in order to facilitate the computation of accurate temperatures and temperature-compensated pressures. Beyond that, it's the programmer's responsibility to convert the raw data into calibrated temperature and pressure readings and, from there, to usable altimeter and barometer data.

When presented with this task, my first question was, "If I were using this module, what services would I expect from a Propeller object that supports it?" In order to answer this question, I needed to acquaint myself with basic barometry and altimetry.

The Basics

The sensor in this module measures temperature and absolute pressure, and outputs data in digital form from its built-in 24-bit ADC. Due to process variations, the gain and offset of these readings will vary from part to part. These variances are measured at the factory, and correction factors are programmed into each sensor's PROM, which the user must apply to obtain correct readings. Also, because pressure increases with temperature, the temperature reading has to be used to adjust the pressure reading to obtain a temperature-compensated pressure value. These calculations can all be accomplished using multiplies and shifts in 64-bit integer math -- something that, with some effort, can be accommodated by Spin. So far, so good.

The pressure measured by the sensor in free air is atmospheric pressure, which varies with changes in the weather and with changes in altitude. Pressure decreases with altitude, so a pressure sensor at sea level will indicate a higher value than the same sensor at, say, 1000 feet. When you hear a weather report that includes a barometer reading in millibars or inches of mercury, the reading is always corrected to sea level. In other words, the local pressure in Denver, say, at a one-mile elevation, will be adjusted to reflect what the pressure would be if measured at the bottom of a one-mile-deep hole.

So how does pressure vary with altitude? Or, more usefully, if you know the local air pressure, how do you compute your altitude from that? The following formula yields altitude in terms of pressure for the troposphere (i.e. from below sea level to 11 km):
attachment.php?attachmentid=85400&d=1317064723

where Altitude is in meters. P is the local air pressure, and P0 is the pressure at sea level, both expressed in the same units, whether millibars, Pascals, or inches of mercury. When P0 is set equal to the standard sea level pressure of 1013.25 mb, the altitude yielded by the formula is called the "pressure altitude." The actual altitude may be computed by substituting the local air pressure, corrected to sea level, for P0.

Implementation

Clearly, the above is an unfriendly formula for the Propeller's native integer math. My first reaction was that I would have to use the Float32 object to pull this off. But that comes at a cost of one more cog and additional heft, memory-wise. The other option was to pre-compute the function at equally-spaced points to produce a table and use interpolation to get the intervening values. Unfortunately, for any table of a reasonable size, linear interpolation does not produce adequately-accurate results. So I reached back to some derivations I did about thirty years ago for CNC milling smooth curves in molds for fishing lures via cubic interpolation.

Whereas linear interpolation involves just the two tabular values on either side of the independent variable and the straight line between them, cubic interpolation takes advantage of four tabular values (two to the left and two to the right) and the third-order polynomial that intersects all of them. In this way the actual curve's convexities and concavities can be approximated more closely. The basic formula is this:
y(x) = yi-1(-a3/2 + a2 - a/2) + yi(3a3/2 - 5a2/ 2 + 1) + yi+1(-3a3/2 + 2a2 + a/2) + yi+2(a3/2 - a2/ 2)

where y(x) is the interpolated value at a = (x - xi) / (xi+1 - xi), assuming the y's in the table are all calculated at equally-spaced x values; and i is chosen such that x is between xi and xi+1.

This formula can be computed with integer math. By spacing the x values in the table at power-of-two multiples of the real x values, i can be computed by shifting x to the right. a, then, is just the least-significant bits that got shifted out.

The table was computed in Perl using standard pressure in hundredths of a millibar (i.e. 101325) for P0 to produce altitude values in whole centimeters (i.e. hundredths of a meter). This was done using 65 equally-spaced values for P (also in hundredths of a millibar), yielding an altitude range of -2086 meters to +23230 meters.

In order to use the table with P0 values other than standard sea-level pressure, the P value must first be corrected, as follows:
P := P * P0(standard) / P0(actual)

Then the interpolation can proceed as described above.

Use as a Barometer

To use the module as a barometer to obtain the local air pressure, one need only read the data and apply the calibration and temperature corrections to obtain a value in hundredths of a millibar. However, to get the air pressure corrected to sea level (as a real weather station would do), you have to know your altitude (i.e. elevation if on land). The question then becomes, "Given the local pressure reading, at what sea-level pressure does the altitude formula produce my current altitude?" Rather than producing yet another table that inverts the altitude formula, I decided to use a binary search, with the presumptive sea-level pressure being the independent variable whose value we want to zero in on. This method turned out to yield an accurate result very quickly.

Use as an Altimeter

To use the module as an altimeter, you have to know both the local pressure (which the sensor gives you) and the corrected sea-level pressure for your location. The latter can be a bit tricky to obtain. For one thing, there may not be a weather station at your x,y coordinates to provide this information. For another, the sea-level pressure can change, due to changing weather conditions. One solution is to start from a known altitude and compute the sea-level pressure as described above for a barometer, then use this value with the changing local pressure to compute your current altitude. Of course, if the weather changes during your travel, the altitude readings become inaccurate again. This is why pilots, when approaching an airport, will radio ahead for its sea-level-corrected barometric reading, so they can adjust their altimeters accordingly, using the knob and little window circled here:
attachment.php?attachmentid=85398&d=1317064721

The Spin object provides the same facilities: you can adjust the sea-level pressure either directly by providing the correct value, or indirectly by providing your current altitude and local air pressure.

Foreground and Background Operation

The MS5607 datasheet suggests averaging multiple temperature and pressure readings to get a stable value for each. Depending on the chosen resolution -- and there are five to choose from -- acquiring and averaging a bunch (33 in this case) of readings can take a bit of time. For this reason, I decided to include an optional background mode, wherein a separate cog is started that continuously reads the sensor, performs the temperature and pressure corrections, and averages the last 33 readings. As a bonus, it also keeps a running tab of the median value of the last 33 readings, in case it's preferred over the mean (average). The median can be handy for eliminating spurious readings when, for example, the device is in your car and you slam the door, causing an instantaneous increment in air pressure. With the median, that errant value is simply shunted to one end or the other of the range of values and ignored. With the mean, the errant value would be averaged into the result, skewing it a bit.

In order to ensure that all values requested at a certain time come from the same batch of 33 readings, I've included pause and resume methods for the background process. These can also be used when the sensor shares its I2C port with other devices, in order to avoid conflicts when those devices are accessed.

Documentation

The object was created with Gold Standard autodoc tags and comments. Here's a link to the autodoc file:

Test Results

I'm not going to release the actual object just yet, since it requires more testing first. However, my confidence has been bolstered by the results I've seen so far. I borrowed a Garmin GPS that has a built-in barometric altimeter from a friend of mine to obtain comparative readings between it and the module. I attached the module to a Proto-DB, plugged into a battery-powered Spinneret, which was programmed to record altitude values on a micro-SD card via Kye's file driver object. Along with each module value was also recorded the altitude value from the Garmin (which was running with its GPS disabled). At the outset of each test, both the Garmin GPS and the Parallax module were initialized to the same known altitude. Here are two graphs which plot the Garmin and Parallax altitude readings superimposed on each other:

attachment.php?attachmentid=85401&d=1317064725
Readings taken while driving around town.

attachment.php?attachmentid=85399&d=1317064722
Readings taken between Quilcene, WA, and the summit of Mt. Walker and back.

So far, I'm pretty happy with the results, and I think the Parallax barometer/altimeter module is going to be an excellent product!

-Phil
400 x 400 - 133K
270 x 63 - 4K
612 x 462 - 21K
326 x 302 - 37K
«134

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-09-26 13:43
    Phil,

    This is very interesting and very cool. Thanks for all this information. I look forward to seeing the object.

    I foresee altimeters in my RC airplanes and helicopter in the near future.

    With the right tubing and enclosure I could use a second sensor as an airspeed indicator.

    Duane
  • PublisonPublison Posts: 12,366
    edited 2011-09-26 14:04
    Phil,

    A most excellent pre document report, (as always). Looking forward to the product, makes the WiFi EOL seem a little bit less of a blow :)
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-09-26 14:18
    Great introduction Phil. I'm working with Kevin on BASIC Stamp code for this module. Oh, my! No cubic splines or 64 bit math or background processes for me!

    I've used previous versions of the MSI (formerly Intersema) sensors, MS5534 and MS5540, and this new one is similar in terms of the parsing and calculations. The basics of the interface take quite a bit of code space, and I've put all of those basics in one slot of a BS2p_, kind of like a separate spin object if not cog, and then the application gets the data or increments the accumulators/filters with a cross-slot call. I'm not sure how I'll handle it with a vanilla BS2. I have a couple of demos written that show data in tabular or ascii graphic format, like a variometer. An accurate full-range altimeter may be out of the question. Linearization around a datum altitude/pressure is the key for most practical applications anyway, I believe.

    This harks back to Ken's request that led to this product offering... Pressure-sensors-as-altimeters-seeking-your-important-customer-input!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-09-26 14:38
    Thanks, Tracy. I'm glad to hear you're involved! When Ken asked whether the BASIC Stamp could handle it, I immediately replied, "I don't know; but if it can, Tracy Allen would be the one to make it happen." I don't envy you the contortions you must be enduring to make it all fit! (At least you don't have to undo the effects of Spin's default signed math, if that's any consolation. :) )

    -Phil
  • ElectricAyeElectricAye Posts: 4,561
    edited 2011-09-26 15:18
    Totally cool!
    I bet the rocket and balloon peeps are gonna love this thing.
  • Kevin CookKevin Cook Posts: 159
    edited 2011-09-26 17:05
    Nice write-up Phil,

    I took this module up to Wrights Lake (7000 feet) over the weekend. I started it off at home (120 feet) and monitored the module’s output the entire 3.5 hour trip. As we made our way up the mountain, I watched out for every altitude marker on the side of the road. All in all the accuracy was amazing! By the time I was at my destination I was reading 6898 feet, this was a little over 70’ off what it should be reading. Some may think that’s a problem, but this was over 3.5 hours and a noticeable weather difference (clouds at the mountain and clear sky at home). I made no adjustments or corrections during that time to compensate for pressure changes due to weather conditions. I made the same test on the way home and results where nearly the same, with only about 50’ off what I expected.

    Also, something to mention here, during my trip the sunlight would occasionally directly hit the sensor and when it did, it would cause an altitude shift of about 200’, something I will note in the documentation. Once the sun was off the sensor it was back to normal operation.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-09-26 17:21
    Thanks, Kevin. 'Glad to hear you got good results up to 7000'. BTW, the same "altitude shift" phenomenon happened on my Mt. Walker excursion yesterday. The last altitude reading in Quilcene was actually right at sea-level, even though I had started and stopped at the same location, 40ft. above sea-level. But the barometer had risen significantly during the one-hour drive, according the the online barograph I checked when I got home.

    -Phil
  • bsnutbsnut Posts: 521
    edited 2011-09-26 19:46
    Nice write-up Phil. Its well documented both here and your website.
  • john_sjohn_s Posts: 369
    edited 2011-09-26 21:10
    Phil,

    In case you happened to use Garmin Rino 530HCX when doing the comparison - here's a picture of what's inside.
    Their pressure sensor looks quite similar to SCP1000

    530HCx back.jpg
    1024 x 408 - 95K
  • sylvie369sylvie369 Posts: 1,622
    edited 2011-09-27 03:55
    Totally cool!
    I bet the rocket and balloon peeps are gonna love this thing.

    We rocket people are paying close attention.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-09-27 07:54
    Rocketry folks may want to alter the object to reduce the number of terms used for averaging (simple constant change) -- or not do any averaging at all.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-09-27 09:27
    I've updated the online HTML doc with some comment corrections and also added a couple sample programs. The actual code has not changed.

    -Phil
  • PublisonPublison Posts: 12,366
    edited 2011-10-14 12:26
    Any projected date for this module?

    Looks QuadCopter ready :)

    Jim
  • markustermarkuster Posts: 184
    edited 2011-10-21 11:42
    Hi,

    Just to know how I can use the Altimeter/Barometer Module with the
    Basic Stamp 2P.

    Thanks, Mark
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-10-21 13:11
    Hi Mark,

    Yes, you can read this sensor with the BS2p. I've been working up code for that, a work in progress. I had to put it aside for a while, but I'm attaching two BS2 programs that could get you started. Always, the first question is, "can I read the values from the chip?" These go through the basics of resetting the chip, reading out the calibration parameters and the raw data. This chip can operate in either I2C mode or in SPI mode, so there is one program for each. The SPI program will run on any stamp using the SHIFTIN and SHIFTOUT commands, while the I2C program will run only on '2p series, which support the I2CIN and I2COUT commands.

    If you use the SPI version, it is essential to include a 4.7K ohm pulldown resistor from the sdo pin to ground. (It took me a while to figure that out!) For I2C mode, the pullup resistors on sda and scl are built into the module.

    Now, these programs go only so far as to extract the raw data from the chip. I takes some math to convert to real pressure and temperature units, and it's pretty knarly math for a BASIC Stamp. Not in principal, however the way they have it parsed in the data sheet it involves multiple precision signed integers, up to 41 bits. I've been cogitating about other ways to arrange it and will post more code in a followup message. Once we have the pressure, then it's on to altitude, which I've done before with the MS5534 an earlier pressure/altimeter sensor from MSI. I am sure it can be effective with a BS2p series Stamp, but I'm not so sure about the original BS2 where the ram is more limiting.
  • Tom.in.MarylandTom.in.Maryland Posts: 17
    edited 2011-10-21 13:32
    I am very interested in this module I Please advise is this SPI output? I2C output or some other ? Is there a regeister map for reading it with a microcontroller? Does the math need to be done in the microcontroller, or is there an actual barometric pressure output? I want to use for barometer.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-10-21 13:36
    The module has both I2C and SPI interfaces -- take your pick. The datasheet includes a register map. The math has to be done by the connected microcontroller; the module provides only the raw data.

    -Phil
  • Cluso99Cluso99 Posts: 18,069
    edited 2011-10-21 13:49
    Just a note about the altitude over time... Barometric pressure has cyclic changes over the day and night. So the altitude errors you are seeing over 3/5 hours could also be due to this.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2011-10-21 15:00
    Excellent work! Those comparisons look fantastic.

    Graham
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-11-14 13:08
    Phil,

    I picked up one of the Altimeter modules from Radio Shack and started playing with it today. I'm using your 29124_Altimeter_Demo straight out of the .zip file. I'm not seeing the results expected and I'm not sure if it's me or the module at this point.

    According to my iPhone, the GPS altitude of my desk is 1190ft (+/-6ft).
    The local barometric pressure is about 29.55
    The desktop temperature where the Quickstart and altimeter module are has stabilized at about 79.8F

    If I enter i2955 to the demo program, I get this:
    +-------------------------------------------------------------+
    |             Parallax #29124 Altimeter Readings              |
    +-------------+---------------+---------------+---------------+
    |             |    Current    |    Average    |    Median     |
    +-------------+---------------+---------------+---------------+
    | Temperature |     30.31°C   |     30.30°C   |     30.31°C   |
    |             |     86.55°F   |     86.54°F   |     86.55°F   |
    +-------------+---------------+---------------+---------------+
    |   Local     |    479.20 mb  |    479.21 mb  |    479.21 mb  |
    |  Pressure   |     14.15 in  |     14.15 in  |     14.15 in  |
    +-------------+---------------+---------------+---------------+
    |  Altitude   |   5794.89 m   |   5795.19 m   |   5795.19 m   |
    |             |  19012.11 ft  |  19013.09 ft  |  19013.09 ft  |
    +-------------+---------------+---------------+---------------+
    |  Sea Level  |               |   1000.64 mb  |               |
    |  Pressure   |               |     29.55 in  |               |
    +-------------+---------------+---------------+---------------+
    
    If I enter f119000 to the program, I get this:
    +-------------------------------------------------------------+
    |             Parallax #29124 Barometer Readings              |
    +-------------+---------------+---------------+---------------+
    |             |    Current    |    Average    |    Median     |
    +-------------+---------------+---------------+---------------+
    | Temperature |     30.27°C   |     30.27°C   |     30.27°C   |
    |             |     86.48°F   |     86.48°F   |     86.48°F   |
    +-------------+---------------+---------------+---------------+
    |   Local     |    479.24 mb  |    479.24 mb  |    479.24 mb  |
    |  Pressure   |     14.15 in  |     14.15 in  |     14.15 in  |
    +-------------+---------------+---------------+---------------+
    |  Altitude   |    362.71 m   |    362.71 m   |    362.71 m   |
    |             |   1189.99 ft  |   1189.99 ft  |   1189.99 ft  |
    +-------------+---------------+---------------+---------------+
    |  Sea Level  |               |    500.39 mb  |               |
    |  Pressure   |               |     14.78 in  |               |
    +-------------+---------------+---------------+---------------+
    

    The temperature and local pressure aren't at all what I was expecting to see. That air pressure put me at about 19,000 ft in altitude...not bad for Ohio!

    Any thoughts? Misunderstanding the demo? Did I miss something in the code I was supposed to set? bad module? Calibration issues?

    Thanks for your help!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-11-14 13:24
    Rick,

    I've spent a lot of time in Ohio, so I know that 19,000 ft is a "bit" off. Take a look at the little white sensor chip on the module, and tell me what the part number is (first four digits). There are two possible parts for which demo code was written, and it looks from your results as if your sensor and demo code do not match.

    -Phil

    Okay, I see the problem. The demo is set up for the 5611 chip, and it needs to be for the 5607 chip. You can modify the code as follows (assuming you're using it with the QuickStart board):
    PUB  start | data, reading, unit, s
    
      pst.start(38400)
      alt.start(alt#QUICKSTART | [b][color=red]alt#MS5607[/color][/b], alt#BACKGROUND)
      alt.set_resolution(alt#RES_4096)
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-11-14 13:39
    It looks like 612673B...parts are getting too small!!!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-11-14 13:47
    You're reading it upside down. I'm sure it's a 5607. See my addendum above.

    -Phil
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-11-14 13:50
    Much better! Thanks!
    +-------------------------------------------------------------+
    |             Parallax #29124 Barometer Readings              |
    +-------------+---------------+---------------+---------------+
    |             |    Current    |    Average    |    Median     |
    +-------------+---------------+---------------+---------------+
    | Temperature |     31.04°C   |     31.04°C   |     31.05°C   |
    |             |     87.87°F   |     87.87°F   |     87.89°F   |
    +-------------+---------------+---------------+---------------+
    |   Local     |    958.55 mb  |    958.55 mb  |    958.55 mb  |
    |  Pressure   |     28.31 in  |     28.31 in  |     28.31 in  |
    +-------------+---------------+---------------+---------------+
    |  Altitude   |    362.71 m   |    362.71 m   |    362.71 m   |
    |             |   1189.99 ft  |   1189.99 ft  |   1189.99 ft  |
    +-------------+---------------+---------------+---------------+
    |  Sea Level  |               |   1000.85 mb  |               |
    |  Pressure   |               |     29.56 in  |               |
    +-------------+---------------+---------------+---------------+
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-11-14 14:09
    Sadly, it wasn't upside down....I just couldn't read the actual part # until I took a close-up photograph and blew it up (MORE) in Photoshop! My eyes are worse than I thought!

    5607.jpg


    <Insert Wilder/Feldman Young Frankenstein dialog here>

    It would have helped if I had read your excellently documented code BEFORE calling 9-1-1, too.

    Thank you.
    770 x 1052 - 312K
    5607.jpg 311.9K
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-11-14 14:16
    I'm glad you posted. The MS5611 flag was vestigial from the first proto module that Parallax sent me, and I had just forgotten to change it. I've sent Kevin Cook a corrected zip file to post on the product page.

    Thanks for calling it to my attention!

    -Phil
  • abmcdanabmcdan Posts: 7
    edited 2011-11-30 20:31
    Thanks for code Tracy.

    I'm using this Altimeter with a Basic Stamp 2 and board of education USB. (SPI)

    This is the raw output I'm getting, is this correct?
    raw_data.jpg



    Does anyone have the math code to convert the pressure and temperature to usable numbers? The pressure is the one I need for my project.

    Any help will be greatly appreciated.

    Thank you,
    Andy
    277 x 145 - 17K
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-11-30 22:51
    Yes, that is the correct output. You are seeing the raw temperature and pressure readings, and also the coefficients that allow conversion of those to standard temperature and pressure in in degrees Celsius and millibar. Thanks for posting your results, and welcome to the forum!

    I did get a chance to work on the math required to take the next step, and I'll will post what I came up with shortly. As you can see from the data sheet or from Phil's spin code, the raw readings and the intermediate results involve very large numbers. It has been a challenge to squeeze it into the limited RAM and 16 bit integers of the BASIC Stamp and PBASIC .
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2011-12-01 09:07
    Okay, here are two demo programs for the BASIC Stamp. One uses the SPI interface and SHIFT commands that are common to the whole family, while the second uses the i2c interface that is available only on the BS2p series.

    The demo program merely displays on the debug screen current values of the temperature and pressure as they are reported by the module, crunched to units of degrees Celsius and millibar. Functions of barometer (with altitude correction) and altimeter are yet to come, but this program has the essentials to get you started on your own. In the vanilla BASIC Stamp there is not much RAM memory left to work with, but some things can be done, we'll see. The situation is much better if you have more RAM available, such as the scratchpad RAM on the multi-slot Stamps, or external RAM in something like a real time clock chip.

    Please report bugs or issues you have with the programs, or success too, of course.

    Edit: Updated programs, now include code for 2nd order temperature compensation at low (< 20 °C) temperatures.
    Edit: New photo, eliminated kluge pulldown resistor on sdo, see discussion in followup post below.
  • abmcdanabmcdan Posts: 7
    edited 2011-12-01 09:44
    You rock Tracy.

    My temp is reading 20 which matches my wall unit.

    My pressure seems off though. It's reading 655.36 and giving a "overpressure error!"
Sign In or Register to comment.