LPS22HB pressure readings are very unstable

Board: Nano 33 BLE Sense Rev2
Code Overview: The code sets the initial pressure as a reference for altitude measurement and velocity calculation is done by measuring change in altitude. Averaging has been done to reduce noise in the output data.
Issue: Pressure readings vary a lot. Within a minute, there are deviations of 50 Pa. This didn't happen earlier when the board was new. It has been only a month since I bought it. Also, I tried filtering the pressure data with kalman filter but still the pressure data is very unstable. I am attaching photos for reference. The data in the string is Pressure, Count, Altitude, Velocity.

At 18:36:46

image

At 18:37:46

image

At 18:57, there is a difference of 300 Pa!

image

Code:

/*
  LPS22HB - Read Pressure

  This example reads data from the on-board LPS22HB sensor of the
  Nano 33 BLE Sense and prints the temperature and pressure sensor
  value to the Serial Monitor once a second.

  The circuit:
  - Arduino Nano 33 BLE Sense

  This example code is in the public domain.
*/

#include <Arduino_LPS22HB.h>

float pressure, b, ReferencePressure, d, altitude, alticmp, velocity, velo;
int count = 0, count1 = 0;
unsigned long a, c;

void setup() {
  Serial.begin(9600);
  while (!Serial)
    ;

  if (!BARO.begin()) {
    Serial.println("Failed to initialize pressure sensor!");
    while (1)
      ;
  }

  BARO.setOutputRate(5);
  //BARO.i2cWrite(0x10, 0x5C);
  delay(5000);
  BARO.readPressure(MILLIBAR);
  delay(100);
  for (int i = 0; i < 50; i++) {
    b += BARO.readPressure(MILLIBAR);
    Serial.println(b);
    delay(100);
  }
  ReferencePressure = b / 50;
}

void loop() {
  // read the sensor value

  pressure += BARO.readPressure(MILLIBAR);
  count++;

  if (millis() - a >= 200) {
    a += 200;
    d = pressure / count;
    // print the sensor value
    // Serial.print("Pressure = ");
    Serial.print(d * 100);
    //  Serial.print(" Pa");


    Serial.print(",");
    Serial.print(count);
    count = 0;
    pressure = 0;
    count1 = 0;
    // print an empty line


    altitude = 44330 * (1 - pow(d / ReferencePressure, 0.19029));

    // velocity = 5 * (altitude - alticmp);
    // alticmp = altitude;
    // read the sensor value

    // print the sensor value
    Serial.print(",");
    Serial.print(altitude);
    //  Serial.println(" m");

    Serial.print(",");
    Serial.print(velo);
    Serial.println();
  }

  if (millis() - c >= 50) {

    c += 50;
    d = pressure / count;
    altitude = 44330 * (1 - pow(d / ReferencePressure, 0.1903));
    velocity = 20 * (altitude - alticmp);
    alticmp = altitude;
    velo = velocity / count1;
    count1++;
  }
}

Never post pictures of text! The small snippets imply that there are jumps in the values. Why don't you show these? Post a complete table of let's say 20 minutes.

Was the temperature constant? The sensor is temperature-compensated, so if the temperature changed rather rapidly this might explain the changing values.

As your calculating the altitude and velocity: Are you using that in a balloon?

Otherwise the accuracy of the device is in hPa (up to 1 hPa) so are you sure that the sensor doesn't show real world values?
The datasheet says the device has an output rate of 75Hz. You seem to measure 126 values in 200ms which results in a read rate of over 600 Hz.

You don't even read the temperature. Why?

The temperature is constant. Also, at times the pressure is greater then sea level (I got 101800 Pa). At this point I am pretty sure that the sensor is damaged, though I don't know what caused it since the board is only a month old.

These values were indeed jumps, but even after the output stablized, it was still incorrect by 100-400 Pa. I am using my smartwatch barometer and a BMP390 for reference .

I am also confused about this, but my code for this calculation is correct.

Yes, I am using it in a balloon. And temperature data isn't required from this particular sensor. For temp. measurement I am using the onboard HS3003 sensor.

There is no constant pressure at sea level. Did you realize that the pressure changes depending on the weather conditions?

The age isn't that relevant. If the sensor got damaged it's usually cause by harsh physical conditions outside the specification.
But I would expect values completely out of range from a damaged sensor. Is it possible that the sensor got condensing humidity?
From the description of the sensing element in the datasheet I would not expect a drifting read out if the sensor is really broken.

Which isn't much. My weather station barometer registered a change of over 2000 Pa in the last 20 houres.

Remove that line. It activates a continuous measurement mode which is incompatible with the one-shot mode you use to read the values. The datasheet doesn't say clearly what result you can expect if you configure the device this way.
This method isn't part of the standard library available in the library manager of the IDE. Where did you get your library version? Maybe I'm investigating the completely wrong library...

I don't see a problem with the posted data. I see normal sensor noise, which can be reduced by averaging.

A 300 Pa change in 20 minutes is not unusual or surprising.

I am using my smartwatch barometer and a BMP390 for reference .

Do you have a good reason to believe the output of those sensors?

