Uno based boost gauge with BMP180 and MPX5700AP

Ok so I am very new to the Arduino and the language. This is my first attempt at anything like this. Please be nice to me.

I am building a boost/vacuum gauge for my car utilizing an uno, a MPX5700AP for the pressure sensor, and a BMP180 to set the absolute pressure. I am following the tutorial here: tutorial

This is his code:

/*
Reads boost from MPX4250AP on Analog 0.
Converts vacuum readings to inHg.
*/
int mapsen = 0; // Set MAP sensor input on Analog port 0
float boost = 0; // Set boost value to 0
float mapval = 0; // Set raw map value to 0
volatile float peakboost = -30.0; // Set peak memory to low number so max displays correctly
float warnpsi = 20.5; // Set PSI for warning
float atmpsi = 13.9637; //Local atmospheric pressure
// include the library code:
#include <LiquidCrystal.h>
#include <LcdBarGraph.h>
#define REDLITE 6 //Red is connected to this Digital pin
#define GREENLITE 5 //Green is connected to this Digital pin
#define BLUELITE 3 //Blue is connected to this Digital pin
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// you can change the overall brightness by range 0 -> 255
int brightness =255;
byte lcdNumCols = 16; // -- number of columns in the LCD
byte sensorPin = 0; // -- value for this example
//LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // -- creating LCD instance
LcdBarGraph lbg(&lcd, lcdNumCols);  // -- creating
void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.clear();
  setBacklight(100,255,0);
  lcd.setCursor(4,0);
  lcd.print("Welcome");
  lcd.setCursor(4,1);
  lcd.print("Cameron");
  delay (1500);
  lcd.clear();
  lcd.setCursor(10,0);
  lcd.print("|");
}
void loop()
{
  // -- draw bar graph from the analog value readed
  lbg.drawValue( analogRead(sensorPin), 1024);
  // -- do some delay: frequent draw may cause broken visualization
  //delay(100);
   
 mapval= analogRead(mapsen); //Reads the MAP sensor raw value on analog port 0
 boost = ((((float)mapval/(float)1023+0.04)/.004)*.145)-atmpsi;
  if (boost <0) //If PSI is negative, convert to inHG and display VAC instead of PSI
  {
    //boost = boost*2.036021;
    lcd.setCursor(0,0);
    lcd.print("VAC");
  }
  else
  {
    lcd.setCursor(0,0);
    lcd.print("PSI");
  }
  if (boost > peakboost) //Works the MAX
  {
    peakboost = boost;
    if (peakboost<-10) //Adjusts numbers over
    {
      lcd.setCursor(12,0);
      lcd.print(peakboost,1);
    }
    if (peakboost>-10)
    {
      lcd.setCursor(11,0);
      lcd.write(254);
      lcd.setCursor(12,0);
      lcd.print(peakboost,1);
    }
    if (peakboost >0)
    {
      lcd.setCursor(12,0);
      lcd.write(254);
      lcd.setCursor(13,0);
      lcd.print(peakboost,1);
    }
    if (peakboost >=10)
    {
      lcd.setCursor(12,0);
      lcd.print(peakboost,1);
    }
  }
  if (boost<-10)
  {
    lcd.setCursor(4,0);
    lcd.print(boost,1);
  }
  if (boost>-10)
  {
    lcd.setCursor(8,0);
    lcd.write(254);
    lcd.setCursor(4,0);
    lcd.print(boost,1);
  }
  if (boost >0)
  {
    lcd.setCursor(7,0);
    lcd.write(254);
    lcd.setCursor(4,0);
    lcd.print(boost,1);
  }
  if (boost > warnpsi) //If boost exceeds warnpsi then change backlight color
  {
    setBacklight(255,0,0);
  }
  else
  {
    setBacklight(100,255,0);
  }
  delay(50);
}
void setBacklight(uint8_t r, uint8_t g, uint8_t b) {
  // normalize the red LED - its brighter than the rest!
  r = map(r, 0, 255, 0, 200);
  g = map(g, 0, 255, 0, 255);
  r = map(r, 0, 255, 0, brightness);
  g = map(g, 0, 255, 0, brightness);
  b = map(b, 0, 255, 0, brightness);
  // common anode so invert!
  r = map(r, 0, 255, 255, 0);
  g = map(g, 0, 255, 255, 0);
  b = map(b, 0, 255, 255, 0);
  Serial.print("R = "); 
  Serial.print(r, DEC);
  Serial.print(" G = "); 
  Serial.print(g, DEC);
  Serial.print(" B = "); 
  Serial.println(b, DEC);
  analogWrite(REDLITE, r);
  analogWrite(GREENLITE, g);
  analogWrite(BLUELITE, b);
}

