Add idle ignition timing correction feature (#275)
* Add idle advance and idle switch settings Add idle RPM target based ignition timing correction * Change few names to avoid confusion changed idle switch to closed throttle position sensor (CTPS) and moved CTPS settings under idle advance settings dialog for now
This commit is contained in:
parent
964163d2ec
commit
892e05d2fc
|
@ -316,8 +316,16 @@ page = 1
|
|||
#else
|
||||
primeBins = array, U08, 87, [4], "F", 1.8, -22.23, -40, 215, 0
|
||||
#endif
|
||||
CTPSPin = bits, U08, 91, [0:5], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
|
||||
CTPSPolarity = bits, U08, 91, [6:6], "Normal", "Inverted"
|
||||
CTPSEnabled = bits, U08, 91, [7:7], "Off", "On"
|
||||
idleAdvEnabled = bits, U08, 92, [0:1], "Off", "Added", "Switched", "INVALID"
|
||||
idleAdvAlgorithm = bits, U08, 92, [2:2], "TPS", "CTPS"
|
||||
unused_idle_bits = bits, U08, 92, [3:7]
|
||||
idleAdvRPM = scalar, U08, 93, "rpm", 100, 0.0, 100, 25500, 0
|
||||
idleAdvTPS = scalar, U08, 94, "%", 1, 0, 0, 120, 0
|
||||
|
||||
unused2-91 = array, U08, 91, [37], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
unused2-95 = array, U08, 95, [33], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
|
||||
;Page 2 is the fuel map and axis bins only
|
||||
page = 2
|
||||
|
@ -444,7 +452,11 @@ page = 4
|
|||
baroFuelBins = array, U08, 92, [8], "kPa", 1.0, 0, 80, 120, 0 ; Bins for the Baro correction curve
|
||||
baroFuelValues = array, U08, 100, [8], "%", 1.0, 0, 0, 255, 0 ; % Values for same
|
||||
|
||||
unused4-92 = array, U08, 108,[20], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
;Idle timing advance
|
||||
idleAdvBins = array, U08, 108, [6], "RPM", 10.0, -50, -500, 500, 0
|
||||
idleAdvValues = array, U08, 114, [6], "deg", 1.0, -15, -15, 50, 0
|
||||
|
||||
unused4-120 = array, U08, 120, [8], "%", 1.0, 0.0, 0.0, 255, 0
|
||||
;--------------------------------------------------
|
||||
|
||||
;Start AFR page
|
||||
|
@ -1027,6 +1039,9 @@ page = 11
|
|||
requiresPowerCycle = knock_trigger
|
||||
requiresPowerCycle = knock_pullup
|
||||
requiresPowerCycle = idleUpEnabled
|
||||
requiresPowerCycle = CTPSEnabled
|
||||
requiresPowerCycle = CTPSPin
|
||||
requiresPowerCycle = CTPSPolarity
|
||||
requiresPowerCycle = legacyMAP
|
||||
requiresPowerCycle = fuel2InputPin
|
||||
requiresPowerCycle = fuel2InputPolarity
|
||||
|
@ -1236,6 +1251,8 @@ menuDialog = main
|
|||
subMenu = sparkTbl, "Spark Table", 2
|
||||
subMenu = dwellSettings, "Dwell settings"
|
||||
subMenu = dwell_correction_curve, "Dwell Compensation"
|
||||
subMenu = idleAdvanceSettings, "Idle Advance Settings"
|
||||
subMenu = idle_advance_curve, "Idle Advance" { idleAdvEnabled >= 1 }
|
||||
subMenu = iat_retard_curve, "IAT Retard"
|
||||
subMenu = clt_advance_curve, "Cold Advance"
|
||||
;subMenu = knockSettings, "Knock Settings"
|
||||
|
@ -1248,7 +1265,7 @@ menuDialog = main
|
|||
subMenu = ASE, "Afterstart Enrichment (ASE)"
|
||||
subMenu = std_separator
|
||||
subMenu = idleSettings, "Idle Control"
|
||||
subMenu = iacClosedLoop_curve, "Idle - Closed loop targets", 7, { iacAlgorithm == 3 || iacAlgorithm == 5 }
|
||||
subMenu = iacClosedLoop_curve, "Idle - RPM targets", 7, { iacAlgorithm == 3 || iacAlgorithm == 5 || idleAdvEnabled >= 1 }
|
||||
subMenu = iacPwm_curve, "Idle - PWM Duty Cycle", 7, { iacAlgorithm == 2 }
|
||||
subMenu = iacPwmCrank_curve, "Idle - PWM Cranking Duty Cycle", 7, { iacAlgorithm == 2 }
|
||||
subMenu = iacStep_curve, "Idle - Stepper Motor", 7, { iacAlgorithm == 4 }
|
||||
|
@ -1361,7 +1378,10 @@ menuDialog = main
|
|||
iacCLmaxDuty= "When using closed loop idle control, this is the maximum duty cycle that the PID loop will allow. Combined with the minimum value, this specifies the working range of your idle valve"
|
||||
iacFastTemp = "Below this temperature, the idle output will be high (On). Above this temperature, it will turn off."
|
||||
idleUpPolarity = "Normal polarity is a ground switch where an earthed signal activates the Idle Up. The internal pullup will be enabled with Normal polarity. \n Inverted may be used if a 5v signal is used to enable the Idle Up."
|
||||
CTPSPolarity = "Normal polarity is a ground switch where an earthed signal activates the closed throttle position. The internal pullup will be enabled with Normal polarity. \n Inverted may be used if a 5v signal is used to enable the closed throttle position."
|
||||
idleUpAdder = "The amount (In either Duty Cycle % or Steps (Depending on the idle control method in use), that the idle control will increase by when Idle Up is active"
|
||||
idleAdvEnabled = "Added setting adds curve values to current spark table values when user defined idle is active. \n Switched setting overrides spark table values and uses curve values for idle ignition timing.
|
||||
idleAdvAlgorithm = "Use Throttle position sensor (TPS) or closed throttle position sensor (CTPS) to detect idle state."
|
||||
|
||||
oddfire2 = "The ATDC angle of channel 2 for oddfire engines. This is relative to the TDC angle of channel 1"
|
||||
oddfire3 = "The ATDC angle of channel 3 for oddfire engines. This is relative to the TDC angle of channel 1 (NOT channel 2)"
|
||||
|
@ -1889,6 +1909,15 @@ menuDialog = main
|
|||
field = "Max dwell time", dwellLim, { useDwellLim }
|
||||
field = "Note: Set the maximum dwell time at least 3ms above"
|
||||
field = "your desired dwell time (Including cranking)"
|
||||
|
||||
dialog = idleAdvanceSettings,"Idle Advance Settings",4
|
||||
field = "Idle advance mode", idleAdvEnabled
|
||||
field = "Idle detect mode", idleAdvAlgorithm, { idleAdvEnabled >= 1 }
|
||||
field = "Active Below RPM", idleAdvRPM, { idleAdvEnabled >= 1 }
|
||||
field = "Active Below TPS", idleAdvTPS, { idleAdvEnabled >= 1 && idleAdvAlgorithm == 0 }
|
||||
field = "Closed Throttle Sensor Enabled", CTPSEnabled, { idleAdvEnabled >= 1 && idleAdvAlgorithm == 1 }
|
||||
field = "Closed Throttle Sensor Pin", CTPSPin, { idleAdvEnabled >= 1 && idleAdvAlgorithm == 1 && CTPSEnabled == 1 }
|
||||
field = "Closed Throttle Sensor Pin Polarity", CTPSPolarity, { idleAdvEnabled >= 1 && idleAdvAlgorithm == 1 && CTPSEnabled == 1 }
|
||||
|
||||
dialog = rotary_ignition, "Rotary Ignition", 4
|
||||
field = "Ignition Configuration", rotaryType
|
||||
|
@ -2835,6 +2864,14 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
xBins = cltAdvBins, coolant
|
||||
yBins = cltAdvValues
|
||||
|
||||
; Idle RPM target based ignition timing
|
||||
curve = idle_advance_curve, "Idle Advance"
|
||||
columnLabel = "RPM Delta", "Advance"
|
||||
xAxis = -500, 500, 5
|
||||
yAxis = -15, 50, 5
|
||||
xBins = idleAdvBins, CLIdleDelta
|
||||
yBins = idleAdvValues
|
||||
|
||||
; Curves for idle control
|
||||
; Standard duty table for PWM valves
|
||||
curve = iacPwm_curve, "IAC PWM Duty"
|
||||
|
@ -2874,7 +2911,7 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
xBins = iacCrankBins, coolant
|
||||
yBins = iacCrankSteps
|
||||
|
||||
curve = iacClosedLoop_curve, "IAC Closed Loop Targets"
|
||||
curve = iacClosedLoop_curve, "Idle RPM Targets"
|
||||
columnLabel = "Coolant Temperature", "Motor"
|
||||
xAxis = -40, 120, 6
|
||||
yAxis = 0, 2000, 4
|
||||
|
@ -3469,8 +3506,8 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
entry = hardLimitOn , "Hard Limiter", int, "%d"
|
||||
entry = idleControlOn, "Idle Control", int, "%d"
|
||||
entry = idleLoad, "IAC value", int, "%d"
|
||||
entry = CLIdleTarget, "Idle Target RPM", int, "%%d", { iacAlgorithm == 3 || iacAlgorithm == 5 } ;Only show for closed loop idle modes
|
||||
entry = CLIdleDelta, "Idle RPM Delta", int, "%d", { iacAlgorithm == 3 || iacAlgorithm == 5 } ;Only show for closed loop idle modes
|
||||
entry = CLIdleTarget, "Idle Target RPM", int, "%%d", { iacAlgorithm == 3 || iacAlgorithm == 5 || idleAdvEnabled >= 1 } ;Only show for closed loop idle modes and if idle advance is enabled
|
||||
entry = CLIdleDelta, "Idle RPM Delta", int, "%d", { iacAlgorithm == 3 || iacAlgorithm == 5 || idleAdvEnabled >= 1 } ;Only show for closed loop idle modes and if idle advance is enabled
|
||||
entry = baro, "Baro Pressure",int, "%d"
|
||||
entry = nitrousOn, "Nitrous", int, "%d", { n2o_enable > 0 }
|
||||
entry = syncLossCounter, "Sync Loss #", int, "%d"
|
||||
|
|
|
@ -28,6 +28,7 @@ static inline int8_t correctionFlexTiming(int8_t);
|
|||
static inline int8_t correctionIATretard(int8_t);
|
||||
static inline int8_t correctionBaro(int8_t);
|
||||
static inline int8_t correctionCLTadvance(int8_t);
|
||||
static inline int8_t correctionIdleAdvance(int8_t);
|
||||
static inline int8_t correctionSoftRevLimit(int8_t);
|
||||
static inline int8_t correctionNitrous(int8_t);
|
||||
static inline int8_t correctionSoftLaunch(int8_t);
|
||||
|
|
|
@ -472,6 +472,7 @@ int8_t correctionsIgn(int8_t base_advance)
|
|||
advance = correctionFlexTiming(base_advance);
|
||||
advance = correctionIATretard(advance);
|
||||
advance = correctionCLTadvance(advance);
|
||||
advance = correctionIdleAdvance(advance);
|
||||
advance = correctionSoftRevLimit(advance);
|
||||
advance = correctionNitrous(advance);
|
||||
advance = correctionSoftLaunch(advance);
|
||||
|
@ -480,7 +481,7 @@ int8_t correctionsIgn(int8_t base_advance)
|
|||
|
||||
//Fixed timing check must go last
|
||||
advance = correctionFixedTiming(advance);
|
||||
advance = correctionCrankingFixedTiming(advance); //This overrrides the regular fixed timing, must come last
|
||||
advance = correctionCrankingFixedTiming(advance); //This overrides the regular fixed timing, must come last
|
||||
|
||||
return advance;
|
||||
}
|
||||
|
@ -532,6 +533,34 @@ static inline int8_t correctionCLTadvance(int8_t advance)
|
|||
return ignCLTValue;
|
||||
}
|
||||
|
||||
static inline int8_t correctionIdleAdvance(int8_t advance)
|
||||
{
|
||||
|
||||
int8_t ignIdleValue = advance;
|
||||
//Adjust the advance based on idle target rpm.
|
||||
if(configPage2.idleAdvEnabled >= 1)
|
||||
{
|
||||
currentStatus.CLIdleTarget = (byte)table2D_getValue(&idleTargetTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
int idleRPMdelta = (currentStatus.CLIdleTarget - currentStatus.RPM / 10) + 50;
|
||||
// Limit idle rpm delta between -500rpm - 500rpm
|
||||
if(idleRPMdelta > 100) { idleRPMdelta = 100; }
|
||||
if(idleRPMdelta < 0) { idleRPMdelta = 0; }
|
||||
if(configPage2.idleAdvAlgorithm == 0 && ((currentStatus.RPM < (unsigned int)(configPage2.idleAdvRPM * 100)) && (currentStatus.TPS < configPage2.idleAdvTPS))) // TPS based idle state
|
||||
{
|
||||
int8_t advanceIdleAdjust = (int16_t)(table2D_getValue(&idleAdvanceTable, idleRPMdelta)) - 15;
|
||||
if(configPage2.idleAdvEnabled == 1) { ignIdleValue = (advance + advanceIdleAdjust); }
|
||||
else if(configPage2.idleAdvEnabled == 2) { ignIdleValue = advanceIdleAdjust; }
|
||||
}
|
||||
else if(configPage2.idleAdvAlgorithm == 1 && (currentStatus.RPM < (unsigned int)(configPage2.idleAdvRPM * 100) && currentStatus.CTPSActive == 1)) // closed throttle position sensor (CTPS) based idle state
|
||||
{
|
||||
int8_t advanceIdleAdjust = (int16_t)(table2D_getValue(&idleAdvanceTable, idleRPMdelta)) - 15;
|
||||
if(configPage2.idleAdvEnabled == 1) { ignIdleValue = (advance + advanceIdleAdjust); }
|
||||
else if(configPage2.idleAdvEnabled == 2) { ignIdleValue = advanceIdleAdjust; }
|
||||
}
|
||||
}
|
||||
return ignIdleValue;
|
||||
}
|
||||
|
||||
static inline int8_t correctionSoftRevLimit(int8_t advance)
|
||||
{
|
||||
byte ignSoftRevValue = advance;
|
||||
|
|
|
@ -283,7 +283,8 @@ struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D
|
|||
struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D)
|
||||
struct table2D baroFuelTable; //8 bin baro correction curve (2D)
|
||||
struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature (2D)
|
||||
struct table2D IDLEAdvanceTable; //6 bin idle advance adjustment table based on RPM difference (2D)
|
||||
struct table2D idleTargetTable; //10 bin idle target table for idle timing (2D)
|
||||
struct table2D idleAdvanceTable; //6 bin idle advance adjustment table based on RPM difference (2D)
|
||||
struct table2D CLTAdvanceTable; //6 bin ignition adjustment based on coolant temperature (2D)
|
||||
struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing (2D)
|
||||
struct table2D flexFuelTable; //6 bin flex fuel correction table for fuel adjustments (2D)
|
||||
|
@ -437,6 +438,7 @@ struct statuses {
|
|||
byte idleDuty; /**< The current idle duty cycle amount if PWM idle is selected and active */
|
||||
byte CLIdleTarget; /**< The target idle RPM (when closed loop idle control is active) */
|
||||
bool idleUpActive; /**< Whether the externally controlled idle up is currently active */
|
||||
bool CTPSActive; /**< Whether the externally controlled closed throttle position sensor is currently active */
|
||||
bool fanOn; /**< Whether or not the fan is turned on */
|
||||
volatile byte ethanolPct; /**< Ethanol reading (if enabled). 0 = No ethanol, 100 = pure ethanol. Eg E85 = 85. */
|
||||
unsigned long AEEndTime; /**< The target end time used whenever AE is turned on */
|
||||
|
@ -603,7 +605,16 @@ struct config2 {
|
|||
byte aseBins[4]; //Afterstart enrichment temp axis
|
||||
byte primePulse[4]; //Priming pulsewidth
|
||||
byte primeBins[4]; //Priming temp axis
|
||||
byte unused2_91[37];
|
||||
|
||||
byte CTPSPin : 6;
|
||||
byte CTPSPolarity : 1;
|
||||
byte CTPSEnabled : 1;
|
||||
byte idleAdvEnabled : 2;
|
||||
byte idleAdvAlgorithm : 1;
|
||||
byte idleUnused : 5;
|
||||
byte idleAdvRPM;
|
||||
byte idleAdvTPS;
|
||||
byte unused2_95[33];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
|
@ -688,7 +699,10 @@ struct config4 {
|
|||
byte baroFuelBins[8];
|
||||
byte baroFuelValues[8];
|
||||
|
||||
byte unused2_91[20];
|
||||
byte idleAdvBins[6];
|
||||
byte idleAdvValues[6];
|
||||
|
||||
byte unused4_120[8];
|
||||
|
||||
#if defined(CORE_AVR)
|
||||
};
|
||||
|
@ -1021,6 +1035,7 @@ byte pinFuelPump; //Fuel pump on/off
|
|||
byte pinIdle1; //Single wire idle control
|
||||
byte pinIdle2; //2 wire idle control (Not currently used)
|
||||
byte pinIdleUp; //Input for triggering Idle Up
|
||||
byte pinCTPS; //Input for triggering closed throttle state
|
||||
byte pinFuel2Input; //Input for switching to the 2nd fuel table
|
||||
byte pinSpareTemp1; // Future use only
|
||||
byte pinSpareTemp2; // Future use only
|
||||
|
|
|
@ -122,6 +122,16 @@ void initialiseAll()
|
|||
CLTAdvanceTable.xSize = 6;
|
||||
CLTAdvanceTable.values = (byte*)configPage4.cltAdvValues;
|
||||
CLTAdvanceTable.axisX = configPage4.cltAdvBins;
|
||||
idleTargetTable.valueSize = SIZE_BYTE;
|
||||
idleTargetTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||
idleTargetTable.xSize = 10;
|
||||
idleTargetTable.values = configPage6.iacCLValues;
|
||||
idleTargetTable.axisX = configPage6.iacBins;
|
||||
idleAdvanceTable.valueSize = SIZE_BYTE;
|
||||
idleAdvanceTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||
idleAdvanceTable.xSize = 6;
|
||||
idleAdvanceTable.values = (byte*)configPage4.idleAdvValues;
|
||||
idleAdvanceTable.axisX = configPage4.idleAdvBins;
|
||||
rotarySplitTable.valueSize = SIZE_BYTE;
|
||||
rotarySplitTable.axisSize = SIZE_BYTE; //Set this table to use byte axis bins
|
||||
rotarySplitTable.xSize = 8;
|
||||
|
@ -1962,6 +1972,9 @@ void setPinMapping(byte boardID)
|
|||
//Currently there's no default pin for Idle Up
|
||||
pinIdleUp = pinTranslate(configPage2.idleUpPin);
|
||||
|
||||
//Currently there's no default pin for closed throttle position sensor
|
||||
pinCTPS = pinTranslate(configPage2.CTPSPin);
|
||||
|
||||
/* Reset control is a special case. If reset control is enabled, it needs its initial state set BEFORE its pinMode.
|
||||
If that doesn't happen and reset control is in "Serial Command" mode, the Arduino will end up in a reset loop
|
||||
because the control pin will go low as soon as the pinMode is set to OUTPUT. */
|
||||
|
@ -2079,6 +2092,11 @@ void setPinMapping(byte boardID)
|
|||
if (configPage2.idleUpPolarity == 0) { pinMode(pinIdleUp, INPUT_PULLUP); } //Normal setting
|
||||
else { pinMode(pinIdleUp, INPUT); } //inverted setting
|
||||
}
|
||||
if(configPage2.CTPSEnabled > 0)
|
||||
{
|
||||
if (configPage2.CTPSPolarity == 0) { pinMode(pinCTPS, INPUT_PULLUP); } //Normal setting
|
||||
else { pinMode(pinCTPS, INPUT); } //inverted setting
|
||||
}
|
||||
if(configPage10.fuel2Mode == FUEL2_MODE_INPUT_SWITCH)
|
||||
{
|
||||
if (configPage10.fuel2InputPullup == true) { pinMode(pinFuel2Input, INPUT_PULLUP); } //With pullup
|
||||
|
|
|
@ -307,6 +307,13 @@ void readTPS()
|
|||
currentStatus.TPS = map(tempADC, configPage2.tpsMax, configPage2.tpsMin, 0, 100);
|
||||
}
|
||||
|
||||
//Check whether the closed throttle position sensor is active
|
||||
if(configPage2.CTPSEnabled == true)
|
||||
{
|
||||
if(configPage2.CTPSPolarity == 0) { currentStatus.CTPSActive = !digitalRead(pinCTPS); } //Normal mode (ground switched)
|
||||
else { currentStatus.CTPSActive = digitalRead(pinCTPS); } //Inverted mode (5v activates closed throttle position sensor)
|
||||
}
|
||||
else { currentStatus.CTPSActive = 0; }
|
||||
TPS_time = micros();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue