FreECU Project


Here are some derivations I had done to understand how Subaru implements some of their fueling strategies. Many of these strategies are also used by other manufacturers and are thus generally applicable to many other EFI systems.

Volumetric Efficiency

Volumetric Efficiency is used to measure engine load.


VE is calculated using mass air flow \(\frac{g}{s}\) , absolute air temperature \(K\) , absolute air pressure \(Pa\) , engine displacement \(cm^2\) and engine speed \(RPM\) .

VE is commonly expressed in liters per revolution. Liters/rev at 100% VE is given by the following equation:

\[\frac{l}{rev} = \frac{Engine\,displacement\,(cm^2)}{2}\]

Next we convert the MAF sensor data from \(\frac{g}{s}\) into liters per second. Grams of air can be converted into volume using the following equation:

\[\frac{gm}{L} = \rho = \frac{P_{abs}}{R_{specific} \cdot T_{abs}}\]

The specific gas constant for dry air is \(287.058\,J/(kg \cdot K)\) . This will require a lookup table as the program becomes more advanced to handle high humidity air.

\[\frac{1}{L} = \frac{P_{abs}}{R_{specific} \cdot T_{abs} \cdot gm}\]


\[L = \frac{R_{specific} \cdot T_{abs} \cdot gm}{P_{abs}}\]

The equation using the MAF reading looks like this:

\[\frac{L}{s} = \frac{R_{specific} \cdot T_{abs} \cdot \frac{gm}{s}}{P_{abs}}\]

We can find the \(\frac{L}{rev}\) by dividing the flow rate in Liters per second by the engine frequency in Hz.

The engine frequency is found as show:

\[Fq_{engine} = \frac{RPM}{60}\]


\[\frac{L}{rev} = \left(\frac{R_{specific} \cdot T_{abs} \cdot \frac{gm}{s}}{P_{abs}}\right) \cdot \left(\frac{1}{Fq_{engine}}\right)\]
//Displacement independent VE calculation

/* variable list from header or elsewhere...
#define R 287.058
float air_mass_flow; // gm/s
float press_abs; // Pa
float temp_abs; // K
float eng_spd; // RPM
float liters_rev;

float mot_fq = (eng_spd / 60);
liters_rev = (R * temp_abs * air_mass_flow) / (press_abs * mot_fq);

Fuel Injection Volume Control

Fuel quantity calculation is calculated using fuel-rail pressure and fuel injector opening time \((ms)\) .

What we want to know for open loop control is, given our VE \((\frac{L}{rev})\) , AFR request, injector flow rate for a given fuel rail pressure \((\frac{cc}{min})\) , injector lag-time \((ms)\) , and fuel rail pressure \((Bar)\) ; how long do we hold the injector open for?

\[fuel_{vol} = \frac{air_{vol} \cdot \rho_{air}}{\lambda \cdot 14.66 \cdot \rho_{fuel}}\] \[t_{inj} = 0.\overline{66} \cdot \left( t_{turnOn} + t_{battComp} \right) + t_{accelComp} + \left( \frac{fuel_{vol}}{flow_{inj}} \right) \cdot \left( \frac{2}{CYL} \right)\]

Open-Loop Air-Fuel Control

Using VE and fuel volume control open-loop AFR can be achieved.

Idle Control

The idle control strategy will be described here…

Lookup Table Interpolation

Lookup tables are intorpolated using simple bilinear interpolation.

\[P \approx \frac{(x_2-x)\cdot(y_2-y)}{(x_2-x_1)\cdot(y_2-y_1)} \cdot Q_{11} + \frac{(x-x_1)\cdot(y_2-y)}{(x_2-x_1)\cdot(y_2-y_1)} \cdot Q_{21} + \frac{(x_2-x)\cdot(y-y_1)}{(x_2-x_1)\cdot(y_2-y_1)} \cdot Q_{12} + \frac{(x-x_1)\cdot(y-y_1)}{(x_2-x_1)\cdot(y_2-y_1)} \cdot Q_{22}\]

The point “P” is found between the four known points “Q” of the lookup table.

Bilinear Interpolation

Image by Bocsika - Own work, Public Domain,