The difference is that he isn't utilizing the BMP180 and he is using the MPX4250AP datapage while i am using the MPX5700AP datapage

Can someone help me code the BMP180 so it calibrates the absolute pressure instead of using a fixed absolute pressure which is in the code.

Also do the formulas for the pressure sensors need to be adjusted based on the transfer function formulas on the datapages?

Thanks for the help,
Mike

Here are the two transfer function from the datasheets.

MPX5700AP >>>>> V out = VS*(0.0012858*P+0.04) ± Error

MPX4250AP >>>>> V OUT = VS*(0.004 x P-0.04) ± Error

The supplied code has this that looks like where the transfer function is used.

boost = ((((float)mapval/(float)1023+0.04)/.004)*.145)-atmpsi;

Perhaps change the code to this? I am guessing and I would test it before I would trust it.

boost = ((((float)mapval/(float)1023+0.04)/0.0012858)*.145)-atmpsi;

By the way, there are pressure sensors that communicate with I2C or SPI. They might simplify calculations and perhaps be more accurate because of less math errors.

Thank you. That's exactly what i wasn't understanding. I knew that was the formula but i didn't know where the data sheet formulas came into play.

Now just need to figure out how to get this BMP180 working correctly

Well I got some code from another guy. His again calibrated for another pressure sensor. The MPXA6400AP, but his formula for boost is completely different. i changed on variable in the formula called the 'calibration factor' to 2.5 as that is what allowed my gauge to read exactly 0.0 when it has no boost or vacuum. Im going to test it on my car tomorrow. we'll see how it goes

code was too long here's the first half

/*
  HolyCrapItsFast Boost Gauge (C)
 - Reads boost from internal MPXA6400AP 4 bar MAP sensor on Analog 0
 - Provides barometric compensation
 - Converts vacuum readings to inHg
 
 Source code By George VanPopering HolyCrapItsFast @ www.igotasti.com
 Revision 1.1A
 */
#include <Wire.h>
#include <LiquidCrystal.h>
#include <LcdBarGraph.h>

#define BMP180_ADDRESS 0x77  // I2C address of BMP180 Baro Sensor
#define sensorPin 0

// Baro definitions
const unsigned char OSS = 0;  // Oversampling Setting
int ac1;
int ac2; 
int ac3; 
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1; 
int b2;
int mb;
int mc;
int md;
// Sensors, I/O, switches, settings and thresholds
int val = 0; // variable to store the read value
float boost = 0; // Set boost value to 0
volatile float peakboost = -30.0; // Set peak memory to low number so max displays correctly
float warnpsi = 22; // Set PSI for overboost warning
float alertpsi = 18; // Set PSI for high boost alert
//float pressure = 14.7; //Local atmospheric pressure
float vacuum = -1;
float deadbandMin = -.6; // inHg
float deadbandMax = .6; // PSIg
// b5 is calculated in bmp180GetTemperature(...), this variable is also used in bmp180GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5; 
short temperature;
long pressure;
short temperatureA;
long pressureA;
const float p0 = 101325; // Pressure at sea level (Pa)
float altitude;
float altitudeA;

#define REDLITE 15 //Red is connected to this Digital pin
#define GREENLITE 16 //Green is connected to this Digital pin
#define BLUELITE 17 //Blue is connected to this Digital pin
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int brightness =255;
byte lcdNumCols = 16; // -- number of columns in the LCD
LcdBarGraph lbg(&lcd, lcdNumCols);  // -- creating bar graph object

boolean State = LOW;
long previousMillis = 0;
long interval = 100;

const int numReadings = 2;
int readings1[numReadings];      // the readings from the analog input
int index1 = 0;                  // the index of the current reading
int total1 = 0;
int average1 = 0;

