Added taper entering DFCO (#1118)
* Added taper for DFCO for ignition and fuel Used 1 byte of RAM and 4 on page 9 * Moved data to be compatible with DFCO map thres * Added taper for DFCO for ignition and fuel Used 1 byte of RAM and 4 on page 9 * Moved data to be compatible with DFCO map thres * Fixed potential overflow and DFCO tests * Moved math into functions and added tests --------- Co-authored-by: Josh Stewart <josh@noisymime.org>
This commit is contained in:
parent
602203d3e0
commit
f8ffbb13da
|
@ -1075,7 +1075,15 @@ page = 9
|
||||||
coolantProtTemp = array, U08, 173, [6], "F", 1.8, -22.23, -40, 419, 0
|
coolantProtTemp = array, U08, 173, [6], "F", 1.8, -22.23, -40, 419, 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unused179_184 = array, U08, 179, [6], "", 1, 0, 0, 255, 0
|
unused10_179 = scalar, U08, 179, "", 1, 0, 0, 255, 0
|
||||||
|
|
||||||
|
dfcoTaperTime = scalar, U08, 180, "S", 0.1, 0.0, 0.0, 25.5, 1
|
||||||
|
dfcoTaperFuel = scalar, U08, 181, "%", 1.0, 0.0, 0, 255, 0
|
||||||
|
dfcoTaperAdvance = scalar, U08, 182, "deg", 1.0, 0.0, 0, 40, 0
|
||||||
|
dfcoTaperEnable = bits, U08, 183, [0:0], "Off", "On"
|
||||||
|
unused10_182 = bits, U08, 183, [1:7], ""
|
||||||
|
|
||||||
|
unused10_184 = scalar, U08, 184, "", 1, 0, 0, 255, 0
|
||||||
|
|
||||||
; AFR engine protection
|
; AFR engine protection
|
||||||
afrProtectEnabled = bits, U08, 185, [0:1], "Off", "Fixed mode", "Table mode", "INVALID"
|
afrProtectEnabled = bits, U08, 185, [0:1], "Off", "Fixed mode", "Table mode", "INVALID"
|
||||||
|
@ -2594,6 +2602,10 @@ menuDialog = main
|
||||||
field = "Cutoff delay", dfcoDelay, { dfcoEnabled }
|
field = "Cutoff delay", dfcoDelay, { dfcoEnabled }
|
||||||
field = "Cutoff RPM", dfcoRPM, { dfcoEnabled }
|
field = "Cutoff RPM", dfcoRPM, { dfcoEnabled }
|
||||||
field = "RPM Hysteresis", dfcoHyster, { dfcoEnabled }
|
field = "RPM Hysteresis", dfcoHyster, { dfcoEnabled }
|
||||||
|
field = "Enable cutoff taper", dfcoTaperEnable, { dfcoEnabled }
|
||||||
|
field = "Cutoff taper time", dfcoTaperTime, { dfcoEnabled && dfcoTaperEnable }
|
||||||
|
field = "Taper end fuel amount", dfcoTaperFuel, { dfcoEnabled && dfcoTaperEnable }
|
||||||
|
field = "Taper advance remove", dfcoTaperAdvance, { dfcoEnabled && dfcoTaperEnable }
|
||||||
|
|
||||||
dialog = accelEnrichments_north_south, ""
|
dialog = accelEnrichments_north_south, ""
|
||||||
liveGraph = pump_ae_Graph, "AE Graph"
|
liveGraph = pump_ae_Graph, "AE Graph"
|
||||||
|
|
|
@ -48,9 +48,10 @@ byte lastKnockCount;
|
||||||
int16_t knockWindowMin; //The current minimum crank angle for a knock pulse to be valid
|
int16_t knockWindowMin; //The current minimum crank angle for a knock pulse to be valid
|
||||||
int16_t knockWindowMax;//The current maximum crank angle for a knock pulse to be valid
|
int16_t knockWindowMax;//The current maximum crank angle for a knock pulse to be valid
|
||||||
uint8_t aseTaper;
|
uint8_t aseTaper;
|
||||||
uint8_t dfcoTaper;
|
uint8_t dfcoDelay;
|
||||||
uint8_t idleAdvTaper;
|
uint8_t idleAdvTaper;
|
||||||
uint8_t crankingEnrichTaper;
|
uint8_t crankingEnrichTaper;
|
||||||
|
uint8_t dfcoTaper;
|
||||||
|
|
||||||
/** Initialise instances and vars related to corrections (at ECU boot-up).
|
/** Initialise instances and vars related to corrections (at ECU boot-up).
|
||||||
*/
|
*/
|
||||||
|
@ -122,7 +123,9 @@ uint16_t correctionsFuel(void)
|
||||||
if (currentStatus.launchCorrection != 100) { sumCorrections = div100(sumCorrections * currentStatus.launchCorrection); }
|
if (currentStatus.launchCorrection != 100) { sumCorrections = div100(sumCorrections * currentStatus.launchCorrection); }
|
||||||
|
|
||||||
bitWrite(currentStatus.status1, BIT_STATUS1_DFCO, correctionDFCO());
|
bitWrite(currentStatus.status1, BIT_STATUS1_DFCO, correctionDFCO());
|
||||||
if ( BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) == 1 ) { sumCorrections = 0; }
|
byte dfcoTaperCorrection = correctionDFCOfuel();
|
||||||
|
if (dfcoTaperCorrection == 0) { sumCorrections = 0; }
|
||||||
|
else if (dfcoTaperCorrection != 100) { sumCorrections = div100(sumCorrections * dfcoTaperCorrection); }
|
||||||
|
|
||||||
if(sumCorrections > 1500) { sumCorrections = 1500; } //This is the maximum allowable increase during cranking
|
if(sumCorrections > 1500) { sumCorrections = 1500; } //This is the maximum allowable increase during cranking
|
||||||
return (uint16_t)sumCorrections;
|
return (uint16_t)sumCorrections;
|
||||||
|
@ -539,6 +542,27 @@ byte correctionLaunch(void)
|
||||||
return launchValue;
|
return launchValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
byte correctionDFCOfuel(void)
|
||||||
|
{
|
||||||
|
byte scaleValue = 100;
|
||||||
|
if ( BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) )
|
||||||
|
{
|
||||||
|
if ( (configPage9.dfcoTaperEnable == 1) && (dfcoTaper != 0) )
|
||||||
|
{
|
||||||
|
//Do a check if the user reduced the duration while active to avoid overflow
|
||||||
|
if (dfcoTaper > configPage9.dfcoTaperTime) { dfcoTaper = configPage9.dfcoTaperTime; }
|
||||||
|
scaleValue = map(dfcoTaper, configPage9.dfcoTaperTime, 0, 100, configPage9.dfcoTaperFuel);
|
||||||
|
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { dfcoTaper--; }
|
||||||
|
}
|
||||||
|
else { scaleValue = 0; } //Taper ended or disabled, disable fuel
|
||||||
|
}
|
||||||
|
else { dfcoTaper = configPage9.dfcoTaperTime; } //Keep updating the duration until DFCO is active
|
||||||
|
|
||||||
|
return scaleValue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if deceleration fuel cutoff should be on, false if its off
|
* Returns true if deceleration fuel cutoff should be on, false if its off
|
||||||
*/
|
*/
|
||||||
|
@ -550,19 +574,19 @@ bool correctionDFCO(void)
|
||||||
if ( BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) == 1 )
|
if ( BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) == 1 )
|
||||||
{
|
{
|
||||||
DFCOValue = ( currentStatus.RPM > ( configPage4.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh );
|
DFCOValue = ( currentStatus.RPM > ( configPage4.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh );
|
||||||
if ( DFCOValue == false) { dfcoTaper = 0; }
|
if ( DFCOValue == false) { dfcoDelay = 0; }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( (currentStatus.TPS < configPage4.dfcoTPSThresh) && (currentStatus.coolant >= (int)(configPage2.dfcoMinCLT - CALIBRATION_TEMPERATURE_OFFSET)) && ( currentStatus.RPM > (unsigned int)( (configPage4.dfcoRPM * 10) + (configPage4.dfcoHyster * 2)) ) )
|
if ( (currentStatus.TPS < configPage4.dfcoTPSThresh) && (currentStatus.coolant >= (int)(configPage2.dfcoMinCLT - CALIBRATION_TEMPERATURE_OFFSET)) && ( currentStatus.RPM > (unsigned int)( (configPage4.dfcoRPM * 10) + (configPage4.dfcoHyster * 2)) ) )
|
||||||
{
|
{
|
||||||
if( dfcoTaper < configPage2.dfcoDelay )
|
if( dfcoDelay < configPage2.dfcoDelay )
|
||||||
{
|
{
|
||||||
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { dfcoTaper++; }
|
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { dfcoDelay++; }
|
||||||
}
|
}
|
||||||
else { DFCOValue = true; }
|
else { DFCOValue = true; }
|
||||||
}
|
}
|
||||||
else { dfcoTaper = 0; } //Prevent future activation right away if previous time wasn't activated
|
else { dfcoDelay = 0; } //Prevent future activation right away if previous time wasn't activated
|
||||||
} // DFCO active check
|
} // DFCO active check
|
||||||
} // DFCO enabled check
|
} // DFCO enabled check
|
||||||
return DFCOValue;
|
return DFCOValue;
|
||||||
|
@ -702,6 +726,8 @@ int8_t correctionsIgn(int8_t base_advance)
|
||||||
advance = correctionSoftFlatShift(advance);
|
advance = correctionSoftFlatShift(advance);
|
||||||
advance = correctionKnock(advance);
|
advance = correctionKnock(advance);
|
||||||
|
|
||||||
|
advance = correctionDFCOignition(advance);
|
||||||
|
|
||||||
//Fixed timing check must go last
|
//Fixed timing check must go last
|
||||||
advance = correctionFixedTiming(advance);
|
advance = correctionFixedTiming(advance);
|
||||||
advance = correctionCrankingFixedTiming(advance); //This overrides the regular fixed timing, must come last
|
advance = correctionCrankingFixedTiming(advance); //This overrides the regular fixed timing, must come last
|
||||||
|
@ -936,6 +962,23 @@ int8_t correctionKnock(int8_t advance)
|
||||||
return advance - knockRetard;
|
return advance - knockRetard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Ignition DFCO taper correction.
|
||||||
|
*/
|
||||||
|
int8_t correctionDFCOignition(int8_t advance)
|
||||||
|
{
|
||||||
|
int8_t dfcoRetard = advance;
|
||||||
|
if ( (configPage9.dfcoTaperEnable == 1) && BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) )
|
||||||
|
{
|
||||||
|
if ( dfcoTaper != 0 )
|
||||||
|
{
|
||||||
|
dfcoRetard -= map(dfcoTaper, configPage9.dfcoTaperTime, 0, 0, configPage9.dfcoTaperAdvance);
|
||||||
|
}
|
||||||
|
else { dfcoRetard -= configPage9.dfcoTaperAdvance; } //Taper ended, use full value
|
||||||
|
}
|
||||||
|
else { dfcoTaper = configPage9.dfcoTaperTime; } //Keep updating the duration until DFCO is active
|
||||||
|
return dfcoRetard;
|
||||||
|
}
|
||||||
|
|
||||||
/** Ignition Dwell Correction.
|
/** Ignition Dwell Correction.
|
||||||
*/
|
*/
|
||||||
uint16_t correctionsDwell(uint16_t dwell)
|
uint16_t correctionsDwell(uint16_t dwell)
|
||||||
|
|
|
@ -21,6 +21,7 @@ byte correctionBatVoltage(void); //Battery voltage correction
|
||||||
byte correctionIATDensity(void); //Inlet temp density correction
|
byte correctionIATDensity(void); //Inlet temp density correction
|
||||||
byte correctionBaro(void); //Barometric pressure correction
|
byte correctionBaro(void); //Barometric pressure correction
|
||||||
byte correctionLaunch(void); //Launch control correction
|
byte correctionLaunch(void); //Launch control correction
|
||||||
|
byte correctionDFCOfuel(void); //DFCO taper correction
|
||||||
bool correctionDFCO(void); //Decelleration fuel cutoff
|
bool correctionDFCO(void); //Decelleration fuel cutoff
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ int8_t correctionNitrous(int8_t advance);
|
||||||
int8_t correctionSoftLaunch(int8_t advance);
|
int8_t correctionSoftLaunch(int8_t advance);
|
||||||
int8_t correctionSoftFlatShift(int8_t advance);
|
int8_t correctionSoftFlatShift(int8_t advance);
|
||||||
int8_t correctionKnock(int8_t advance);
|
int8_t correctionKnock(int8_t advance);
|
||||||
|
int8_t correctionDFCOignition(int8_t advance);
|
||||||
|
|
||||||
uint16_t correctionsDwell(uint16_t dwell);
|
uint16_t correctionsDwell(uint16_t dwell);
|
||||||
|
|
||||||
|
@ -49,8 +51,9 @@ extern byte lastKnockCount;
|
||||||
extern int16_t knockWindowMin; //The current minimum crank angle for a knock pulse to be valid
|
extern int16_t knockWindowMin; //The current minimum crank angle for a knock pulse to be valid
|
||||||
extern int16_t knockWindowMax;//The current maximum crank angle for a knock pulse to be valid
|
extern int16_t knockWindowMax;//The current maximum crank angle for a knock pulse to be valid
|
||||||
extern uint8_t aseTaper;
|
extern uint8_t aseTaper;
|
||||||
extern uint8_t dfcoTaper;
|
extern uint8_t dfcoDelay;
|
||||||
extern uint8_t idleAdvTaper;
|
extern uint8_t idleAdvTaper;
|
||||||
extern uint8_t crankingEnrichTaper;
|
extern uint8_t crankingEnrichTaper;
|
||||||
|
extern uint8_t dfcoTaper;
|
||||||
|
|
||||||
#endif // CORRECTIONS_H
|
#endif // CORRECTIONS_H
|
||||||
|
|
|
@ -1128,12 +1128,16 @@ struct config9 {
|
||||||
byte hardRevMode : 2;
|
byte hardRevMode : 2;
|
||||||
byte coolantProtRPM[6];
|
byte coolantProtRPM[6];
|
||||||
byte coolantProtTemp[6];
|
byte coolantProtTemp[6];
|
||||||
|
|
||||||
byte unused10_179;
|
byte unused10_179;
|
||||||
byte unused10_180;
|
byte dfcoTaperTime;
|
||||||
byte unused10_181;
|
byte dfcoTaperFuel;
|
||||||
byte unused10_182;
|
byte dfcoTaperAdvance;
|
||||||
byte unused10_183;
|
byte dfcoTaperEnable : 1;
|
||||||
|
byte unused10_183 : 6;
|
||||||
|
|
||||||
byte unused10_184;
|
byte unused10_184;
|
||||||
|
|
||||||
byte afrProtectEnabled : 2; /* < AFR protection enabled status. 0 = disabled, 1 = fixed mode, 2 = table mode */
|
byte afrProtectEnabled : 2; /* < AFR protection enabled status. 0 = disabled, 1 = fixed mode, 2 = table mode */
|
||||||
byte afrProtectMinMAP; /* < Minimum MAP. Stored value is divided by 2. Increments of 2 kPa, maximum 511 (?) kPa */
|
byte afrProtectMinMAP; /* < Minimum MAP. Stored value is divided by 2. Increments of 2 kPa, maximum 511 (?) kPa */
|
||||||
byte afrProtectMinRPM; /* < Minimum RPM. Stored value is divded by 100. Increments of 100 RPM, maximum 25500 RPM */
|
byte afrProtectMinRPM; /* < Minimum RPM. Stored value is divded by 100. Increments of 100 RPM, maximum 25500 RPM */
|
||||||
|
|
|
@ -727,7 +727,11 @@ void doUpdates(void)
|
||||||
if(readEEPROMVersion() == 22)
|
if(readEEPROMVersion() == 22)
|
||||||
{
|
{
|
||||||
//202311-dev
|
//202311-dev
|
||||||
|
configPage9.dfcoTaperEnable = 0; //Disable
|
||||||
|
configPage9.dfcoTaperTime = 10; //1 second
|
||||||
|
configPage9.dfcoTaperFuel = 100; //Don't scale fuel
|
||||||
|
configPage9.dfcoTaperAdvance = 20; //Reduce 20deg until full fuel cut
|
||||||
|
|
||||||
//EGO MAP Limits
|
//EGO MAP Limits
|
||||||
configPage9.egoMAPMax = 255, // 255 will be 510 kpa
|
configPage9.egoMAPMax = 255, // 255 will be 510 kpa
|
||||||
configPage9.egoMAPMin = 0, // 0 will be 0 kpa
|
configPage9.egoMAPMin = 0, // 0 will be 0 kpa
|
||||||
|
|
|
@ -137,9 +137,9 @@ void setup_DFCO_on()
|
||||||
configPage2.dfcoMinCLT = 40; //Actually 0 with offset
|
configPage2.dfcoMinCLT = 40; //Actually 0 with offset
|
||||||
configPage2.dfcoDelay = 10;
|
configPage2.dfcoDelay = 10;
|
||||||
|
|
||||||
dfcoTaper = 1;
|
dfcoDelay = 1;
|
||||||
correctionDFCO();
|
correctionDFCO();
|
||||||
dfcoTaper = 20;
|
dfcoDelay = 20;
|
||||||
}
|
}
|
||||||
//**********************************************************************************************************************
|
//**********************************************************************************************************************
|
||||||
void test_corrections_dfco_on(void)
|
void test_corrections_dfco_on(void)
|
||||||
|
@ -178,6 +178,65 @@ void test_corrections_dfco_off_delay()
|
||||||
|
|
||||||
TEST_ASSERT_FALSE(correctionDFCO()); //Make sure DFCO does not come on
|
TEST_ASSERT_FALSE(correctionDFCO()); //Make sure DFCO does not come on
|
||||||
}
|
}
|
||||||
|
void setup_DFCO_taper_on()
|
||||||
|
{
|
||||||
|
//Test that DFCO comes will not activate if there has not been a long enough delay
|
||||||
|
//The steup function below simulates a 2 second delay
|
||||||
|
setup_DFCO_on();
|
||||||
|
|
||||||
|
configPage9.dfcoTaperEnable = 1; //Enable
|
||||||
|
configPage9.dfcoTaperTime = 20; //2.0 second
|
||||||
|
configPage9.dfcoTaperFuel = 0; //Scale fuel to 0%
|
||||||
|
configPage9.dfcoTaperAdvance = 20; //Reduce 20deg until full fuel cut
|
||||||
|
|
||||||
|
BIT_CLEAR(currentStatus.status1, BIT_STATUS1_DFCO);
|
||||||
|
//Set the threshold to be 2.5 seconds, above the simulated delay of 2s
|
||||||
|
configPage2.dfcoDelay = 250;
|
||||||
|
}
|
||||||
|
void test_corrections_dfco_taper()
|
||||||
|
{
|
||||||
|
setup_DFCO_taper_on();
|
||||||
|
|
||||||
|
TEST_ASSERT_FALSE(correctionDFCO()); //Make sure DFCO does not come on
|
||||||
|
correctionDFCOfuel();
|
||||||
|
TEST_ASSERT_EQUAL(20, dfcoTaper); //Check if value was reset to setting
|
||||||
|
}
|
||||||
|
void test_corrections_dfco_taper_fuel()
|
||||||
|
{
|
||||||
|
setup_DFCO_taper_on();
|
||||||
|
|
||||||
|
correctionDFCOfuel();
|
||||||
|
TEST_ASSERT_EQUAL(20, dfcoTaper); //Check if value was reset to setting
|
||||||
|
|
||||||
|
BIT_SET(currentStatus.status1, BIT_STATUS1_DFCO);
|
||||||
|
dfcoTaper = 10;
|
||||||
|
TEST_ASSERT_EQUAL(50, correctionDFCOfuel());
|
||||||
|
dfcoTaper = 5;
|
||||||
|
TEST_ASSERT_EQUAL(25, correctionDFCOfuel());
|
||||||
|
|
||||||
|
configPage9.dfcoTaperTime = 10; //1.0 second
|
||||||
|
dfcoTaper = 15; //Check for overflow
|
||||||
|
TEST_ASSERT_EQUAL(100, correctionDFCOfuel());
|
||||||
|
configPage9.dfcoTaperEnable = 0; //Disable
|
||||||
|
TEST_ASSERT_EQUAL(0, correctionDFCOfuel());
|
||||||
|
}
|
||||||
|
void test_corrections_dfco_taper_ign()
|
||||||
|
{
|
||||||
|
setup_DFCO_taper_on();
|
||||||
|
|
||||||
|
dfcoTaper = 20;
|
||||||
|
BIT_SET(currentStatus.status1, BIT_STATUS1_DFCO);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(20, correctionDFCOignition(20));
|
||||||
|
dfcoTaper = 15;
|
||||||
|
TEST_ASSERT_EQUAL(15, correctionDFCOignition(20));
|
||||||
|
dfcoTaper = 10;
|
||||||
|
TEST_ASSERT_EQUAL(10, correctionDFCOignition(20));
|
||||||
|
dfcoTaper = 5;
|
||||||
|
TEST_ASSERT_EQUAL(5, correctionDFCOignition(20));
|
||||||
|
configPage9.dfcoTaperEnable = 0; //Disable
|
||||||
|
TEST_ASSERT_EQUAL(20, correctionDFCOignition(20));
|
||||||
|
}
|
||||||
|
|
||||||
void test_corrections_dfco()
|
void test_corrections_dfco()
|
||||||
{
|
{
|
||||||
|
@ -185,6 +244,9 @@ void test_corrections_dfco()
|
||||||
RUN_TEST(test_corrections_dfco_off_RPM);
|
RUN_TEST(test_corrections_dfco_off_RPM);
|
||||||
RUN_TEST(test_corrections_dfco_off_TPS);
|
RUN_TEST(test_corrections_dfco_off_TPS);
|
||||||
RUN_TEST(test_corrections_dfco_off_delay);
|
RUN_TEST(test_corrections_dfco_off_delay);
|
||||||
|
RUN_TEST(test_corrections_dfco_taper);
|
||||||
|
RUN_TEST(test_corrections_dfco_taper_fuel);
|
||||||
|
RUN_TEST(test_corrections_dfco_taper_ign);
|
||||||
}
|
}
|
||||||
//**********************************************************************************************************************
|
//**********************************************************************************************************************
|
||||||
//Setup a basic TAE enrichment curve, threshold etc that are common to all tests. Specifica values maybe updated in each individual test
|
//Setup a basic TAE enrichment curve, threshold etc that are common to all tests. Specifica values maybe updated in each individual test
|
||||||
|
|
Loading…
Reference in New Issue