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:
iLeeeZi 2019-11-08 07:40:53 +02:00 committed by Josh Stewart
parent 964163d2ec
commit 892e05d2fc
6 changed files with 117 additions and 10 deletions

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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();
}