void setup()
{
  for (int thisReading1 = 0; thisReading1 < numReadings; thisReading1++)
    readings1[thisReading1] = 0;
  Wire.begin();
  bmp180Calibration();
  temperatureA = bmp180GetTemperature(bmp180ReadUT());
  pressureA = bmp180GetPressure(bmp180ReadUP());
  altitudeA = (float)44330 * (1 - pow(((float) pressureA/p0), 0.190295));
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.clear();
  setBacklight(255,0,255);
  lcd.setCursor(0,0);
  lcd.print("HolyCrapItsFast!");
  lcd.setCursor(0,1);
  lcd.print("  Boost  Gauge  ");
  delay (2000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("    Applying    ");
  lcd.setCursor(0,1);
  lcd.print("Barometric  Comp");
  delay (1000);
  lcd.clear();
  setBacklight(255,0,0);
  lcd.setCursor(0,0);
  lcd.print("  Temperature   ");
  lcd.setCursor(0,1);
  lcd.print("  ");
  lcd.setCursor(2,1);
  lcd.print(((temperatureA * 0.1) * 1.8) + 32);
  lcd.setCursor(7,1);
  lcd.print(" Deg F   ");
  delay (1500);
  lcd.clear();
  setBacklight(0,0,255);
  lcd.setCursor(0,0);
  lcd.print(" Atmos Pressure ");
  lcd.setCursor(0,1);
  lcd.print("   ");
  lcd.setCursor(3,1);
  lcd.print(pressureA * .000145037);
  lcd.setCursor(8,1);
  lcd.print(" PSI    ");
  delay (1000);
  lcd.clear();
  setBacklight(0,255,0);
  lcd.setCursor(0,0);
  lcd.print("Altitude  Calc'd");
  lcd.setCursor(0,1);
  lcd.print("    ");
  lcd.setCursor(4,1);
  lcd.print(altitudeA);
  lcd.setCursor(9,1);
  lcd.print(" ft    ");
  delay (2000);
  lcd.clear();
  setBacklight(255,0,255);
  lcd.setCursor(0,0);
  lcd.print("Measuring  Boost");
  delay (2000);
  lcd.clear();
  lcd.clear();          
  lcd.setCursor(10,1);
  lcd.print("Pk0.0");
}

void loop()
{
  unsigned long currentMillis = millis();
  temperature = bmp180GetTemperature(bmp180ReadUT());
  pressure = bmp180GetPressure(bmp180ReadUP());
  altitude = (float)44330 * (1 - pow(((float) pressure/p0), 0.190295));

  total1 = total1 - readings1[index1];        
  readings1[index1] = analogRead(0);
  total1= total1 + readings1[index1];      
  index1 = index1 + 1;                    
  if (index1 >= numReadings)              
    index1 = 0;                          
  average1 = total1 / numReadings;
  //
  int MAPval1 = average1;

  // int MAPval1 = analogRead(0);
  MAPval1 = map(MAPval1, 15, 1024, 0, 225); // Sets range of MAP sensor
  boost = (((MAPval1 * 2.5) * .14503773773020923)-(pressure * .000145037))+2; 
  // Calibrated for MPXA6400AP MAP Sensor (MAPval1 * 'Calibration Factor')
  // Min .2 Volts, Max 4.80 Volts Typical
  // Typical pressure range, 20-400KPA (4 Bar)

  if (boost >= deadbandMin && boost <= deadbandMax)
  {
    boost = 0;
    lcd.setCursor(0,1); 
    lcd.print("PSI 0.0 ");
    lcd.setCursor(10,1);
    lcd.print("Pk");
  }
  else if (boost < vacuum) //If PSI is negative, convert to inHG and display VAC instead of PSI
  {
    boost = boost*2.036021;
    //boost = boost;
    lcd.setCursor(0,1);
    lcd.print("VAC");
    lcd.setCursor(10,1);
    lcd.print("Pk");
  }
  else
  {
    lcd.setCursor(0,1); 
    lcd.print("PSI");
    lcd.setCursor(10,1);
    lcd.print("Pk");
  }
  if (boost > peakboost) //Works the MAX
  {
    peakboost = boost;
    if (peakboost<-10) //Adjusts numbers over
    {
      lcd.setCursor(12,1);
      lcd.print(peakboost,0);
    }
    if (peakboost>-10)
    {
      lcd.setCursor(12,1);
      lcd.write(254);
      lcd.setCursor(12,1);
      lcd.print(peakboost,1);
    }
    if (peakboost >0)
    {
      lcd.setCursor(12,1);
      lcd.write(254);
      lcd.setCursor(13,1);
      lcd.print(peakboost,1);
    }
    if (peakboost >=10)
    {
      lcd.setCursor(12,1);
      lcd.print(peakboost,1);
    }
  }
  if (boost<-10)
  {
    lcd.setCursor(4,1);
    lcd.print(boost,1);
  }
  if (boost>-10)
  {
    lcd.setCursor(8,1);
    lcd.write(254);
    lcd.setCursor(4,1);
    lcd.print(boost,1);
  }
  if (boost >0)
  {
    lcd.setCursor(7,1);
    lcd.write(254);
    lcd.setCursor(4,1);
    lcd.print(boost,1);
  }
  if (boost <0)
  {
    peakboost = 0; //Reset Peak Hold when boost is zero
  }
  if (boost > alertpsi and boost < warnpsi)  //If boost exceeds alert psi then change backlight color
  {
    setBacklight(255,255,0);
  }
  else if (boost > warnpsi){
    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;  
      if (State == LOW){
        State = HIGH;
        setBacklight(255,255,255);
      }
      else{
        State = LOW;
        setBacklight(255,0,0);
      }
    }
  }
  else if (boost < vacuum) //If in vac
  {
    setBacklight(0,0,255);
  }
  else 
  {
    setBacklight(0,255,0);
  }
  lbg.drawValue(analogRead(sensorPin), 1024); // -- draw bar graph from the analog value readed
  delay(10); // -- do some delay: frequent draw may cause broken visualization

}

