Pressure Sensors MS5611 MS5803

Hello _Leo

here is my code, i make a mistake to do not use the #-button to insert my code here.

Jürgen

MS5611_LCD_Moverage.ino (4.5 KB)

Jürgen,

you misunderstood.

"movavg_buff[i] = Pressure;"

Pressure has no value in your code.

You need to write a subroutine that reads the pressure from the sensor. Then call the routine in the loop to populate the buffer.

Example:

"movavg_buff[i] = Get_Pressure();"

Leo

Leo can you caste your eye over these results and those in my last post?
Dead on the reference temperature of 20C the temperature changes to a large negative number which seems to be a constant-21329306.00 with the sensor put into the Kuhlschrank.
The code I use is as already posted which I assume you use and Juergen usw.

RAW Temp D2= 8379134 RAW Pressure D1= 8352890
Actual TEMP= 20.01 Actual PRESSURE= 1019.96

RAW Temp D2= 8379080 RAW Pressure D1= 8352918
Actual TEMP= 20.00 Actual PRESSURE= 1019.96

RAW Temp D2= 8378778 RAW Pressure D1= 8352956
Actual TEMP= -21329306.00 Actual PRESSURE= -9499139.00

RAW Temp D2= 8378598 RAW Pressure D1= 8353160
Actual TEMP= -21329306.00 Actual PRESSURE= -9495526.00

RAW Temp D2= 8378420 RAW Pressure D1= 8353066
Actual TEMP= -21329306.00 Actual PRESSURE= -9504028.00

RAW Temp D2= 8378290 RAW Pressure D1= 8353288
Actual TEMP= -21329306.00 Actual PRESSURE= -9503490.00

If I use another 5611 then I get the same thing

RAW Temp D2= 7972696 RAW Pressure D1= 8170442
Actual TEMP= -21326056.00 Actual PRESSURE= -4003808.25

With this one the Actual TEMP is a constant at-21326056.00 and the raw pressure is half.

(Has it anything to do with the use of int64_t).

Best

Hi,
I found the same problemm for temperatures below 20°C. dt then gets negative. The uint_32 then roll to big numbers
I changed dt to int32_t and the line for calculation of dt as follows:
dT = D2 - ((int32_t)C[5] << 8);
Now it seems to work. :wink:
BR
c00laris

You see only a small "jump" due to the change in the compensation at 20.00°C:

Actual TEMP= 19.99 Actual PRESSURE= 975.79
Actual ALTITUDE= 324.33m
RAW Temp D2= 8787722 RAW Pressure D1= 8083108
dT= -246
TEMP= 1999
T1= 0
OFF= -1100205905
OFF1= 2
SENS= 1658456444
SENS1= 1

Actual TEMP= 20.00 Actual PRESSURE= 975.73
Actual ALTITUDE= 324.88m
RAW Temp D2= 8788094 RAW Pressure D1= 8082768
dT= 126
TEMP= 2000
T1= 0
OFF= -1100125650
OFF1= 2
SENS= 1658502323
SENS1= 1

Actual TEMP= 20.00 Actual PRESSURE= 975.73
Actual ALTITUDE= 324.88m
RAW Temp D2= 8788254 RAW Pressure D1= 8082694
dT= 286
TEMP= 2000
T1= 0
OFF= -1100091132
OFF1= 2
SENS= 1658522055
SENS1= 1

Actual TEMP= 20.01 Actual PRESSURE= 975.75
Actual ALTITUDE= 324.71m
RAW Temp D2= 8788534 RAW Pressure D1= 8082688
dT= 566
TEMP= 2001
T1= 0
OFF= -1100030727
OFF1= 2
SENS= 1658556587
SENS1= 1

@c00laris
Can you post your final code for future reference?
Thanks,

c00laris:
Hi,
I found the same problemm for temperatures below 20°C. dt then gets negative. The uint_32 then roll to big numbers
I changed dt to int32_t and the line for calculation of dt as follows:
dT = D2 - ((int32_t)C[5] << 8);
Now it seems to work. :wink:
BR
c00laris
...

That's a bad idea because C[] can be between 0 - 65535!

To solve the problem in the code you are using use:

dT = D2 - ((uint64_t)C[5] << 8);

Hi,
I just tested my MS5611 using the following code (Arduino-1.0.1) letting the sensor rest quietly on my desk (weather is fine,..):

#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(115200); //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 - ((uint64_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;

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

  Pressure = (float)P;
  
//  Serial.print("     Actual TEMP= ");
//  Serial.print(Temperature);
//  Serial.print("      Actual PRESSURE= ");
  Serial.println(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();
}

I just sampled the pressure value for 60 seconds, attached you can find an image of the pressure/time dependency. I think the pressure (97436 Pa) is OK for my height, but the pressure noise seems too much for me! The range is 100 Pa, which would correspond to a height variation of more than 12 meters I think.
What characteristic pressure noise do you have? Is there a possibility to get less noise (oversampling,...?) without averaging too much? I would need about 5 reliable values per second...

Best regards,
Mike

The pressure always has to be corrected in relation to the location of measurement.

The "Noise" you are witnessing can be different depending which hardware you are using.
The sensor has fluctuations, which is normal. However if e.g. the I2C bus layout on the PCB board is poorly designed then you will get additional interference noise.
I'm running 3 different manufactured Arduino platforms, all showing different noise levels. Interestingly my Arduino R3 with protoshield has the least interference noise.

The noise can be due to many different reasons, that´s clear....but the magnitude makes me a little bit irritated. I have mounted the MS5611 directly besides a BMP085 on my breadboard, both sharing the same I2C bus just with different addresses.
The MS5611 shows a range of +/-50 Pa, while the BMP085 only shows about +/-15 Pa.
I thought the MS5611 should be much better than the BMP085 exhibiting a max. resolution of around 10 to 15 cm, which would be a factor 100 away from my measurements... :frowning:

