Click here for MegaSquirt® MegaManual™ Information, Guides, and Links |
Understanding how MegaSquirt controls the fuel injectors will help you to assemble, test, and tune your MegaSquirt for best performance.
MegaSquirt works on a number of levels to inject the correct amount of fuel into your engine. Most tangible is the hardware. This consists of:
The MC68HC908 CPU is controlled by “embedded software”. This is “burned” into the non-volatile memory (remembers data even when the power is turned off) of the CPU. It is written in assembly language. The embedded code and its variants are freely available. Another part of the CPU memory is burned with the “bootloader”, which tells the CPU how to interpret and store new versions of the embedded code sent through the serial communications port.
The software uses an algorithm to take the inputs and calculates what the outputs should be set to. The inputs are voltage signals, either on/off - aka. digital inputs - (like a tach input) or variable voltage (like a temperature sensor - for which an external variable resistance is used to create a variable voltage at the processor pin with a voltage divider circuit).
The inputs set the state of the input registers (registers are simply fixed addresses in the processor's memory, that correspond to physical pins in the case of I/O pins) by forcing them 'high' (~5V) or low (~0V), normally by supplying a ground or 5V signal to the processor pin. Since the processor sees a register value of ~5V = high as 'on' (or 'true'), and ~0V = low as 'off' or 'false', it can directly read a digital input register as if it were a variable. (Variable voltage signals are more complicated,, and are discussed briefly below.) Processor pins can also have built in 'pull-up' voltages, so that the pin is forced high if not grounded, and low if grounded.
Outputs are switched on or off by setting a bit value in their respective output registers. The 'on' value is a one, which is represented in the registers by a small charge. This small charge is frequently replenished, otherwise the charge might be lost. Because the charge is replenished, we can use this charge flow to switch a transistor on (which simply amplifies the charge flow on the port pin to create a much larger current flow in an external device). To turn the external current flow off, we write a 0 to that pin's register bit. This is how we use a command in the code to switch an injector, relay, or ignition module on and off - by setting the register value to 0 (off) or one (on) and hooking that register to an output pin that is connected to the base (middle layer) of a transistor. However, we have to know when to set the output on or off, and for this we have set-up and tuning parameters.
The parameters that adjust the embedded code to your specific vehicle are configured using a laptop and tuning software, such as MegaTune. These are Windows9x/Me/XP applications. They can read information coming from the MegaSquirt® EFI Controller, as well as send parameters to MegaSquirt® for use and storage.
The amount of fuel injected by MegaSquirt depends on several factors:
MegaSquirt uses all these factors to determine the fuel pulse width - longer pulse widths mean more fuel (richer), shorter pulse widths mean less fuel (leaner).
To understand these, we will start with the basics: the Ideal Gas Law, the REQ_FUEL value, and the fueling equation.
The Ideal Gas Law
You might remember from high school physics classes that an ideal gas (which air is reasonably close to) obeys the relationship:
PV = nRT
Where:
P = pressure,
V = volume,
n = number of moles (which is related to the mass of the gas, i.e. 1 mol = 6.023x1023 molecules of the gas, and n = mass (in grams)/molar mass(MM)),
R = the ideal gas constant,
and T = the absolute temperature.
What does this have to do with fuel injection? In order to know how much fuel to inject, we need to know how much air is going into the engine so the chemically correct mixture (called “stoichiometric”) can be achieved. So for a fuel injected engine, we use sensors to determine the pressure in the intake manifold and the air temperature. However, the temperature in this equation is “absolute temperature” measured in Kelvins which is equal to degrees Celsius + 273°.
The volumetric efficiency (VE) is a percentage that tells us the pressure inside the cylinder versus the pressure in the manifold. We know the volume (V) from the displacement of the engine. Thus we can calculate the mass of air (M) in the cylinder (proportional to n) from
n = PV/RT |
Since:
P = VE * MAP (i.e. the pressure in the cylinder in kPa),
V = CYL_DISP = the displacement of one cylinder (in liters),
R = 8.3143510 J/mol K,
and T = (IAT-32)* 5/9 + 273 to convert IAT from °Fahrenheit to Kelvin.
Note that we can combine the constants R and MMair into one, and we will ignore them from this point on since they can be hard-coded into the assembly language code and neglected after that.
Since we now know the amount of air in a cylinder from the MAP and IAT values and the 'tuned' value for VE, we need to know the amount of fuel to inject. We specify this with a parameter called REQ_FUEL.
Injectors operate by using a 12 volt supply source to operate a solenoid (via the injector coil) that opens a valve in the tip of the injector. In most electronic fuel injection installations (and all MegaSquirt® installations), the opening and closing is achieved by the switching of the ground for the injectors. That is, the 12 volt supply is live to the engine whenever it is running, and the EFI controller opens the injector by providing a ground path for this 12 volts through the injector. Note the some injectors (called "low impedance" or "peak and hold") require some form of current limiting to avoid over heating the injectors. MegaSquirt® has provisions for controlling and tuning the current through the injectors - see the 'Injectors and Fuel System' section of this manual for more details. Except for the very brief periods when they are opening and closing (generally about 1 millisecond), injectors are either fully open (and flowing at their rated capacity for the applied fuel pressure) or fully closed and not flowing at all.
Injectors flow ratings are given in pounds per hour (lbs/hr) or cubic centimeters (milliliters) per min. You will need to find this number for your injectors to calculate your REQ_FUEL. See the 'Injectors and Fuel System' section of this manual for more details.
REQ_FUEL (short for "required fuel") is the part of the computation that tells MegaSquirt® how big your injectors are, and what your cylinder displacement (CYL_DISP) is. It is the length of time in milliseconds [ms] that MegaSquirt® should “squirt” to give the stoichiometric amount of fuel (14.7 Air/Fuel Ratio for gasoline) at 100% VE, a manifold absolute pressure (MAP) of 100kPa, and an air temperature of 70 degrees Fahrenheit for a complete stroke cycle.
The air/fuel ratio (AFR) is the mass of air compared to the mass of fuel entering the engine, so for a 14.7:1 AFR we have 14.7 times as much air (by weight) as fuel. The volume ratio is much more extreme, about 9000:1, and varies considerably with temperature, so AFR is always specified by mass.
A stoichiometric mixture is chemically correct for complete burning with no extra fuel OR air left over. For gasoline, a 14.7:1 AFR is considered the correct amount for burning with no leftover air or fuel. Note that it is not necessarily the ratio for most power or efficiency.
Req_Fuel is calculated from the equation:
Where:
36,000,000 is the number of tenths of a millisecond in an hour, used to get the pounds per 1/10 milllisecond from the pounds/hours rating of the injectors.
REQ_FUEL = Computed injector open time in tenths of millisecond.
CID = Cubic Inch Displacement.
AIRDEN = Air density (pounds per cubic inch) at MAP pressure of 100 Kpa, Air Temperature of 70
Degrees F, and Barometric Pressure of 30.00 In HG
NCYL = Number of Cylinders
INJFLOW = Injector Flow Rate in pounds per hour.
DIVIDE_PULSE = injection divide number for number of injections per engine cycle.
The AIRDEN function (used above) is defined by:
Or, in metric units (kg/m3, °C, kPa):
Where:
MAP = Manifold Air Pressure in kPa,
Temp = Air Temperature in Degrees F,
459.7 is used to convert from Fahrenheit to absolute temperature,
1728 is used to convert from pounds per cubic feet to pounds per cubic inch.
Note that there is also a small adjustment for relative humidity.
You can read more about the air density function at the Air Density and Density Altitude Calculations site.
Hence, the REQ_FUEL value is the amount of fuel (in milliseconds) required for a MAP reading of 100 Kpa, manifold air temp of 70 degrees F, and a barometer of 30.00 In Hg, for one complete filling of one cylinder (Volumetric Efficiency = 100%), without any enrichments.
For a 4-stroke, a complete stroke cycle is 720 degrees of crankshaft rotation (i.e. two revolutions); for a 2-stroke, it is 360 degrees (this is also factored in the REQ_FUEL value downloaded to MegaSquirt). (Technically, for MegaSquirt® EFI Controller, a cycle is defined as nCyl ignition events.) In the tuning software, the upper REQ_FUEL box is the amount per cylinder, as noted above. The lower REQ_FUEL box is the downloaded value to the ECU - this is the REQ_FUEL number on top, but scaled by your injection mode (number of squirts and alternate/simultaneous). For example, if you inject simultaneous and one injection, and have the same number of injectors as cylinders [i.e. port injection], then REQ_FUEL on the bottom is the same as REQ_FUEL on top. Same with alternate and two squirts. If you put in simultaneous and two squirts, then REQ_FUEL is divided in half - because you squirt twice, you need to inject 1/2 the fuel on each shot.
To see how Req_Fuel works, enter your number of cylinders and your engine displacement in cubic inches (1.0L = 1000cc = 61 cid), as well as your injector flow in lbs/hr and the stoichiometric air/fuel ratio, in the form below and press the "Compute Req_Fuel" button.
MegaSquirt Fuel Equation
What MegaSquirt® does is take this downloaded REQ_FUEL number and then multiply (or adds) values that scale this number, to come up with the injected pulse width [PW]. Therefore, pulse width is:
PW = REQ_FUEL * VE * MAP * E + accel + Injector_open_time
The "E" above is the multiplied result of all enrichments, like warm-up, after-start, barometer and air temperature correction, closed-loop, etc:
and
Gamma_Enrich (E) is the scaling factor applied to the REQ_FUEL value, along with VE(RPM,MAP) and MAP. For all of the corrections, 100% means no enrichment/enleanment, since the value is normalized by 100 to get a fractional multiplier.
Notice there are two other factors added to this - one is the acceleration enrichment, and the other is the injector open time.
Even if you set REQ_FUEL to zero you are still left with the injector open time (and accel enrichment if activated). The reason for adding in the open time is that it takes a finite amount of time to open the injector before one reaches a linear control state where injector time relates to fuel flow. The controller compensates for the open time by adding it to the applied total pulse width, otherwise the pulse would be too short.
The thing to note is that the REQ_FUEL is a pre-computed number downloaded to the MegaSquirt® unit by MegaTune based on injector size, etc. MegaSquirt® uses this by applying the ideal gas law to compute relative charge density based upon those conditions, then scales Req_Fuel accordingly to arrive at a pulse width. For changes in barometer and manifold air temperature, there are the lookup tables the values are run through (i.e. airdenfactor, etc).
The main loop (the area of the embedded code where the fuel pulse width is calculated) for MegaSquirt-I normally runs at about 1500 Hertz (1500 times per second) and can wander a couple hundred Hertz either way depending on whether you are in cranking mode or whatever else is going on and needs attention (these are called interrupts). For MegaSquirt-II, the main loop runs about twice as fast.
For example, in a pretty reasonable worst case, 1500 Hz is about 4 times the IRQ ("interrupt request") rate (6000 RPM * 8 cyl = 400 Hz). So on a V8 at 6000 rpm, the fuel pulse width is updated 4 times between each spark event (and 8 times between fuel injection events, if running 2 squirts). MegaSquirt-II doubles these, as would running a 4 cylinder (since there are half as many events at a given rpm). At 600 rpm, you have 10 times as many updates per ignition/injection event.
To further understand the equations, read the VE Tuner document. This document describes one implementation of the autotune that was not finished at the time that document was written. The top section has the equations for the MegaSquirt® fuelling.
As we saw above the fuelling equation is:
PW = REQ_FUEL * MAP/100 * VE/100 * GammaE/100 + Inj Open Time
So to see an example of how MegaSquirt® calculates
pulsewidths, we will look at a low rpm cruise point data from a datalog file,
with MAP=40 kPa, VE=74%, GammaE=97%, and a reported pulse width of 4.0
milliseconds, with constants: Req_Fuel = 10ms and
Inj Open Time = 1.3 ms.
so: PW = 10 * 40/100 * 74/100 * 97/100 + 1.3 = 4.17 ms in this case.
The tuning software just reports what the MegaSquirt box is generating, 4.0 ms in the example.
You may not get exactly the number displayed reported by MegaSquirt® in the datalogs. Remember that the serial transfer routine works asynchronous to the main calculation loop, so there is always the chance that you get readings where the VE, MAP, etc do not exactly match the pulse width. In other words, while the "math" is being done in the main loop (right after finding the VE, etc), MegaSquirt® may transmit the pulse width before it has been calculated for this iteration. In fact, the main event loop will execute repeatedly many times before the SCI has sent out one iteration of all of the 22 runtime variable bytes (at 9600 baud).
To verify the calculations, you need to run things steady state. For instance, run MegaSquirt® on the stimulator, and then go through the exercise. Also remember that the resolution is 0.1 milliseconds for pulse width, and the intermediate calculation steps in MegaSquirt® are held with 8 and 16-bit numbers, so if you want an exact match you need to manage the intermediate numbers the same way that MegaSquirt® handles them.
Finally, note that the final absolute value of VE is not that important, as long as everything is repeatable for a given input parameter set (i.e. MegaSquirt® yields the same PW for a given set of input values each and every time, i.e. repeatable). You tune the vehicle for best operation.
A fuel injection computer could use the cylinder filling efficiency (VE) relative to two points - the atmosphere, and the intake manifold pressure (as measured by the MAP sensor). If you use manifold absolute pressure (MAP) as your reference pressure to compute cylinder filling as MegaSquirt does, then a turbo motor is usually worse than a naturally aspirated (NA) motor, because of the added back pressure from the turbocharger exhaust manifold and the turbine. If you are referencing VE to ambient pressure, then "VE" goes way up as the boost builds.
Speed Density algorithms (like the one in MegaSquirt) usually use the first definition in their VE calculations, and then multiply the VE number by the MAP value to get an actual filling mass. However, VE values above 100% can be used in a turbocharged motor to cool the charge and prevent detonation by making the mixture richer.
Measured Values
As noted above, MegaSquirt® uses several measured values in its computations. These include the Manifold Absolute Pressure (MAP) and Intake Air Temperature (IAT). The MPX4250 MAP sensor works by taking a 5 Volt reference (often abbreviated to 5Vref) supply from MegaSquirt® EFI Controller, and returning a 0-5 volt signal whose voltage is a linear function of the absolute pressure at the sensor. Absolute pressure is the pressure compared to a total vacuum. Normal atmospheric pressure is about 101.3 kiloPascals (kPa), or about 14.7 psi or 29.92 inches of Mercury (“Hg). Engine diagnostic gauges often use inches of mercury for measuring vacuum. So a vacuum of 15” (as read on a vacuum gauge) is equal to 29.92 – 15 = 14.92 “Hg = 101.3*14.92/29.92 = 50.5 kPa. MegaSquirt uses kiloPascals exclusively for pressure measurement.
To convert pressure (kPa, Hg, psi, etc.), use Eric F.'s calculator.
Lower pressures give lower voltages from the MPX4250 MAP sensor. MegaSquirt® uses an analog to digital converter (ADC) to turn the MAP sensor voltage signal into a digital number between 0 and 255 (i.e. one byte = 8 bits). The “kpafactor4250.inc” is used by MegaSquirt® to scale the “conversion” from volts to bits. MegaTune uses a similar file for its computations. MegaSquirt® embedded code uses the variable “kpa” to store the measured manifold pressure value for use in its computations (when the assembling language code is compiled).
Note that MegaSquirt® also uses the MAP sensor to grab a “barometer” reading at start-up to apply barometric corrections that compensate for reduced exhaust back pressure at high altitude. This value is stored in a variable called “baro”. The corrections themselves are in a variable called “aircor”.
MegaSquirt also uses an analog to digital conversion (ADC) to translate the varying resistance of the intake air temperature sensor to a digital value (“clt”) between 0 and 255 for MS-I controllers, or 0 and 1024 for MS-II controllers. The sensor resistance can range from 100,000 ohms at –40°F (-40°C) to 185 ohms at 210°F (99°). Other sensors can be used by recompiling the code using EasyTherm for MS-II controllers, or directly in MegaTune for MS-II controllers.
In addition to the measurements necessary to compute the ideal gas law, other sensors are used by MegaSquirt® to compensate when the engine needs a mixture other than stoichiometric. These other sensors include a coolant temperature sensor for warm-up enrichment, and a throttle position sensor for acceleration/deceleration enrichment.
MegaSquirt has a coolant temperature sensor (CLT) that is electrically identical to the IAT sensor. It functions in exactly the same fashion as the IAT, but it is used only for warm-up enrichment, cranking pulse width determination, and controlling the fidle valve. At low temperature, fuel vaporizes poorly, and more fuel is needed to ensure enough vaporized fuel for adequate combustion. The variable “coolant”, which is equal to “clt” + the offset of 40°F, is used to tell MegaSquirt® when warm-up enrichment (variable is “warmcor”) is needed. Cranking pulse widths are determined by both the low temperature (-40°F) setting (“CWU”) and the high temperature (170°F) setting (“CWH”). The actual pulse width is determined by a linear interpolation between these two settings based on the current coolant temperature (“clt”). The fast idle valve is activated whenever CLT is below “FASTIDLE”.
The TPS sensor tells MegaSquirt® what the current position of the throttle. This variable is compared to the most recent readings to determine if the throttle is opening or closing rapidly. If so, extra fuel can be added for an opening throttle to compensate for transient conditions. This functions the same as an accelerator pump in a carburetor.
The TPS also does two other important functions. First, if the throttle is open more than a specified amount during cranking, it invokes the “flood clear” mode by reducing the injected pulse width to 0.3 milliseconds. Second, if the throttle is open more than 70%, exhaust gas feedback is shut off.
The exhaust gas oxygen (EGO) sensor provides feedback to MegaSquirt® if it is injecting the correct amount of fuel. The EGO sensor (also called an O2 sensor or oxygen sensor) measures the amount of oxygen in the exhaust gases, and sends a 0 to 1 volt signal (for a narrow-band sensor, more on wide band sensors later) to MegaSquirt® (raw ADC count is “ego”). MegaSquirt® then computes the adjustment that should be made in the fuel duration (“egocorr”) for the next injection event. Lower voltages mean lean mixtures, and higher voltages mean richer mixtures.
However, the conventional narrow-band sensors are not particularly precise away from stoichiometric mixtures, so situations demanding richer or leaner mixtures must turn off EGO correction. MegaSquirt uses TPS measurements to shut off EGO correction at more than 70% throttle. MegaSquirt also gives you options to shut off EGO correction below a specified coolant temperature (“egotemp”) and below a specified engine rpm.
The ONLY differences between narrow-band exhaust gas oxygen sensors and wide-band oxygen sensor/controllers on MegaSquirt® are the slope and set point. The feedback fuel control logic is the same.
The step size is a constant, and is user set on the enrichments page. The total number of step allowed is set with the EGO ± limit (%).
The time between steps depends on the 'Ignition events per step' MegaSquirt® waits this number of 'sparks', then:
For example, suppose we have:
Then if we are running above the rpm active above setting, MegaSquirt® has been on for 30 seconds, the engine is above the coolant temperature activation pont, etc., then:
Narrow Band | Wide Band (DIY-WB) | |
Stoichiometric Set Point | 0.450 volts | 2.500 volts |
Rich Voltage | > 0.450 | < 2.500 |
Lean Voltage | < 0.450 | > 2.500 |
The other crucial difference between narrow and wide and sensors is that for a narrow band sensor, only the stoichiometric set point ensures a particular air/fuel ratio (14.7:1). With a wide band sensor, other voltages correspond to other air/fuel ratios (for example 2.08=12.5:1), so the set point in MegaSquirt® can be moved to achieve other AFRs. For example, you could set it to 2.65 volts to get a 16.5:1 'cruise' closed loop mixture.
Of course, this only happens if the coolant temperature is above the activation threshold, MegaSquirt® has been running for 30 seconds or more, the rpm is above the RPM active above threshold, and the TPS ADC count is less than 178 (~3.5 volts).
Okay, now that MegaSquirt® knows how much fuel to inject, how does it know when to inject the fuel? That is a function of the ignition input circuit. A signal is taken from the distributor or negative terminal of the coil. Ideally, there is one “spike” each time a cylinder fires. MegaSquirt injects fuel on even multiples of these signals.
Considerable work has been done in the field to ensure clean ignition signals, with no dropped events and no false events. This is covered in more detail in the Ignition Triggering subsection of the Tuning section.
The timing of the injection events depends on the parameters you set using the tuning software (Injection Per Engine Cycle, Injector Staging, Number of Cylinders, etc.). These will be covered in detail in the Tuning section of this manual.
Batch, Bank, Sequential Injection and MegaSquirt
There are two common sorts of injection:
Sequential injection requires:
MegaSquirt has just two injector drivers (that can handle up to ten injectors each), and no provisions for a cam sensor signal, so it would be difficult to make it into a sequential injection system.
The benefits of sequential injection are that:
The effect on maximum horsepower is general negligible.
Al Grippo has an EFI332 controller on his vehicle that can do sequential injection. As a real-world test, he programmed his EFI332 ECU to start the injection when the exhaust valve closed (intake already open), but if the pulse width was such that injection could not finish by the time the intake closed, then the ECU advanced the injection timing so the injection would end when the intake closed. From this theoretical optimum, he varied the timing through the whole cycle and confirmed that what he picked as default was optimum based on the highest rpm, lowest map reading. This was all done at idle. There was a small but measurable difference if the timing was such that injection took place coincident with the exhaust being open.
However, sequential injection does not necessarily mean you are injecting into an open intake valve all the time. The intake valve is only open less than 30% of the time in a typical 4 stroke engine. Once you are trying to produce more than about 25% of maximum HP your injectors are firing for longer than the intake valves are open. If your maximum HP is correctly calibrated to a safe 80% duty cycle, your injectors are injecting well over 50% of the time on closed valves.
At higher rpms, it becomes increasingly difficult to inject while the valve is open. For example, if your Req_Fuel = 15.0 ms, and your maximum duty cycle is 85% then the interval between injections cannot be closer than 17.6 ms. The time available to inject during the entire 4 stroke cycle is:
the intake is typically open for less than 240° of 720° in an engine cycle in a hot street engine, about 1/3 of the time for a complete cycle. So:
and
Using the numbers above,
Above this RPM, it is not possible to inject the entire amount fuel through the open valve at 100% VE and 100kPa. At idle, however, VE may be 30%, and kPa might be 35 kPa, yielding a pulse width of ~1.8 milliseconds, which certainly could be injected during the intake valve opening. So sequential injection is primarily effective at idle, and not much different from batch injection as pulse widths get larger at higher engine speeds and loads.
In any case, when fuel is injected while the valve is closed, it will simply stay in the port until the valve opens. In some cases, this period of time may allow enough heating of the mixture to better vaporize the liquid fuel, improving efficiency and emissions.
So the effect of sequential timing is relatively minor, and applies mostly at low rpms. The OEM manufacturers use it mostly for emissions reasons (most of the OEM fuel injection systems up to the mid-90s were bank fire). However there is a real benefit in sequential systems in that you can do individual cylinder tuning (if you have the time, skill, and equipment).
This has been a brief introduction to the workings of MegaSquirt. You can learn more by studying the schematics, the assembly code, and the hardware datasheets, as well as by assembling and using a MegaSquirt.