Altimeter Module MS5607 wrong altitude

Hi!
I've recently bought a Altimeter Module, but when I open Serial Monitor, the altimeter only gives negative results.
I'm using :
-Windows 7
-Arduino Duemilanove
-Altimeter Module MS5607 ( http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/altimeter/List/0/SortField/4/ProductID/780/Default.aspx )
-Arduino 1.0
-The program on this link ( http://sites.google.com/site/parallaxinretailstores/home/altimeter-module-ms5607 )
I have followed the instructions correctly on this page ( http://sites.google.com/site/parallaxinretailstores/home/altimeter-module-ms5607 )
Is there anyway to calibrate the sensor ? Or is it something wrong in the programming ?
These are the results I'm getting :

Centimeters: -27629.00, Feet: -906.46
Centimeters: -27638.00, Feet: -906.76
Centimeters: -27629.00, Feet: -906.46
Centimeters: -27647.00, Feet: -907.05
Centimeters: -27647.00, Feet: -907.05
Centimeters: -27621.00, Feet: -906.20
Centimeters: -27629.00, Feet: -906.46
Centimeters: -27647.00, Feet: -907.05
Centimeters: -27621.00, Feet: -906.20
Centimeters: -27655.00, Feet: -907.32
Centimeters: -27655.00, Feet: -907.32
Centimeters: -27629.00, Feet: -906.46
Centimeters: -27647.00, Feet: -907.05

Definitly not good
Anyone who knows a solution ?
Sorry for my bad English, I'm Dutch.

Many thanks !

FRR

From NL too (there is a dutch section too you know)

Negative values can be caused by an overflow of a datatype. Check .... and yes.

The sample application has a bug. getHeightCentiMeters() returns an int32_t ... not an int so that may be the cause

#include <Wire.h> 
#include "IntersemaBaro.h"

Intersema::BaroPressure_MS5607B baro(true);

void setup() { 
    Serial.begin(9600);
    baro.init();
}

void loop() {
  long alt = baro.getHeightCentiMeters();   // <<<<<< CHANGED
  Serial.print("Centimeters: ");
  Serial.print((float)(alt), 2);
  Serial.print(", Feet: ");
  Serial.println((float)(alt) / 30.48, 2);
  delay(400);
}

give it a try.

Hi!

Thanks for the quick reply!
Didn't know there was a dutch section here.
I've tried the new code and I'm getting positive results! So that's good :grin:
But the results are still not correct as you can see :
Centimeters: 41187.00, Feet: 1351.28
Centimeters: 41213.00, Feet: 1352.13
Centimeters: 41187.00, Feet: 1351.28
Centimeters: 41170.00, Feet: 1350.72
Centimeters: 41196.00, Feet: 1351.57
Centimeters: 41170.00, Feet: 1350.72
Centimeters: 41144.00, Feet: 1349.87
Centimeters: 41152.00, Feet: 1350.13
Centimeters: 41144.00, Feet: 1349.87
Centimeters: 41144.00, Feet: 1349.87
Centimeters: 41161.00, Feet: 1350.43
Centimeters: 41161.00, Feet: 1350.43
Centimeters: 41187.00, Feet: 1351.28
Centimeters: 41161.00, Feet: 1350.43
Centimeters: 41170.00, Feet: 1350.72
Centimeters: 41170.00, Feet: 1350.72
Centimeters: 41178.00, Feet: 1350.98
Centimeters: 41187.00, Feet: 1351.28
Centimeters: 41196.00, Feet: 1351.57
Centimeters: 41204.00, Feet: 1351.84
Centimeters: 41178.00, Feet: 1350.98
Centimeters: 41161.00, Feet: 1350.43
Centimeters: 41204.00, Feet: 1351.84
Centimeters: 41161.00, Feet: 1350.43
I think you need to calibrate the altimeter, but I don't find any way to do that.
I have found one way, but it's a bit cheating.
So if you have this result for example : Centimeters: 41204.00, Feet: 1351.84
If you (in the IntersemaBaro.h) have the results, you can do the result - 41204.00 (centimeter) = 0 centimeter.(I think)
So it's calibrated to where you're standing. Is this good ? Or are there other (better :stuck_out_tongue: ) ways to calibrate it.

Thanks!

FRR

Can the sensor read the atmospheric pressure (barometer).
That's something easy to calibrate. Most local weather station will have it on it's website.

Hi,
I have just looked at the data sheet p7 for your sensor and it seems to be using the same calculations as the MS5611 which is discussed over at "Pressure Sensors MS5611 MS5803". Give the code there a try perhaps with Leo's corrections and include the latest couple of lines for the altitude and see what you get.
I also gave this code a try on the 5803 and did not get good results although I have not had time as of yet to investigate further. I would be interested to see if it works on yours.
Best
Vanja

"Pressure Sensors MS5611 MS5803" thats there ==> - http://arduino.cc/forum/index.php/topic,103377 -

Hi !

Thanks for the reply's!
@ Krodal:
I wouldn't know how to get the Atmospheric Pressure.
If I write: Serial.print(Pressure);
It gives an error: error: 'Pressure' was not declared in this scope

@ Vanja and Robtillaart:
I've tried the code from the Pressure Sensors MS5611 MS5803...
First the normal code without changes:
The result:
PROM COEFFICIENTS ivan
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Then I tried Leo's code:

PROM COEFFICIENTS ivan
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0
Error reading PROM 1
0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

Actual TEMP= 20.00 Actual PRESSURE= 0.00
RAW Temp D2= 4294967295 RAW Pressure D1= 4294967295

C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0
C6 = 0

The same results...
But then i've changed the #define ADDRESS 0x77 //0x76 to 0x76
Then I get these results... the temperature works fine I think. I've put the sensor outside and the temperature drops , but when it reaches 20 degrees, it's not correct .
Actual TEMP= 21.01 Actual PRESSURE= 504.23
RAW Temp D2= 8309316 RAW Pressure D1= 6239926

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 20.75 Actual PRESSURE= 504.26
RAW Temp D2= 8301170 RAW Pressure D1= 6241510

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 20.54 Actual PRESSURE= 504.26
RAW Temp D2= 8294964 RAW Pressure D1= 6242566

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 20.32 Actual PRESSURE= 504.26
RAW Temp D2= 8288212 RAW Pressure D1= 6243750

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 20.11 Actual PRESSURE= 504.29
RAW Temp D2= 8281746 RAW Pressure D1= 6245034

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 141086.15 Actual PRESSURE= 156428.96
RAW Temp D2= 8275998 RAW Pressure D1= 6245854

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 141086.01 Actual PRESSURE= 156495.70
RAW Temp D2= 8271354 RAW Pressure D1= 6246866

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 141085.90 Actual PRESSURE= 156532.20
RAW Temp D2= 8267988 RAW Pressure D1= 6247420

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552
The problem is when it reaches below 20 degrees.
The pressure isn't correct either.
Any solutions?

Many Thanks!!!

FRR

Edit: Opps, I just realised you have a MS5607. Dunno if the <20°C code works.

Nonetheless, I did add the code for the MS5611. You might have to modify it for the MS5607.

#include <Wire.h>
#define ADDRESS 0x76 //0x77

uint32_t D1 = 0;
uint32_t D2 = 0;
int64_t dT = 0;
int32_t TEMP = 0;
int64_t OFF = 0; 
int64_t SENS = 0; 
int32_t P = 0;
uint16_t C[7];

float Temperature;
float Pressure;


void setup() {
// Disable internal pullups, 10Kohms are on the breakout
 PORTC |= (1 << 4);
 PORTC |= (1 << 5);

  Wire.begin();
  Serial.begin(9600); //9600 changed 'cos of timing?
  delay(100);
  initial(ADDRESS);

}

void loop()
{
  D1 = getVal(ADDRESS, 0x48); // Pressure raw
  D2 = getVal(ADDRESS, 0x58);// Temperature raw

  dT   = D2 - ((uint32_t)C[5] << 8);
  OFF  = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
  SENS = ((int32_t)C[1] << 15) + ((dT * C[3]) >> 8);

  TEMP = (int64_t)dT * (int64_t)C[6] / 8388608 + 2000;

  if(TEMP < 2000) // if temperature lower than 20 Celsius 
  {
    int32_t T1    = 0;
    int64_t OFF1  = 0;
    int64_t SENS1 = 0;

    T1    = pow(dT, 2) / 2147483648;
    OFF1  = 5 * pow((TEMP - 2000), 2) / 2;
    SENS1 = 5 * pow((TEMP - 2000), 2) / 4;
    
    if(TEMP < -1500) // if temperature lower than -15 Celsius 
    {
      OFF1  = OFF1 + 7 * pow((TEMP + 1500), 2); 
      SENS1 = SENS1 + 11 * pow((TEMP + 1500), 2) / 2;
    }
    
    TEMP -= T1;
    OFF -= OFF1; 
    SENS -= SENS1;
  }


  Temperature = (float)TEMP / 100; 
  
  P  = ((int64_t)D1 * SENS / 2097152 - OFF) / 32768;

  Pressure = (float)P / 100;
  
  Serial.print("     Actual TEMP= ");
  Serial.print(Temperature);
  Serial.print("      Actual PRESSURE= ");
  Serial.print(Pressure);

  Serial.println();  
  Serial.print(" RAW Temp D2=  ");
  Serial.print(D2);
  Serial.print(" RAW Pressure D1=  ");
  Serial.println(D1);
  Serial.println();

//  Serial.print(" dT=  ");
//  Serial.println(dT); can't print int64_t size values
  Serial.println();
  Serial.print(" C1 = ");
  Serial.println(C[1]);
  Serial.print(" C2 = ");
  Serial.println(C[2]); 
  Serial.print(" C3 = ");
  Serial.println(C[3]); 
  Serial.print(" C4 = ");
  Serial.println(C[4]); 
  Serial.print(" C5 = ");
  Serial.println(C[5]); 
  Serial.print(" C6 = ");
  Serial.println(C[6]); 
//  Serial.print(" C7 = ");
//  Serial.println(C[7]);
  Serial.println();

  delay(1000);
}

long getVal(int address, byte code)
{
  unsigned long ret = 0;
  Wire.beginTransmission(address);
  Wire.write(code);
  Wire.endTransmission();
  delay(10);
  // start read sequence
  Wire.beginTransmission(address);
  Wire.write((byte) 0x00);
  Wire.endTransmission();
  Wire.beginTransmission(address);
  Wire.requestFrom(address, (int)3);
  if (Wire.available() >= 3)
  {
    ret = Wire.read() * (unsigned long)65536 + Wire.read() * (unsigned long)256 + Wire.read();
  }
  else {
    ret = -1;
  }
  Wire.endTransmission();
  return ret;
}

void initial(uint8_t address)
{

  Serial.println();
  Serial.println("PROM COEFFICIENTS ivan");

  Wire.beginTransmission(address);
  Wire.write(0x1E); // reset
  Wire.endTransmission();
  delay(10);


  for (int i=0; i<6  ; i++) {

    Wire.beginTransmission(address);
    Wire.write(0xA2 + (i * 2));
    Wire.endTransmission();

    Wire.beginTransmission(address);
    Wire.requestFrom(address, (uint8_t) 6);
    delay(1);
    if(Wire.available())
    {
       C[i+1] = Wire.read() << 8 | Wire.read();
    }
    else {
      Serial.println("Error reading PROM 1"); // error reading the PROM or communicating with the device
    }
    Serial.println(C[i+1]);
  }
  Serial.println();
}

Hi!

i've tried the code , but it has the same results as before.

Actual TEMP= 23.29 Actual PRESSURE= 506.45
RAW Temp D2= 8378600 RAW Pressure D1= 6238566

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 23.30 Actual PRESSURE= 506.44
RAW Temp D2= 8378796 RAW Pressure D1= 6238482

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 23.30 Actual PRESSURE= 506.44
RAW Temp D2= 8378768 RAW Pressure D1= 6238484

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

Actual TEMP= 23.30 Actual PRESSURE= 506.46
RAW Temp D2= 8378922 RAW Pressure D1= 6238554

C1 = 43760
C2 = 39947
C3 = 26993
C4 = 24969
C5 = 32337
C6 = 27552

What do I need to change to get the code working for the MS5607 ?
In the code I saw why the minus 20 degrees didn't work :

if(TEMP < 2000) // if temperature lower than 20 Celsius
{
int32_t T1 = 0;
int64_t OFF1 = 0;
int64_t SENS1 = 0;

T1 = pow(dT, 2) / 2147483648;
OFF1 = 5 * pow((TEMP - 2000), 2) / 2;
SENS1 = 5 * pow((TEMP - 2000), 2) / 4;

Why do you need that ? Can't you just delete that part ? ]:smiley:

Many Thanks!

FRR

Read the data sheet. It's all documented.

You are correct to question why you need the extra code but the answer is very simple and is as Leo advised, it is in the data sheet. The code that Leo provided is for a second order temperature compensation simply, as I view it, to increase the temperature reading accuracy below 20C. It should work without this extra code but not that accurate. I have not seen accurate results so I cannot comment.
When we get your / my sensor – or any of these sensors – working properly below 20C then it will be interesting to see whether the temerature / data function is linear or not, as in if you double one value then the associated value is automatically doubled for example. I susect that it is not linear and hence the need for another correction below 15C. But to repeat myself I do not understand why the pressure / resistance of the piezo component of the Wheatstone bridge should be non linear with a reference temperature of 20C.
I do not understand why you are getting wrong values with Leo’s ammeded code above 20C as there is nothing much one can do wrong on the I2C. I do suggest putting the sensor in a 'match box' so that it is not exposed to any changes in the ambient environment like door opening or shutting or if you, like I, hang it out of the window for values <20C. If you are getting wrong values then put Serial.print statements (how primitive) in where you can and check results by hand calculations.
Finally have a good look at p7 of the your data sheet as Leo advised for there are one or two seemingly small changes which are easy to overlook and which make a huge difference in the results. I am referring especially to the power functions as in 2^7 instead of 2^8 for example. I get excellent results with Leo’s amended code post 20C and a few tweaks. We just have to crack the <20C barrier which I think is a problem with the data declaration.
Best wishes
Vanja

Hi!

Sorry for my late reply!

Thanks for the advice!!!
If I have the time I will look at it. The sensor is in a plastic box with 2 holes in it, so the air pressure is the same.
I will calculate all the parameters :grin:
But the project has already been stopped.

Thank you all !

FRR

Hello,

First post to come an old dead thread to life, sorry guys.

I'm discovering MS5607, with an arduino uno, and facing the exact same mesure problem than the Foxroxracer using Leo's code : temperature seems right, but the readable pressure value (not raw value) is between 600 and 700 (3xx m high according to the example parallax).

Since I'm not trapped inside a tropical storm, and my tests are done at about 50m high, there is something wrong.

The answer may be on this thread, but the datasheet linked doesn't exist anymore, and while you're talking of the page 7 of the datasheets, the one I found on parallax website is 5 pages long.

So any hint on what point of the code has to be adapted would be really appreciated. Thanks for helping.

There is a possible solution here - forums.parallax.com/showthread.php/140701-Help-using-SPI-in-Altimeter-MS5607-and-Arduino -
(last code with the lookup table,
please let us know if the code works.

Thank you robtillart.
I tried the code found on your link.

Without modification, and with the basic cable diagram (ie only 2 data pins wired & +3.3V and ground), it shows negative values... I'll try to look at the code this week-end.

it shows negative values

you are in a cellar ? :wink:

You should first try to understand the code and how the lookup table fits into it. Then you might need to adapt the lookup table to your needs.

Succes,

Not much time for tests on last week end, but enough to get some results with the code linked on last page :
It uses arduino numeric pins, while the sample parallax program uses analogic pins.

The result :

  • parallax code : altitude= 3xx m, displaying pressure and temperature in the .h file gives values
  • modified code linked : altitude=1x m, 0 displayed for pressure and temp in the .h Note : i used +3.3V and not +5V for ms5607 alim, while the wiring table on the link says +5V.
  • real altitude : around 50m

So the modified code seems closer to reality, but i can't see intermediate values.
I used leo's code with analogic pins wired (without modification in the code), it gave me correct temp but pressure was too low.
I had no time to analyse this results yet.

@lavabo

The real height is only directly calculated from your samples if you are under an "Standard ICAO Athmosphere" !!!
Without a calibration to your actual "real Environment" (rel. Humidity and some other physical parameters) you will only see a "theoretical" Height.

Only the absolute Pressure value is (temperature) compensated, NOT the height (over mean Sea level).

Compare the measured Pressure Values to an Barometer, wich is adopted to your geographical Position.

The calculated Height will change also continously with your actual Weatherconditions ]:smiley:

greetz