Mostly complete engine protection (excl AFR)
This commit is contained in:
parent
56509b3a4a
commit
1ec7e7ee86
|
@ -526,7 +526,7 @@ page = 6
|
|||
egoType = bits , U08, 0, [2:3], "Disabled", "Narrow Band", "Wide Band", "INVALID" ; egoOption
|
||||
boostEnabled = bits, U08, 0, [4:4], "Off", "On"
|
||||
vvtEnabled = bits, U08, 0, [5:5], "Off", "On"
|
||||
engineProtectType = bits, U08, 0, [6:7], "Off", "Spark Only", "Fuel Only","Both"
|
||||
engineProtectType = bits, U08, 0, [6:7], "Off", "Spark Only", "Fuel Only","Both"
|
||||
|
||||
egoKP = scalar, U08, 1, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
||||
egoKI = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
||||
|
@ -542,7 +542,7 @@ page = 6
|
|||
vvtCLDir = bits, U08, 6, [4:4], "Advance", "Retard"
|
||||
vvtCLUseHold = bits, U08, 6, [5:5], "No", "Yes"
|
||||
vvtCLAlterFuelTiming = bits, U08, 6, [6:6], "No", "Yes"
|
||||
unused6-6 = bits, U08, 6, [7:7], "TPS", "MAP"
|
||||
boostCutEnabled = bits, U08, 6, [7:7], "Off", "On"
|
||||
egoLimit = scalar, U08, 7, "", 1, 0, 0, 16, 0
|
||||
ego_min = scalar, U08, 8, "AFR", 0.1, 0.0, 7, 25, 1
|
||||
ego_max = scalar, U08, 9, "AFR", 0.1, 0.0, 7, 25, 1
|
||||
|
@ -1186,9 +1186,9 @@ page = 11
|
|||
defaultValue = sparkDur, 1.0
|
||||
defaultValue = fixAngEnable,0
|
||||
defaultValue = n2o_enable, 0
|
||||
defaultValue = speeduino_tsCanId, 0
|
||||
defaultValue = true_address, 256
|
||||
defaultValue = realtime_base_address, 336
|
||||
defaultValue = speeduino_tsCanId, 0
|
||||
defaultValue = true_address, 256
|
||||
defaultValue = realtime_base_address, 336
|
||||
defaultValue = VVTasOnOff, 0
|
||||
defaultValue = stagingEnabled, 0
|
||||
defaultValue = lnchCtrlTPS, 0
|
||||
|
@ -1200,7 +1200,7 @@ page = 11
|
|||
defaultValue = aeColdTaperMin, 0
|
||||
defaultValue = aeColdTaperMax, 60
|
||||
defaultValue = aeMode, 0 ;Set aeMode to TPS
|
||||
defaultValue = batVoltCorrect, 0
|
||||
defaultValue = batVoltCorrect, 0
|
||||
defaultValue = legacyMAP, 0
|
||||
defaultValue = battVCorMode, 1
|
||||
defaultValue = idleAdvEnabled, 0 ;Idle advance control turned off
|
||||
|
@ -1210,6 +1210,7 @@ page = 11
|
|||
defaultValue = dfcoDelay, 0.1
|
||||
defaultValue = dfcoMinCLT, 25
|
||||
defaultValue = crankingEnrichTaper, 0.1
|
||||
defaultValue = boostCutEnabled, 1
|
||||
|
||||
;Default pins
|
||||
defaultValue = fanPin, 0
|
||||
|
@ -1562,9 +1563,11 @@ menuDialog = main
|
|||
flatSArm = "The RPM switch point that determines whether an eganged clutch is for launch control or flat shift. Below this figure, an engaged clutch is considered to be for launch, above this figure an active clutch input will be considered a flat shift. This should be set at least several hundred RPM above idle"
|
||||
flatSSoftWin = "The number of RPM below the flat shift point where the softlimit will be applied (aka Soft limit window). Recommended values are 200-1000"
|
||||
flatSRetard = "The absolute timing (BTDC) that will be used when within the soft limit window"
|
||||
hardCutType = "How hard cuts should be performed for rev/launch limits. Full cut will stop all ignition events, Rolling cut will step through all ignition outputs, only cutting 1 per revolution"
|
||||
engineProtectType = "Whether the engine protect an rev limiter will cut the fuel, the ignition or both"
|
||||
hardCutType = "How the cuts should be performed for rev/launch limits. Full cut will stop all fuel/ignition events, Rolling cut will step through all ignition outputs, only cutting a limited number per revolution"
|
||||
SoftLimitMode = "Fixed: the soft limiter will retard the ignition advance to the specified value.\nRelative: current timing advance will be retarted by the specified amount"
|
||||
|
||||
HardRevLim = "The hard rev limit is the point that the fuel or ignition (or both) will be cut completely to reduce increasing RPMs"
|
||||
engineProtectMaxRPM = "The RPM point that engine protections will engage from. Below this RPM value, engine protections will NOT be active"
|
||||
|
||||
fuel2InputPin = "The Arduino pin that is being used to trigger the second fuel table to be active"
|
||||
fuel2InputPolarity = "Whether the 2nd fuel table should be active when input is high or low. This should be LOW for a typical ground switching input"
|
||||
|
@ -2298,8 +2301,8 @@ menuDialog = main
|
|||
panel = rotaryTrailing_curve
|
||||
|
||||
dialog = boostCut, "Boost Cut"
|
||||
field = "Boost Cut", boostCutType
|
||||
field = "Boost Limit", boostLimit, { boostCutType }
|
||||
field = "Enable Boost limit", boostCutEnabled
|
||||
field = "Boost Limit", boostLimit, { boostCutEnabled }
|
||||
|
||||
dialog = boostLoad, ""
|
||||
field = "Mode", boostType
|
||||
|
@ -2307,16 +2310,38 @@ menuDialog = main
|
|||
field = "In closed loop mode, the values are boost targets in kPa"
|
||||
panel = boostTbl
|
||||
|
||||
dialog = RevLimiterS, "Rev Limiter", 4
|
||||
topicHelp = "https://wiki.speeduino.com/en/configuration/Rev_Limits"
|
||||
dialog = revLimiterDialog, "Rev Limiter"
|
||||
field = "Rev Limiter"
|
||||
field = "Soft rev limit", SoftRevLim
|
||||
field = "Soft limiter mode", SoftLimitMode
|
||||
field = "Soft limit timing", SoftLimRetard
|
||||
field = "Soft limit max time", SoftLimMax
|
||||
field = "Hard Rev limit", HardRevLim
|
||||
field = "Hard limiter method", hardCutType
|
||||
panel = boostCut
|
||||
|
||||
dialog = oilPressureProtection, "Oil Pressure"
|
||||
field = "Oil Pressure Protection", oilPressureProtEnbl, { oilPressureEnable }
|
||||
panel = oil_pressure_prot_curve, { oilPressureEnable && oilPressureProtEnbl }
|
||||
|
||||
indicatorPanel = protectIndicatorPanel, 1, { 1 }
|
||||
indicator = { engineProtectStatus}, "Engine Protect OFF", "Engine Protect ON", green, black, red, black
|
||||
indicator = { engineProtectRPM }, "Rev Limiter Off", "Rev Limiter ON", green, black, red, black
|
||||
indicator = { engineProtectMAP }, "Boost Limit OFF", "Boost Limit ON", green, black, red, black
|
||||
indicator = { engineProtectOil }, "Oil Pres. Protect OFF","Oil Pres. Protect ON",green, black, red, black
|
||||
indicator = { engineProtectAFR }, "AFR Protect OFF", "AFR Protect ON", green, black, red, black
|
||||
|
||||
dialog = engineProtectionWest, ""
|
||||
field = "Protection Cut", engineProtectType
|
||||
field = "Engine Protection RPM min", engineProtectMaxRPM, { engineProtectType }
|
||||
field = "Cut method", hardCutType, { engineProtectType }
|
||||
panel = protectIndicatorPanel, { engineProtectType }
|
||||
|
||||
dialog = RevLimiterS, "Engine Protection and Limiters", xAxis
|
||||
topicHelp = "https://wiki.speeduino.com/en/configuration/Rev_Limits"
|
||||
panel = engineProtectionWest
|
||||
panel = revLimiterDialog, { engineProtectType }
|
||||
panel = boostCut, { engineProtectType }
|
||||
panel = oilPressureProtection, { engineProtectType }
|
||||
|
||||
|
||||
dialog = clutchInput, "Clutch input"
|
||||
field = "Clutch Input Pin", launchPin, { launchEnable || flatSEnable }
|
||||
|
@ -2482,8 +2507,6 @@ menuDialog = main
|
|||
settingOption = "0-150 PSI", oilPressureMin=-18, oilPressureMax=168 ; Vout = VCC x (P x 0.8 / 150 + 0.1) https://aftermarketindustries.com.au/image/cache/data/aftermarket%20industries%20fuel%20pressure%20sensor%20data%202-500x500.png
|
||||
field = "Pressure at 0v", oilPressureMin, { oilPressureEnable }
|
||||
field = "Pressure at 5v", oilPressureMax, { oilPressureEnable }
|
||||
field = "Oil Pressure Protection", oilPressureProtEnbl, { oilPressureEnable }
|
||||
panel = oil_pressure_prot_curve, { oilPressureEnable }
|
||||
|
||||
dialog = oilPressureDialog, "Oil Pressure", xAxis
|
||||
gauge = oilPressureGauge
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
|
||||
byte checkEngineProtect();
|
||||
byte checkRevLimit();
|
||||
byte checkBoostLimit();
|
||||
byte checkOilPressureLimit();
|
||||
byte checkAFRLimit();
|
|
@ -5,7 +5,7 @@
|
|||
byte checkEngineProtect()
|
||||
{
|
||||
byte protectActive = 0;
|
||||
if(checkBoostLimit() || checkOilPressureLimit() || checkAFRLimit())
|
||||
if(checkRevLimit() || checkBoostLimit() || checkOilPressureLimit() || checkAFRLimit())
|
||||
{
|
||||
if(currentStatus.RPM > (configPage4.engineProtectMaxRPM*100U)) { protectActive = 1; }
|
||||
}
|
||||
|
@ -13,13 +13,32 @@ byte checkEngineProtect()
|
|||
return protectActive;
|
||||
}
|
||||
|
||||
byte checkRevLimit()
|
||||
{
|
||||
//Hardcut RPM limit
|
||||
byte revLimiterActive = 0;
|
||||
BIT_CLEAR(currentStatus.engineProtectStatus, ENGINE_PROTECT_BIT_RPM);
|
||||
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage4.HardRevLim) * 100) )
|
||||
{
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_HRDLIM); //Legacy and likely to be removed at some point
|
||||
BIT_SET(currentStatus.engineProtectStatus, ENGINE_PROTECT_BIT_RPM);
|
||||
revLimiterActive = 1;
|
||||
}
|
||||
else { BIT_CLEAR(currentStatus.spark, BIT_SPARK_HRDLIM); }
|
||||
|
||||
return revLimiterActive;
|
||||
}
|
||||
|
||||
byte checkBoostLimit()
|
||||
{
|
||||
byte boostLimitActive = 0;
|
||||
//Boost cutoff is very similar to launchControl, but with a check against MAP rather than a switch
|
||||
if( (configPage6.boostCutType > 0) && (currentStatus.MAP > (configPage6.boostLimit * 2)) ) //The boost limit is divided by 2 to allow a limit up to 511kPa
|
||||
if( (configPage6.boostCutEnabled > 0) && (currentStatus.MAP > (configPage6.boostLimit * 2)) ) //The boost limit is divided by 2 to allow a limit up to 511kPa
|
||||
{
|
||||
boostLimitActive = 1;
|
||||
BIT_SET(currentStatus.engineProtectStatus, ENGINE_PROTECT_BIT_MAP);
|
||||
/*
|
||||
switch(configPage6.boostCutType)
|
||||
{
|
||||
case 1:
|
||||
|
@ -40,6 +59,7 @@ byte checkBoostLimit()
|
|||
BIT_CLEAR(currentStatus.status1, BIT_STATUS1_BOOSTCUT);
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_BOOSTCUT);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -70,6 +90,8 @@ byte checkOilPressureLimit()
|
|||
|
||||
byte checkAFRLimit()
|
||||
{
|
||||
byte checkAFRLimitActive = 0;
|
||||
|
||||
return checkAFRLimitActive ;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,6 +227,11 @@
|
|||
#define NITROUS_STAGE2 2
|
||||
#define NITROUS_BOTH 3
|
||||
|
||||
#define PROTECT_CUT_OFF 0
|
||||
#define PROTECT_CUT_IGN 1
|
||||
#define PROTECT_CUT_FUEL 2
|
||||
#define PROTECT_CUT_BOTH 3
|
||||
|
||||
#define AE_MODE_TPS 0
|
||||
#define AE_MODE_MAP 1
|
||||
|
||||
|
@ -817,7 +822,7 @@ struct config6 {
|
|||
byte egoType : 2;
|
||||
byte boostEnabled : 1;
|
||||
byte vvtEnabled : 1;
|
||||
byte boostCutType : 2;
|
||||
byte engineProtectType : 2;
|
||||
|
||||
byte egoKP;
|
||||
byte egoKI;
|
||||
|
@ -829,7 +834,7 @@ struct config6 {
|
|||
byte vvtCLDir : 1; //VVT direction (advance or retard)
|
||||
byte vvtCLUseHold : 1; //Whether or not to use a hold duty cycle (Most cases are Yes)
|
||||
byte vvtCLAlterFuelTiming : 1;
|
||||
byte unused6_6 : 1;
|
||||
byte boostCutEnabled : 1;
|
||||
byte egoLimit; //Maximum amount the closed loop will vary the fueling
|
||||
byte ego_min; //AFR must be above this for closed loop to function
|
||||
byte ego_max; //AFR must be below this for closed loop to function
|
||||
|
|
|
@ -574,14 +574,18 @@ byte getFuelPressure()
|
|||
int16_t tempFuelPressure = 0;
|
||||
uint16_t tempReading;
|
||||
|
||||
//Perform ADC read
|
||||
tempReading = analogRead(pinFuelPressure);
|
||||
tempReading = analogRead(pinFuelPressure);
|
||||
if(configPage10.fuelPressureEnable)
|
||||
{
|
||||
//Perform ADC read
|
||||
tempReading = analogRead(pinFuelPressure);
|
||||
tempReading = analogRead(pinFuelPressure);
|
||||
|
||||
tempFuelPressure = fastMap10Bit(tempReading, configPage10.fuelPressureMin, configPage10.fuelPressureMax);
|
||||
//Sanity checks
|
||||
if(tempFuelPressure < 0) { tempFuelPressure = 0; }
|
||||
if(tempFuelPressure > configPage10.fuelPressureMax) { tempFuelPressure = configPage10.fuelPressureMax; }
|
||||
}
|
||||
|
||||
tempFuelPressure = fastMap10Bit(tempReading, configPage10.fuelPressureMin, configPage10.fuelPressureMax);
|
||||
//Sanity checks
|
||||
if(tempFuelPressure < 0) { tempFuelPressure = 0; }
|
||||
if(tempFuelPressure > configPage10.fuelPressureMax) { tempFuelPressure = configPage10.fuelPressureMax; }
|
||||
|
||||
return (byte)tempFuelPressure;
|
||||
}
|
||||
|
@ -591,15 +595,19 @@ byte getOilPressure()
|
|||
int16_t tempOilPressure = 0;
|
||||
uint16_t tempReading;
|
||||
|
||||
//Perform ADC read
|
||||
tempReading = analogRead(pinOilPressure);
|
||||
tempReading = analogRead(pinOilPressure);
|
||||
if(configPage10.oilPressureEnable)
|
||||
{
|
||||
//Perform ADC read
|
||||
tempReading = analogRead(pinOilPressure);
|
||||
tempReading = analogRead(pinOilPressure);
|
||||
|
||||
|
||||
tempOilPressure = fastMap10Bit(tempReading, configPage10.oilPressureMin, configPage10.oilPressureMax);
|
||||
//Sanity checks
|
||||
if(tempOilPressure < 0) { tempOilPressure = 0; }
|
||||
if(tempOilPressure > configPage10.oilPressureMax) { tempOilPressure = configPage10.oilPressureMax; }
|
||||
tempOilPressure = fastMap10Bit(tempReading, configPage10.oilPressureMin, configPage10.oilPressureMax);
|
||||
//Sanity checks
|
||||
if(tempOilPressure < 0) { tempOilPressure = 0; }
|
||||
if(tempOilPressure > configPage10.oilPressureMax) { tempOilPressure = configPage10.oilPressureMax; }
|
||||
}
|
||||
|
||||
|
||||
return (byte)tempOilPressure;
|
||||
}
|
||||
|
|
|
@ -677,9 +677,6 @@ void loop()
|
|||
|
||||
//***********************************************************************************************
|
||||
//| BEGIN IGNITION CALCULATIONS
|
||||
if (currentStatus.RPM > ((unsigned int)(configPage4.HardRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_HRDLIM); } //Hardcut RPM limit
|
||||
else { BIT_CLEAR(currentStatus.spark, BIT_SPARK_HRDLIM); }
|
||||
|
||||
|
||||
//Set dwell
|
||||
//Dwell is stored as ms * 10. ie Dwell of 4.3ms would be 43 in configPage4. This number therefore needs to be multiplied by 100 to get dwell in uS
|
||||
|
@ -722,6 +719,56 @@ void loop()
|
|||
// interrupts();
|
||||
// }
|
||||
// }
|
||||
|
||||
//Check for any of the engine protections or rev limiters being turned on
|
||||
if(checkEngineProtect() || currentStatus.launchingHard || currentStatus.flatShiftingHard)
|
||||
{
|
||||
if(currentStatus.RPMdiv100 > configPage4.engineProtectMaxRPM)
|
||||
{
|
||||
if(configPage2.hardCutType == HARD_CUT_FULL)
|
||||
{
|
||||
switch(configPage6.engineProtectType)
|
||||
{
|
||||
case PROTECT_CUT_IGN:
|
||||
ignitionOn = false;
|
||||
break;
|
||||
case PROTECT_CUT_FUEL:
|
||||
fuelOn = false;
|
||||
break;
|
||||
case PROTECT_CUT_BOTH:
|
||||
ignitionOn = false;
|
||||
fuelOn = false;
|
||||
break;
|
||||
default:
|
||||
ignitionOn = false;
|
||||
fuelOn = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rollingCutCounter >= 2) //Vary this number to change the intensity of the roll. The higher the number, the closer is it to full cut
|
||||
{
|
||||
//Rolls through each of the active ignition channels based on how many revolutions have taken place
|
||||
//curRollingCut = ( (currentStatus.startRevolutions / 2) % maxIgnOutputs) + 1;
|
||||
rollingCutCounter = 0;
|
||||
ignitionOn = true;
|
||||
curRollingCut = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rollingCutLastRev == 0) { rollingCutLastRev = currentStatus.startRevolutions; } //
|
||||
if (rollingCutLastRev != currentStatus.startRevolutions)
|
||||
{
|
||||
rollingCutLastRev = currentStatus.startRevolutions;
|
||||
rollingCutCounter++;
|
||||
}
|
||||
ignitionOn = false; //Finally the ignition is fully cut completely
|
||||
}
|
||||
} //Hard/Rolling cut check
|
||||
} //RPM Check
|
||||
} //Protection active check
|
||||
else { curRollingCut = 0; } //Disables the rolling hard cut
|
||||
|
||||
#if INJ_CHANNELS >= 1
|
||||
if (fuelOn && !BIT_CHECK(currentStatus.status1, BIT_STATUS1_BOOSTCUT))
|
||||
|
@ -899,40 +946,14 @@ void loop()
|
|||
ignition2StartAngle -= 5;
|
||||
ignition3StartAngle -= 5;
|
||||
ignition4StartAngle -= 5;
|
||||
ignition5StartAngle -= 5;
|
||||
ignition6StartAngle -= 5;
|
||||
ignition7StartAngle -= 5;
|
||||
ignition8StartAngle -= 5;
|
||||
}
|
||||
}
|
||||
else { fixedCrankingOverride = 0; }
|
||||
|
||||
//Perform an initial check to see if the ignition is turned on (Ignition only turns on after a preset number of cranking revolutions and:
|
||||
//Check for any of the hard cut rev limits being on
|
||||
if(checkEngineProtect() || currentStatus.launchingHard || BIT_CHECK(currentStatus.spark, BIT_SPARK_HRDLIM) || currentStatus.flatShiftingHard)
|
||||
{
|
||||
if(configPage2.hardCutType == HARD_CUT_FULL) { ignitionOn = false; }
|
||||
else
|
||||
{
|
||||
if(rollingCutCounter >= 2) //Vary this number to change the intensity of the roll. The higher the number, the closer is it to full cut
|
||||
{
|
||||
//Rolls through each of the active ignition channels based on how many revolutions have taken place
|
||||
//curRollingCut = ( (currentStatus.startRevolutions / 2) % maxIgnOutputs) + 1;
|
||||
rollingCutCounter = 0;
|
||||
ignitionOn = true;
|
||||
curRollingCut = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rollingCutLastRev == 0) { rollingCutLastRev = currentStatus.startRevolutions; } //
|
||||
if (rollingCutLastRev != currentStatus.startRevolutions)
|
||||
{
|
||||
rollingCutLastRev = currentStatus.startRevolutions;
|
||||
rollingCutCounter++;
|
||||
}
|
||||
ignitionOn = false; //Finally the ignition is fully cut completely
|
||||
}
|
||||
}
|
||||
}
|
||||
else { curRollingCut = 0; } //Disables the rolling hard cut
|
||||
|
||||
//if(ignitionOn && !currentStatus.launchingHard && !BIT_CHECK(currentStatus.spark, BIT_SPARK_BOOSTCUT) && !BIT_CHECK(currentStatus.spark, BIT_SPARK_HRDLIM) && !currentStatus.flatShiftingHard)
|
||||
if(ignitionOn)
|
||||
{
|
||||
//Refresh the current crank angle info
|
||||
|
|
Loading…
Reference in New Issue