I used a library from github. Here is the link GitHub - arduino-libraries/Arduino_LPS22HB: LPS22HB Library for Arduino

Also, I got 101800 Pa constantly at times which is greater than sea level pressure of 101350 Pa

I also tried that out but there are no changes in the output values

Yes, I found BMP390 readings to very accurately match my smartwatch's builtin barometer, nearby weather station and iphone's bulitin barometer.

At times this 300 Pa change occurs in 30s

As you know, officially reported pressures are corrected to sea level. Does the code apply any altitude correction?

At times this 300 Pa change occurs in 30s

Please post a sample of raw data documenting the time course of an event in which the pressure changes by 300 Pa in a few seconds, and a photo of your setup. Discontinuous readings may be due to wiring problems, unstable power supply, program bugs, etc.

Post data and code using code tags, rather than photos.

You really had the standard pressure at that time? You know that sea level pressure isn't constant, don't you?

If you use above library you must see a change, at least in the timing. I agree with jremington that you should post complete data of at least a few minutes.

Test done with ODR set to 75 Hz using BARO.setOutputRate(5)
TEST2.txt (101.7 KB)

Test done with default ODR settings
TEST3.txt (105.6 KB)

While doing these tests, current pressure acc. to weather station was 100900 Pa. Both tests were run one after another in a window of 20 min. These readings at times were above 101350 Pa sea level pressure which shouldn't have occured. Every time I restart the code, there is a deviation of about 200 Pa when compared with the values before restarting.

Code:

#include <Arduino_LPS22HB.h>
#include <SD.h>
#include <SPI.h>
#include <RTClib.h>

File myFile;
RTC_DS3231 rtc;
String timestamp;
void setup() {

  rtc.begin();
  rtc.adjust(DateTime(2023, 7, 1, 0, 0, 0));
  if (!SD.begin(2))
    Serial.println("SD error");

  Serial.begin(9600);
  while (!Serial)
    ;

  if (!BARO.begin()) {
    Serial.println("Failed to initialize pressure sensor!");
    while (1)
      ;
  }
  //BARO.setOutputRate(5);
}

void loop() {
  // read the sensor value
  float pressure = BARO.readPressure(MILLIBAR);
  readrtc();
  float temperature = BARO.readTemperature();

  String a = String("Pressure = ") + ',' + String(pressure * 100) + ',' + String("Temperature = ") + ',' + String(temperature);
  Serial.println(a);

  myFile = SD.open("test3.csv", FILE_WRITE);
  myFile.print(timestamp);
  myFile.println(a);

  myFile.close();
  // wait 1 second to print again
  delay(100);
}

void readrtc() {

  DateTime now = rtc.now();
  timestamp = String(now.hour()) + ':' + String(now.minute()) + ':' + String(now.second()) + ',';
}

There is an interesting temperature dependence in the TEST3.txt data. No discontinuities, though.

Same for TEST2.txt, also no discontinuities.

Capture

1 Like

Is there anything I can do to reduce this rapid changes in pressure? I did try kalman filter, but since the change in values is this large, it isn't of much use either.

It is the temperature that is changing, not the pressure.

Where do you live? Sahara? A temperature of almost 40°C in April is rather special from my point of view.

The pressure changes are in a range I wouldn't call "extraordinary". And as @jremington already mentioned: the pressure value depends on the temperature.

1 Like

Obviously, the pressure readings are linearly proportional to the temperature, which explains the variations.

Check the data sheet for the LPS22HB sensor on how it should be used, and what temperature dependence is expected.

Perhaps the sensor is defective, or the library you are using has errors.

The datasheet doesn't have any mention of temperature drift. I will try with a different library and see if there are any improvements. I am also getting a new BLE Sense rev2 board and will update this thread with the results I get on that board and compare the results with the current board. If nothing helps, I am willing to replace the current sensor with a LPS22DF sensor.

Thank you very much for helping me out @pylon @jremington

I'm still curious: Do you have almost 40°C or is the temperature sensor damaged?

Drift? The compensation calculations you're using change the pressure value by the measured temperature value. As this code is from the datasheet I would say that datasheet does mention that dependency.

I took a look at LPS22HB the data sheet, and it very clearly states that the pressure is temperature compensated over the range of 0 to 65 C. So something is wrong. OPC is One Point Calibration.

Capture

Yes, in India it is 41 'C at daytime in my city, so temp. sensor is working fine. The measurements were taken in evening.

Earlier, when the sensor was new and I wanted to reduce noise, since there were no builtin options in library to enable low pass filter, I tried enabling low pass filter by manually tweaking the library's default values sent to ctrl_reg1, which I couldn't achieve maybe that has caused this issue. Though, even after tweaking this values, since the code didn't work, I reinstalled the library and the sensor worked fine for a week or two after that. Also, many times the sensor doesn't initialize even though it is onboard, so it can't have any connection problems and whenever this happens, the only solution is to upload blank sketch and then reupload the previous code again.

That actually sounds like a damaged sensor/board. I would expect the sensor to always initialize as it's only reading a ROM value there. If that doesn't work I guess you have a damage.

1 Like