void setBacklight(uint8_t r, uint8_t g, uint8_t b) {
  // normalize the red LED - its brighter than the rest
  r = map(r, 0, 255, 0, 255);
  g = map(g, 0, 255, 0, 255);
  b = map(b, 0, 255, 0, 255);
  r = map(r, 0, 255, 0, brightness);
  g = map(g, 0, 255, 0, brightness);
  b = map(b, 0, 255, 0, brightness);
  // common anode so invert
  r = map(r, 0, 255, 255, 0);
  g = map(g, 0, 255, 255, 0);
  b = map(b, 0, 255, 255, 0);
  analogWrite(REDLITE, r);
  analogWrite(GREENLITE, g);
  analogWrite(BLUELITE, b);
}

// Stores all of the bmp180's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp180Calibration()
{
  ac1 = bmp180ReadInt(0xAA);
  ac2 = bmp180ReadInt(0xAC);
  ac3 = bmp180ReadInt(0xAE);
  ac4 = bmp180ReadInt(0xB0);
  ac5 = bmp180ReadInt(0xB2);
  ac6 = bmp180ReadInt(0xB4);
  b1 = bmp180ReadInt(0xB6);
  b2 = bmp180ReadInt(0xB8);
  mb = bmp180ReadInt(0xBA);
  mc = bmp180ReadInt(0xBC);
  md = bmp180ReadInt(0xBE);
}
// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp180GetTemperature(unsigned int ut)
{
  long x1, x2;
  x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  x2 = ((long)mc << 11)/(x1 + md);
  b5 = x1 + x2;
  return ((b5 + 8)>>4);  
}

The second half of the code.

// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp180GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp180GetPressure(unsigned long up)
{
  long x1, x2, x3, b3, b6, p;
  unsigned long b4, b7;
  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
  p += (x1 + x2 + 3791)>>4;
  return p;
}
// Read 1 byte from the BMP180 at 'address'
char bmp180Read(unsigned char address)
{
  unsigned char data;
  Wire.beginTransmission(BMP180_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(BMP180_ADDRESS, 1);
  while(Wire.available());
  return Wire.read();
}
// Read 2 bytes from the BMP180
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp180ReadInt(unsigned char address)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(BMP180_ADDRESS);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom(BMP180_ADDRESS, 2);
  while(Wire.available()<2);
  msb = Wire.read();
  lsb = Wire.read();
  return (int) msb<<8 | lsb;
}
//Read the uncompensated temperature value
unsigned int bmp180ReadUT()
{
  unsigned int ut;
  // Write 0x2E into Register 0xF4
  // This requests a temperature reading
  Wire.beginTransmission(BMP180_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x2E);
  Wire.endTransmission();
  // Wait at least 4.5ms
  delay(5);
  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp180ReadInt(0xF6);
  return ut;
}
// Read the uncompensated pressure value
unsigned long bmp180ReadUP()
{
  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;
  // Write 0x34+(OSS<<6) into register 0xF4
  // Request a pressure reading w/ oversampling setting
  Wire.beginTransmission(BMP180_ADDRESS);
  Wire.write(0xF4);
  Wire.write(0x34 + (OSS<<6));
  Wire.endTransmission();
  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<<OSS));
  // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
  Wire.beginTransmission(BMP180_ADDRESS);
  Wire.write(0xF6);
  Wire.endTransmission();
  Wire.requestFrom(BMP180_ADDRESS, 3);
  // Wait for data to become available
  while(Wire.available() < 3);
  msb = Wire.read();
  lsb = Wire.read();
  xlsb = Wire.read();
  up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
  return up;
}