MPX5100 Pressure Sensor Not Reading Correctly

I am using a MPX5100 pressure sensor, a Arduino Uno, LCD, and two air pumps. This setup is to read pressure or flow through a 2cycle fuel mixture needle valve using mmhg standard. The calculation I am using for the MPX5100 is what I got from some other code, but the problem is it isn't reading correctly. It is off by 38mmhg verified with a calibrated meter from work. Everything I try doesn't work. I have tried changing the upper calibration number but that causes the code to not read consistent number like example 50,51,52,53,54,55 instead it is 51,52, 54,55 so it misses numbers throughout the range.

The picture just shows a different LCD.

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//int rawValue; // A/D readings
int offset = 30; // zero pressure adjust (~30-72)
int fullScale = 819; // 819 max pressure adjust (~798-840),Calibrate high pressure reading.
float pressure; // final pressure in mmHg
int Battery; // battery % of use
uint32_t rawValue; // new average code
int rawAccumulator; // new average code
int filteredValue; // new average code
void setup()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

void loop()
{
  rawValue = analogRead(A0);
  pressure = (filteredValue - offset) * 650.0 / (fullScale - offset); // Replaced rawValue with filteredValue. 650.0 for calibrated pressure conversion
  Battery = analogRead(A1) / 9.00; // Display battery percentage at max 100%

  // New code for averaging - On each pass, it subtracts 1/8 of the total rawAccumulator value, then adds in the current rawValue.
  // So over time, the rawAccumulator value will converge on 8x the average raw value.
  // Then it takes 1/8 of the rawAccumulator value as the filteredValue.
  rawAccumulator -= (rawAccumulator >> 2); // new average code. Can change 3 to 2 for less or 3 to 4 for more averaging.
  rawAccumulator += rawValue; // new average code
  filteredValue = rawAccumulator >> 2; // new average code. Can change 3 to 2 for less or 3 to 4 for more averaging.

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):

  if (pressure < 0)
  {
    lcd.setCursor(0 , 0);
    lcd.print("FLOW RATE:");
    lcd.print("0");
  }
  else
  {
    lcd.setCursor(0 , 0);
    lcd.print("FLOW RATE:");
    lcd.print(pressure, 0);
    lcd.print("   ");
  }
  if (Battery > 65)
  {
    lcd.setCursor(0 , 1);
    lcd.print("BATTERY:");
    lcd.print(Battery);
    lcd.print("%     ");
  }
  else
  {
    lcd.setCursor(0 , 1);
    lcd.print("*CHARGE BATTERY*");
  }
  delay(200);
}

Flow Meter 640x480.jpg

Rather than use "some other code", a better approach would be to write correct code according to the transfer function given in the MPX5100 data sheet. Then it will perform according to the manufacturer's specifications.

TF.png

TF.png

I don't know how. The code I posted was written for the MPX5100 based off o the specs.

Got a suggestion on as to the code you suggest?

With a little algebra, and assuming that Vs = ADC reference = 5V,

float pressure = 111.11*(analogRead(pin)/1024. - 0.04);  //kPa

You can do better with custom calibration, if you have access to an accurate pressure gauge for comparison. Tutorial here.

What would need to be calculated for mmhg instead of kpa?

It is too much trouble to look up the conversion factor?

BTW the low pass filter in the code you posted doesn't round correctly and will always underestimate the correct value. Use a simple average of several readings instead.

Why make it so hard ?
The sensor is ratiometric, that means 5V can be used in the calculation, even if the actual 5V voltage varies a little.
The sensor is input 0...100kPa which corresponds to an output of 0.2 to 4.7V.
That means the range of 100kPa corresponds to a range of 4.5V (with 0.2V offset).

I strongly prefer to calculate the voltage at the pin, to be able to write it to the serial port and check it with a multimeter.

int rawADC = analogRead(A0);
float voltage = (float) rawADC / 1024.0 * 5.0;    // 5.0 is always good, the sensor is ratiometric
// correct offset, divide by voltage range, multiply with pressure range.
float kpa = ((voltage - 0.2) / 4.5) * 100.0;

If you want to add a filter, keep it seperated from this calculation. Use the resulting float 'kpa' variable as input for a filter.

We all use kPa of course. Have you been watching too much Cody's Lab ? Making a Barometer With King of Random - YouTube

To get mmHg:

// According to: https://en.wikipedia.org/wiki/Millimeter_of_mercury
// 1 mmHg = 133.322387415 Pascals, which is 0.133322387415 kPa.
float mmhg = kpa / 0.133322387415;