Hello -
Ok, I now have a workable formula, thanks to post #9 :
Calculating MPG from VSS and MAF from OBD2 - MP3Car.com
Quote:
... For the record, the first "one-line" MPG formula above, taken from my Circuit Cellar article, is off by 100! The "4.54" should in fact be "454". The correct formula is:
MPG = (14.7 * 6.17 * 454 * VSS * 0.621371) / (3600 * MAF / 100)
MPG = 710.7 * VSS / MAF
Note that OBD-II VSS reading is in kilometers/hour and MAF reading is grams/sec times 100.
This formula works very well in a modern automobile because the engine computer spends almost 100% of its time managing the fuel-air-ratio to 14.7, which it can do very well because of the "closed loop" feedback from the O2 sensor(s).
In fact, the accuracy of this method has been proven in literally tens of thousands of gasoline-powered vehicles. Accuracy within a few percent is typical, often limited by the accuracy of the vehicle speed reading (i.e., VSS).
As for other ways of doing this, especially if you don't have a MAF sensor, by knowing the displacement of the engine, and after a simple "calibration" using fuel tank "fill-up" data to find the only unknown, namely the "volumetric efficiency" (VE) of the engine, MAF can be calculated from RPM, MAP and IAT. With VE, one can use the following formulas to calculate a synthetic "mass air-flow" (MAF) in grams per second, all without a MAF sensor, using the "Ideal Gas Law", as follows:
IMAP = RPM * MAP / IAT
MAF = (IMAP/120)*(VE/100)*(ED)*(MM)/(R)
where manifold absolute pressure (MAP) is in kPa, intake air temp (IAT) is in degrees Kelvin, R is 8.314 J/°K/mole and the average molecular mass of air (MM) is 28.97 g/mole. Note that, in the above formula, the volumetric efficiency of the (4-cycle!) engine is measured in percent and the engine displacement (ED) is in liters.
The VE of my 1999 7.4L Chevy Suburban is about 65%. Smaller, higher performance engines can have VE's of 85% or higher.
...
|
That led me to this code :
Code:
//
// For signalling when one of the critical input variables has been received from the ECU/PCM
//
typedef struct
{
// 32 bits
int mph:1;
int map:1;
int iat:1;
int rpm:1;
int _PADDING:28;
} accessbits32;
//
// MPGData is global data structure for calculating MPG
//
typedef struct
{
union
{
int accessbit32:32;
accessbits32 accessed;
};
double speed_kmh;
double speed_mph;
double map_inHg;
double map_kPa;
double rpm;
double iat_c;
double mpg_instant;
double fuel_instant;
double miles_instant;
int mpg_count;
double mpg_avg;
double imap;
double maf_gs;
double total_miles_travelled;
double total_fuel_consumed;
} MPGData;
MPGData m;
//
// Drivetrain specific variables that can be loaded from a file
//
typedef struct
{
double ed; // Engine Displacement
double ve; // Volumetric Efficiency
double odo_correction; // odometer correction
} DriveTrain;
DriveTrain dt;
//
// calc_mpg_formula
//
int calc_mpg_formula()
{
int ret;
double iat_k;
int kmh_zero;
iat_k = m.iat_c + 273.15;
if ( iat_k == 0.0)
iat_k = ALMOST_ZERO;
// IMAP = RPM * MAP:kPa / IAT:K
m.imap = (m.rpm * m.map_kPa) / iat_k;
// MAF = (IMAP/120)*(VE/100)*(ED)*(MM)/(R)
// MAF = (( IMAP / 120 )*(VE:% /100)*(ED:liters)*(MM) )/(R)
m.maf_gs = (( m.imap / 120.0)*(dt.ve/100)*(dt.ed) *(28.97))/(8.314);
if ( m.maf_gs == 0.0)
// then protect against divide by zero later on
m.maf_gs = ALMOST_ZERO;
// where manifold absolute pressure (MAP) is in kPa,
// intake air temp (IAT) is in degrees Kelvin,
// R is 8.314 J/°K/mole and
// MM is the average molecular mass of air (MM) = 28.97 g/mole.
// Note that, in the above formula, the volumetric
// efficiency of the (4-cycle!) engine is measured in
// percent and the engine displacement (ED) is in liters.
if ( m.speed_kmh == 0.0)
{ // Not a good solution for 0 MPH, but lets give it a try
m.speed_kmh = 0.161 / 1000.0;
m.speed_mph = 0.10 / 1000.0;
kmh_zero = 1;
}
else
{
kmh_zero = 0;
}
// miles travelled in 1 second
m.miles_instant = m.speed_mph / 3600.0;
if (( m.rpm < 100) && (kmh_zero == 1))
{ // then EOC
m.mpg_instant = 9999.0;
m.fuel_instant = 0.0;
}
else
{
// MPG - miles per gallon
// 14.7 grams of air to 1 gram of gasoline - ideal air/fuel ratio
// 6.17 pounds per gallon - density of gasoline
// 454 grams per pound - conversion
// VSS - vehicle speed in kilometers per hour
// 0.621371 miles per hour/kilometers per hour - conversion
// 3600 seconds per hour - conversion
// MAF - mass air flow rate in 100 grams per second
// 100 - to correct MAF to give grams per second => NOT NEEDED
//MPG = (14.7*6.17*454*KPH*0.621371)/((3600*MAF)/100)
// => 710.7335739 * KPH / MAF
// => 7.107335739 * KPH / MAF_gs
m.mpg_instant = (7.107335739 * m.speed_kmh) / m.maf_gs;
// GPH / 3600 = GPSecond = ( MPH / MPG ) / 3600.0
m.fuel_instant = ( m.speed_mph / m.mpg_instant) / 3600.0;
}
m.mpg_count++;
m.total_miles_travelled += m.miles_instant;
m.total_fuel_consumed += m.fuel_instant;
if ( m.total_fuel_consumed != 0.0)
{
m.mpg_avg = m.total_miles_travelled / m.total_fuel_consumed;
}
else
{
m.mpg_avg = 0.0;
}
ret = m.accessbit32;
m.accessbit32 = 0;
return (ret);
} // END calc_mpg_formula()
There are lots of limitations to what I am calculating. I need to get IAT, MAP, MPH, and RPM in one second in order to be able to datalog. This sounds like plenty of time for a computer, but my standing theory is that the ECU/PCM communicates in it's own good time.
Also, I don't know the Volumetric Efficiency (VE) of my engine. This doesn't address the knowledge that VE changes under different loads.
However, I *am* datalogging MPG numbers that are very very very similar to what a Scangauge displays. This has always been my goal, to have a formula that can give me the same *relative* MPG changes as the ScanGauge.
Me Happy,
.
CarloSW2