TheMike:
The noise can be due to many different reasons, that´s clear....but the magnitude makes me a little bit irritated. I have mounted the MS5611 directly besides a BMP085 on my breadboard, both sharing the same I2C bus just with different addresses.
The MS5611 shows a range of +/-50 Pa, while the BMP085 only shows about +/-15 Pa.
I thought the MS5611 should be much better than the BMP085 exhibiting a max. resolution of around 10 to 15 cm, which would be a factor 100 away from my measurements... :frowning:

In your post from the 7th July you didn't state that you were comparing it to the BMP085!

Sorry to display my ignorance but I do not understand your pressure time graph Mike. in particular I do not see how a reading in time gives a range of pressure values - your vertical lines - which I assume is being attributed to noise. Where are you getting your readings from for the pressure time graph? My understanding is that you find 1 discrete quantized pressure reading at any one point in time. I had a look at the bmp 085 and depending on the sampling the noise introduced is 0.03 / 0.06 hPa p12 data sheet with a a comparBle .01 to .06 for the 5611 if I read the sheets correctly.
Leo you may be correct about pcb layout and in an earlier post here Juergen and I reported differences from different boards as well. You have track resistance and track capacitance on the board but if this, for example in spite of putting 100 nF smoothing capcaitors, gives erratic results then it has to be questioned how commercially viable this is when the data sheet reports an accuracy of 3 mbar at 750 mbar and at 25C.
I think what is worrying maybe is the temperature accuracy being +/-0.8C. I have not done the sums but what pressure / altitude error this introduces may be considerable given pv=rt upon which this is all based.
rgds

Hi,

thanks for your answers!
Leo,... I´m sorry, I forget to mention the comparison with the BMP.... I´m just beginning with arduino and just thought you would say something like: "Ah, OK, I have a comparable range,..." or "sensor is dead",...

It seems not that easy...

Vanja, the pressure time graph just displays 2831 measurements, which I recorded within 60 seconds using the MS5611. Ideally this should show a horizontal line with y=P (I thought...). Perhaps the scatter plot is better (attached). Nevertheless, you stated a noise value up to 6 Pa for the MS5611. But my readings are fluctuating within 100 Pa.
Yesterday I hooked up a second MS5611 (I ordered two MS5611, each on a BOB, I just had to solder the pins to the second) and it shows the same range.
I think the MS5611 is not very reliable....I just have to think about the temperature accuracy....pv=rt gives dp = r/v * dt,
therefore the error dp/p = dt/t, with t=295K and dt=1K --> dp/p=0.0033. (-->around 300 Pa)
Mhh, thats much, but temperature reading seems to be stable, at least within 0.1°C giving roughly 30 Pa....!?!
Perhaps I´ll try a third MS5611 and a different arduino board in the future, but I´m a little bit sceptic...

Best regards
Mike

Do you take a temperature reading every time you do a pressure conversion?

The temperature was read within every loop before pressure reading.
I will record it again in a few days when I´m back home...

It is interesting to read in the datasheet that 'The MS5611-01BA is a circuit that can be used in conjunction with a microcontroller in mobile altimeter applications. It is designed for low-voltage systems with a supply voltage of 3 V.'
If we take sea pressure as 1013.25mbar then every meter altitude increase corresponds to .14mbar. Hence with a 3mbar accuracy the altitude accuracy is about 21 meters.
The data sheet also gives on p3 +-0.5 mbar 'with an autozero at one pressure point' which would increase the accuracy to 7 meters. But this is stiil to much especially for a device claiming to be used as a mobile altimeter.
Mike your 100Pa corresponds to 1mbar which is within their stated accuracy. (V is also a variable in the ideal gas equation.)
I feel that something is not going right with this device which only meas can answer especially as it is a commercial product.

Here are my results.

Same sensor and same program run on different hardware.

25 samples per second with OSR is set at 2048.

Very interesting Leo. I would not have thought the board design was so critical. The R3 is giving you what 30cm accuracy. Most troubling is your Watterott mini board for I use mini boards and I wonder how my boards fair. What programme are you using to analyse as I would like to try when I get back home. Also what filtering are you applying? Best.

I am using my own written software. The filter is a 1 dimensional Kalman but a simple low pass filter will give you similar results.

Meas recommend using a filter and if you look at the yellow graph you will notice the sensor is right on target.

At some point in time I will document everything here: www.ALTDuino.de

Leo 25 samples per sec is much more viable, have you averaged the values? Why do you use 2048 and not 4096 OSR power considerations ? Also what is right on ? is it the yellow R3 curve. what is right on is Mike's desired but impossible straight line - alas a dream. Can you reference in the meas literature where they advise filtering? Best as always.

Hello all. My first post, please forgive any communication faux pas.

I am working with the MS5803-01BA sensors. I have 3 of them on a PCB, all exhibiting the same behavior(tested separately). I am using I2C communication via Labview. A partner is working on the software so I do not have immediate access to it.

We have successfully communicated with all 3 sensors using I2C to access the PROM and read out all values. Values 3-6 are in the expected range. Values 1 and 2 are all high. Not sure if this points to a problem.

My issue is that when attempting to read the ADC values for either pressure or temp no data is returned. We are using the 4096x oversampling rate and waiting 20ms to read. (min 8.22ms req'd). We are receiving ack bits for both the conversion and read commands, just no data on the line. As stated above, communication protocol has been verified as PROM read is successful.

Has anybody experienced similar problems? Any troubleshooting suggestions?