All tapers use byte counters (#746)

Fixes

Update idle.ino
This commit is contained in:
Vitor Moreno B. Sales 2022-04-04 18:27:54 -03:00 committed by GitHub
parent 2411fbdddb
commit 9c3f745c16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 56 additions and 38 deletions

View File

@ -49,8 +49,9 @@ extern unsigned long knockStartTime;
extern byte lastKnockCount;
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 uint16_t aseTaperStart;
extern uint16_t dfcoStart;
extern uint16_t idleAdvStart;
extern uint8_t aseTaper;
extern uint8_t dfcoTaper;
extern uint8_t idleAdvTaper;
extern uint8_t crankingEnrichTaper;
#endif // CORRECTIONS_H

View File

@ -48,9 +48,10 @@ unsigned long knockStartTime;
byte lastKnockCount;
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
uint16_t aseTaperStart;
uint16_t dfcoStart;
uint16_t idleAdvStart;
uint8_t aseTaper;
uint8_t dfcoTaper;
uint8_t idleAdvTaper;
uint8_t crankingEnrichTaper;
/** Initialize instances and vars related to corrections (at ECU boot-up).
*/
@ -214,17 +215,19 @@ uint16_t correctionCranking()
{
crankingValue = table2D_getValue(&crankingEnrichTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
crankingValue = (uint16_t) crankingValue * 5; //multiplied by 5 to get range from 0% to 1275%
crankingEnrichTaper = 0;
}
//If we're not cranking, check if if cranking enrichment tapering to ASE should be done
else if ( (uint32_t) runSecsX10 <= configPage10.crankingEnrichTaper)
else if ( crankingEnrichTaper < configPage10.crankingEnrichTaper )
{
crankingValue = table2D_getValue(&crankingEnrichTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
crankingValue = (uint16_t) crankingValue * 5; //multiplied by 5 to get range from 0% to 1275%
//Taper start value needs to account for ASE that is now running, so total correction does not increase when taper begins
unsigned long taperStart = (unsigned long) crankingValue * 100 / currentStatus.ASEValue;
crankingValue = (uint16_t) map(runSecsX10, 0, configPage10.crankingEnrichTaper, taperStart, 100); //Taper from start value to 100%
crankingValue = (uint16_t) map(crankingEnrichTaper, 0, configPage10.crankingEnrichTaper, taperStart, 100); //Taper from start value to 100%
if (crankingValue < 100) { crankingValue = 100; } //Sanity check
if( BIT_CHECK(TIMER_mask, BIT_TIMER_10HZ) ) { crankingEnrichTaper++; }
}
return crankingValue;
}
@ -241,21 +244,21 @@ byte correctionASE()
//Two checks are requiredL:
//1) Is the engine run time less than the configured ase time
//2) Make sure we're not still cranking
if ( BIT_CHECK(TIMER_mask, BIT_TIMER_10HZ) || (currentStatus.ASEValue == 0) )
if ( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) || (currentStatus.ASEValue == 0) )
{
if ( (currentStatus.runSecs < (table2D_getValue(&ASECountTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET))) && !(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as active.
ASEValue = 100 + table2D_getValue(&ASETable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
aseTaperStart = runSecsX10;
aseTaper = 0;
}
else
{
if ( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && ((runSecsX10 - aseTaperStart) < configPage2.aseTaperTime) ) //Cranking check needs to be here also, so cranking and afterstart enrichments won't run simultaneously
if ( (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) && (aseTaper < configPage2.aseTaperTime) ) //Cranking check needs to be here also, so cranking and afterstart enrichments won't run simultaneously
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as active.
ASEValue = 100 + map((runSecsX10 - aseTaperStart), 0, configPage2.aseTaperTime,\
table2D_getValue(&ASETable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET), 0);
ASEValue = 100 + map(aseTaper, 0, configPage2.aseTaperTime, table2D_getValue(&ASETable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET), 0);
aseTaper++;
}
else
{
@ -532,16 +535,19 @@ bool correctionDFCO()
if ( BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO) == 1 )
{
DFCOValue = ( currentStatus.RPM > ( configPage4.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh );
if ( DFCOValue == false) { dfcoStart = 0; }
if ( DFCOValue == false) { dfcoTaper = 0; }
}
else
{
if ( ( currentStatus.coolant >= (int)(configPage2.dfcoMinCLT - CALIBRATION_TEMPERATURE_OFFSET) ) && ( currentStatus.RPM > (unsigned int)( (configPage4.dfcoRPM * 10) + configPage4.dfcoHyster) ) && ( currentStatus.TPS < configPage4.dfcoTPSThresh ) )
if ( (currentStatus.TPS < configPage4.dfcoTPSThresh) && (currentStatus.coolant >= (int)(configPage2.dfcoMinCLT - CALIBRATION_TEMPERATURE_OFFSET)) && ( currentStatus.RPM > (unsigned int)( (configPage4.dfcoRPM * 10) + configPage4.dfcoHyster) ) )
{
if ( dfcoStart == 0 ) { dfcoStart = runSecsX10; }
if( (runSecsX10 - dfcoStart) > configPage2.dfcoDelay ) { DFCOValue = true; }
if( dfcoTaper < configPage2.dfcoDelay )
{
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { dfcoTaper++; }
}
else { DFCOValue = true; }
}
else { dfcoStart = 0; } //Prevent future activation right away if previous time wasn't activated
else { dfcoTaper = 0; } //Prevent future activation right away if previous time wasn't activated
} // DFCO active check
} // DFCO enabled check
return DFCOValue;
@ -762,17 +768,21 @@ int8_t correctionIdleAdvance(int8_t advance)
// Limit idle rpm delta between -500rpm - 500rpm
if(idleRPMdelta > 100) { idleRPMdelta = 100; }
if(idleRPMdelta < 0) { idleRPMdelta = 0; }
if( (currentStatus.RPMdiv100 < configPage2.idleAdvRPM) && ((configPage2.vssMode == 0) || (currentStatus.vss < configPage2.idleAdvVss))
if( (currentStatus.RPM < (configPage2.idleAdvRPM * 100)) && ((configPage2.vssMode == 0) || (currentStatus.vss < configPage2.idleAdvVss))
&& (((configPage2.idleAdvAlgorithm == 0) && (currentStatus.TPS < configPage2.idleAdvTPS)) || ((configPage2.idleAdvAlgorithm == 1) && (currentStatus.CTPSActive == 1))) ) // closed throttle position sensor (CTPS) based idle state
{
if( (runSecsX10 - idleAdvStart) >= configPage9.idleAdvStartDelay )
if( idleAdvTaper < configPage9.idleAdvStartDelay )
{
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { idleAdvTaper++; }
}
else
{
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( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { idleAdvStart = runSecsX10; } //Only copy time at runSecsX10 update rate
else { idleAdvTaper = 0; }
}
return ignIdleValue;
}
@ -787,14 +797,16 @@ int8_t correctionSoftRevLimit(int8_t advance)
{
if (currentStatus.RPMdiv100 >= configPage4.SoftRevLim) //Softcut RPM limit
{
if( (runSecsX10 - softStartTime) < configPage4.SoftLimMax )
BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM);
if( softLimitTime < configPage4.SoftLimMax )
{
BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM);
if (configPage2.SoftLimitMode == SOFT_LIMIT_RELATIVE) { ignSoftRevValue = ignSoftRevValue - configPage4.SoftLimRetard; } //delay timing by configured number of degrees in relative mode
else if (configPage2.SoftLimitMode == SOFT_LIMIT_FIXED) { ignSoftRevValue = configPage4.SoftLimRetard; } //delay timing to configured number of degrees in fixed mode
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { softLimitTime++; }
}
}
else if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { softStartTime = runSecsX10; } //Only copy time at runSecsX10 update rate
else if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { softLimitTime = 0; } //Only reset time at runSecsX10 update rate
}
return ignSoftRevValue;

View File

@ -22,7 +22,7 @@ byte checkRevLimit()
if (configPage6.engineProtectType != PROTECT_CUT_OFF)
{
if ( (currentStatus.RPMdiv100 >= configPage4.HardRevLim) || (((runSecsX10 - softStartTime) > configPage4.SoftLimMax) && (currentStatus.RPMdiv100 >= configPage4.SoftRevLim)) )
if ( (currentStatus.RPMdiv100 >= configPage4.HardRevLim) || ((softLimitTime > configPage4.SoftLimMax) && (currentStatus.RPMdiv100 >= configPage4.SoftRevLim)) )
{
BIT_SET(currentStatus.spark, BIT_SPARK_HRDLIM); //Legacy and likely to be removed at some point
BIT_SET(currentStatus.engineProtectStatus, ENGINE_PROTECT_BIT_RPM);

View File

@ -569,7 +569,7 @@ extern int ignition8StartAngle;
extern bool initialisationComplete; //Tracks whether the setup() function has run completely
extern byte fpPrimeTime; //The time (in seconds, based on currentStatus.secl) that the fuel pump started priming
extern uint16_t softStartTime; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started
extern uint8_t softLimitTime; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started
extern volatile uint16_t mainLoopCount;
extern unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
extern volatile unsigned long timer5_overflow_count; //Increments every time counter 5 overflows. Used for the fast version of micros()

View File

@ -125,7 +125,7 @@ int ignition8EndAngle = 0;
//These are variables used across multiple files
bool initialisationComplete = false; ///< Tracks whether the setup() function has run completely (true = has run)
byte fpPrimeTime = 0; ///< The time (in seconds, based on @ref statuses.secl) that the fuel pump started priming
uint16_t softStartTime = 0; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started
uint8_t softLimitTime = 0; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started
volatile uint16_t mainLoopCount; //Main loop counter (incremented at each main loop rev., used for maintaining currentStatus.loopsPerSecond)
unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
volatile unsigned long timer5_overflow_count = 0; //Increments every time counter 5 overflows. Used for the fast version of micros()

View File

@ -63,6 +63,7 @@ long FeedForwardTerm;
unsigned long idle_pwm_target_value;
long idle_cl_target_rpm;
byte idleCounter; //Used for tracking the number of calls to the idle control function
uint8_t idleTaper;
byte idleUpOutputHIGH = HIGH; // Used to invert the idle Up Output
byte idleUpOutputLOW = LOW; // Used to invert the idle Up Output

View File

@ -469,6 +469,7 @@ void idleControl()
{
//Currently cranking. Use the cranking table
currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idleTaper = 0;
}
else if ( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_RUN))
{
@ -476,17 +477,18 @@ void idleControl()
{
//Engine is not running or cranking, but the run before crank flag is set. Use the cranking table
currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idleTaper = 0;
}
}
else
{
if ( runSecsX10 < configPage2.idleTaperTime )
if ( idleTaper < configPage2.idleTaperTime )
{
//Tapering between cranking IAC value and running
currentStatus.idleDuty = map(runSecsX10, 0, configPage2.idleTaperTime,\
currentStatus.idleDuty = map(idleTaper, 0, configPage2.idleTaperTime,\
table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET),\
table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET));
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { idleTaper++; }
}
else
{
@ -619,18 +621,20 @@ void idleControl()
}
doStep();
idleTaper = 0;
}
else
{
//Standard running
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) && (currentStatus.RPM > 0))
{
if ( runSecsX10 < configPage2.idleTaperTime )
if ( idleTaper < configPage2.idleTaperTime )
{
//Tapering between cranking IAC value and running
idleStepper.targetIdleStep = map(runSecsX10, 0, configPage2.idleTaperTime,\
idleStepper.targetIdleStep = map(idleTaper, 0, configPage2.idleTaperTime,\
table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3,\
table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3);
if( BIT_CHECK(LOOP_TIMER, BIT_TIMER_10HZ) ) { idleTaper++; }
}
else
{
@ -685,7 +689,7 @@ void idleControl()
{
currentStatus.CLIdleTarget = (byte)table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
idle_cl_target_rpm = (uint16_t)currentStatus.CLIdleTarget * 10; //Multiply the byte target value back out by 10
if( runSecsX10 < configPage2.idleTaperTime )
if( idleTaper < configPage2.idleTaperTime )
{
uint16_t minValue = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3;
if( idle_pid_target_value < minValue<<2 ) { idle_pid_target_value = minValue<<2; }
@ -693,7 +697,7 @@ void idleControl()
if( configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OLCL ) { maxValue = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; }
//Tapering between cranking IAC value and running
FeedForwardTerm = map(runSecsX10, 0, configPage2.idleTaperTime, minValue, maxValue)<<2;
FeedForwardTerm = map(idleTaper, 0, configPage2.idleTaperTime, minValue, maxValue)<<2;
idle_pid_target_value = FeedForwardTerm;
}
else if (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OLCL)
@ -713,7 +717,7 @@ void idleControl()
//If DFCO conditions are met keep output from changing
if( (currentStatus.TPS > configPage2.iacTPSlimit) || lastDFCOValue
|| ((configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OLCL) && (runSecsX10 < configPage2.idleTaperTime)) )
|| ((configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OLCL) && (idleTaper < configPage2.idleTaperTime)) )
{
idle_pid_target_value = FeedForwardTerm;
}

View File

@ -136,9 +136,9 @@ void setup_DFCO_on()
configPage2.dfcoMinCLT = 40; //Actually 0 with offset
configPage2.dfcoDelay = 10;
runSecsX10 = 1;
dfcoTaper = 1;
correctionDFCO();
runSecsX10 = 20;
dfcoTaper = 20;
}
void test_corrections_dfco_on(void)