jump to navigation

0.4.1 Alpha (4th public release) 2011/08/17

Posted by Michael in 2JZduino.

I’ve posted another release of 2JZDuino at Sourceforge, available here

This release comes after an extensive amount of testing and a few minor code changes & tweaks. As of this release I’ve logged about 10,000 km operating my IS300 with the 2JZduino connected as a piggyback ECU. For a large part of it I’d been fighting with a lean AFR condition that seems to occur either at low RPM when the throttle is partially depressed (i.e. tip-in), or at idle. I’ve speculated that there is an issue with the stability of the MAF reading due either to the larger intake tube diameter I have installed (3.5″ diam. vs. 2.75″ stock diam.), or turbulence around the MAF sensor due to the shortened intake tract.

There are two symptoms…

1) At idle the AFR would sometimes randomly drift lean to ~17:1 or rich to ~11:1 before the short-term fuel trims would correct.

2) For low RPMs and partial throttle the AFR would drift lean to upwards of 18:1. This was often observed when accelerating gently (MAP readings ~80kPa) from idle RPMs. Under this condition the ECU seems to stay in closed-loop operation which doesn’t provide enough fuel enrichment when the throttle first begins to open. The result is a significant loss of torque when trying to accelerate from low RPM. More throttle would trigger open-loop behaviour and the ECU would command the correct fuel for ~13:1 AFR. But part-throttle often resulted in a fuel shortage until the O2 sensors would command the short-term fuel trims to recover (or driver throttle input triggered closed-loop condition).

This highlighted a potential risk for when the Supercharger is installed… part throttle could result in positive manifold pressures which when mixed with lean AFR conditions could result in engine damage.

For both problems I implemented some logic in the h_InjectorChange() function that intervenes with the injector pulse width if a lean AFR condition is detected. The code is as follows…

  if (!InjectorEventState[Inj_Index]) { // only intervene with InjOFF events
    unsigned int thisInjPWcmd_T64 = TCNT4 - T64_LastInjON[Inj_Index]; // calculate the commanded PW for this Injector and for this combustion cycle
    if ((Inj_Index < 3 && AirFuelRatioB1_x10 > 160) || (Inj_Index >= 3 && AirFuelRatioB2_x10 > 160)) { // this Injector # is part of a bank that is currently LEAN
      // Sometimes at tip-in/accel. from idle a lean condition occurs (for MAP >~60kPa) -> Add fuel to obtain the expected amount
      if (!EngineIsStarting && ManifoldAirPressure > 60 && thisInjPWcmd_T64 < ExpectedIdleTipInInjPW_T64[MAPindex]) EventDelay += ExpectedIdleTipInInjPW_T64[MAPindex] - thisInjPWcmd_T64;
      // Sometimes AFR drifts lean at steady-idle -> Add 1/2 difference in fuel between previous injection dwell and Normal Idle fuel amount
      else if (ManifoldAirPressure >= 27 && EngineHz < 22 && thisInjPWcmd_T64 < NormalIdleInjPW_T64) EventDelay += (NormalIdleInjPW_T64 - thisInjPWcmd_T64) >> 1;

Effectively, if the AFR is ever detected to be leaner than 16:1, the logic will intervene and add to the injector pulse width: an amount to drive the AFR to stoichiometric AFR for MAP > 60 kPa, and half the amount to drive AFR to stoichiometric for the idle condition. The stoichiometric amount is pre-calculated based on an assumed volumetric efficiency of 50% (a reasonable estimate for the situation where these lean conditions tend to occur).

The logic is not intended to enrich the fuel past stoichiometric because the stock ECU fuel control still needs an opportunity to work. The idea is simply to enrich the fuel mixture temporarily while the stock closed-loop system responds.

For the idle condition the enrichment is only half of the difference between the expected and actual pulse-width (allowing the stock closed-loop control more of an opportunity to intervene). Generally the idle AFR fluctuations are more slow-moving, while the part-throttle lean condition is a fleeting condition requiring more aggressive intervention.

There is no intervention for MAP < 27 kPa, which is the point where the engine is deemed to be in vacuum and is decelerating (i.e. driver throttle input is zero).

Other changes since the v0.3 release…

  • Volumetric Efficiency considerations added to the calculation of InjectorOffsetsT64[][]. The volumetric efficiency for each point on the RPM vs. MAP table is now considered when the stoichiometric fuel amount is estimated (refer to this post). This should provide a more accurate fuel adjustment from the Injector Scaling map page of IS300_Arduino_EEPROM.exe.
  • New logic added that tracks EngineIsStarting. When the engine first starts to crank a maximum injector pulse-width is imposed to prevent over-enrichment in the case where larger injectors are installed. The stock ECU commands a lot of fuel during engine cranking. When test fitting my 440cc/min injectors I found this to result in much too much fuel during engine start. IS300_Arduino_EEPROM.exe now allows you to set the “Max Cranking AFR” which calculates a maximum pulse-width for 100% VE for the “Fuel Injector Size” value.
  • Logic implemented to intervene with lean conditions at idle, and under part-throttle (per the elaborate description above).
  • I’ve had some limited time to test the operation of 2JZduino with larger fuel injectors. I was limited by what seems to have been a small air leak between the injectors and the intake manifold, leading the engine to behave like there was a vacuum leak at low RPM. I’ve run into delay after delay in resolving this mechanical issue, so further testing will have to wait for now.