The Fuel Equation
Overview
Every time a cylinder fires, the ECU must decide how long to open the injector. Too short and the mixture is lean; too long and it is rich. The calculation starts with the VE table and works through a chain of corrections to arrive at an injector pulse width in milliseconds.
Understanding this chain makes it much easier to diagnose fuelling problems and to understand what each tuning parameter actually does.
Air mass calculation
The ECU first estimates the mass of air entering the cylinder:
air_mass = (MAP / (R * IAT)) * displacement_per_cylinder * VE
Where:
- MAP: manifold absolute pressure in kPa
- R: specific gas constant for air (287 J/kg/K)
- IAT: intake air temperature in Kelvin (deg C + 273.15)
- displacement_per_cylinder: engine swept volume divided by cylinder count, in litres
- VE: volumetric efficiency from the table, as a fraction (e.g. 0.80 for 80%)
This is the ideal gas law applied to the intake charge. It gives air mass in grams.
Fuel mass required
The required fuel mass follows directly from the air mass and the target AFR:
fuel_mass = air_mass / target_AFR
Target AFR comes from the AFR target table (also called the lambda target table). At stoichiometry for petrol, AFR is 14.7:1, so fuel_mass = air_mass / 14.7.
Injector pulse width
The ECU converts fuel mass to a time duration using the injector's flow rate:
pulse_width = fuel_mass / injector_flow_rate
Injector flow rate is set in the firmware configuration (typically in cc/min or lb/hr at a reference fuel pressure). The ECU divides the required fuel mass by this rate to get a duration in milliseconds.
A staging factor applies if the engine has more than one injector per cylinder (staged injection), but on most single-injector-per-cylinder setups it is 1.
Dead time (injector latency)
Injectors do not respond instantly. From when the ECU sends the open signal to when fuel actually flows, there is a dead time, typically 0.5-1.5 ms depending on the injector and battery voltage. The ECU adds this to every pulse:
effective_pulse_width = pulse_width + dead_time(battery_voltage)
Dead time increases as battery voltage drops (the solenoid takes longer to open). The dead time table maps battery voltage to dead time in milliseconds. Getting this wrong introduces a constant fuelling offset that is worst at idle, where pulse widths are short and dead time is a larger fraction of the total.
Fuel pressure correction
Injector flow rate is specified at a reference pressure (usually 3 bar or 43.5 psi differential). If your fuel pressure differs, the effective flow rate changes:
corrected_flow = rated_flow * sqrt(actual_pressure / reference_pressure)
Flow scales with the square root of the pressure differential (Bernoulli). Some ECUs handle this automatically via a fuel pressure sensor; others require the injector size to be entered at the actual operating pressure.
Correction multipliers
The base pulse width is multiplied by several correction factors before it reaches the injector:
| Correction | Purpose |
|---|---|
| Warmup enrichment (WUE) | Extra fuel during cold running; tapers to 1.0 at operating temperature |
| Afterstart enrichment (ASE) | Brief enrichment immediately after the engine fires; prevents stall on start |
| Accel enrichment (AE) | Transient fuel added on sudden throttle opening to compensate for wall-wetting |
| IAT correction | Adjusts for air density changes with temperature; lean at high IAT, rich at low IAT |
| Barometric correction | Adjusts for altitude; air is less dense at high altitude |
| Closed-loop trim | O2 sensor feedback correction when closed-loop is active |
These all multiply together. An engine starting from cold will see WUE of perhaps 1.3 (30% extra fuel) and ASE on top of that; as it warms up both taper toward 1.0.
What goes wrong and why
Lean at idle, correct at load: often dead time is wrong. Dead time affects short pulses (idle) far more than long ones (full load).
Correct at idle, lean at full load: VE table is too low in the high-RPM/high-load region, or the injectors are undersized.
Rich on tip-in, correct in steady state: accel enrichment is over-set.
Consistently lean or rich everywhere: injector size (cc/min) is entered incorrectly, or the fuel pressure differs from the reference without correction.
Hunting idle, correct elsewhere: check warmup enrichment is not still active at operating temperature, and that the idle ignition advance is reasonable (see Ignition Timing Theory).
Injector sizing
As a rule of thumb, choose injectors so that they run at no more than 80% duty cycle at peak power. Duty cycle is pulse width divided by the time available between injections (60,000 / RPM / cylinders for sequential, or half that for batch fire).
max_flow_needed = (power_kW * BSFC) / (num_cylinders * 0.80)
Where BSFC (brake specific fuel consumption) is typically 0.27-0.32 kg/kWh for a naturally aspirated petrol engine at WOT. Convert to cc/min using fuel density (~0.74 kg/litre for petrol).
Oversized injectors are harder to tune at idle because pulse widths become very short relative to dead time; undersized injectors cannot supply enough fuel at peak power.