Merge branch 'master' of https://github.com/noisymime/speeduino
This commit is contained in:
commit
61b92dd616
|
@ -576,9 +576,9 @@ page = 6
|
||||||
lnchHardLim = scalar, U08, 51, "rpm", 100, 0.0, 100, 25500, 0
|
lnchHardLim = scalar, U08, 51, "rpm", 100, 0.0, 100, 25500, 0
|
||||||
lnchFuelAdd = scalar, U08, 52, "%", 1.0, 0.0, 0.0, 80, 0
|
lnchFuelAdd = scalar, U08, 52, "%", 1.0, 0.0, 0.0, 80, 0
|
||||||
|
|
||||||
idleKP = scalar, U08, 53, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
idleKP = scalar, U08, 53, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
|
||||||
idleKI = scalar, U08, 54, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
idleKI = scalar, U08, 54, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
|
||||||
idleKD = scalar, U08, 55, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
idleKD = scalar, U08, 55, "%", 0.00781, 0.0, 0.0, 1.99, 3 ; * ( 1 byte)
|
||||||
boostLimit = scalar, U08, 56, "kPa", 2.0, 0.0, 0.0, 511.0, 0
|
boostLimit = scalar, U08, 56, "kPa", 2.0, 0.0, 0.0, 511.0, 0
|
||||||
boostKP = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
boostKP = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
||||||
boostKI = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
boostKI = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
||||||
|
@ -1019,9 +1019,9 @@ page = 10
|
||||||
|
|
||||||
;All related to the closed loop VVT control
|
;All related to the closed loop VVT control
|
||||||
vvtCLholdDuty = scalar, U08, 126, "%", 1.0, 0.0, 0.0, 100.0, 0
|
vvtCLholdDuty = scalar, U08, 126, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||||
vvtCLKP = scalar, U08, 127, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
vvtCLKP = scalar, U08, 127, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
|
||||||
vvtCLKI = scalar, U08, 128, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
vvtCLKI = scalar, U08, 128, "%", 0.03125, 0.0, 0.0, 7.96, 2 ; * ( 1 byte)
|
||||||
vvtCLKD = scalar, U08, 129, "%", 1.0, 0.0, 0.0, 200.0, 0 ; * ( 1 byte)
|
vvtCLKD = scalar, U08, 129, "%", 0.00781, 0.0, 0.0, 1.99, 3 ; * ( 1 byte)
|
||||||
vvtCLMinAng = scalar, U16, 130, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
|
vvtCLMinAng = scalar, U16, 130, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
|
||||||
vvtCLMaxAng = scalar, U16, 132, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
|
vvtCLMaxAng = scalar, U16, 132, "deg", 1.0, 0.0, 0.0, 360.0, 0 ; * ( 1 bytes)
|
||||||
|
|
||||||
|
@ -1367,7 +1367,7 @@ menuDialog = main
|
||||||
subMenu = idleSettings, "Idle Control"
|
subMenu = idleSettings, "Idle Control"
|
||||||
subMenu = iacClosedLoop_curve, "Idle - RPM targets", 7, { iacAlgorithm == 3 || iacAlgorithm == 5 || idleAdvEnabled >= 1 }
|
subMenu = iacClosedLoop_curve, "Idle - RPM targets", 7, { iacAlgorithm == 3 || iacAlgorithm == 5 || idleAdvEnabled >= 1 }
|
||||||
subMenu = iacPwm_curve, "Idle - PWM Duty Cycle", 7, { iacAlgorithm == 2 }
|
subMenu = iacPwm_curve, "Idle - PWM Duty Cycle", 7, { iacAlgorithm == 2 }
|
||||||
subMenu = iacPwmCrank_curve, "Idle - PWM Cranking Duty Cycle", 7, { iacAlgorithm == 2 }
|
subMenu = iacPwmCrank_curve, "Idle - PWM Cranking Duty Cycle", 7, { iacAlgorithm == 2 || iacAlgorithm == 3 }
|
||||||
subMenu = iacStep_curve, "Idle - Stepper Motor", 7, { iacAlgorithm == 4 }
|
subMenu = iacStep_curve, "Idle - Stepper Motor", 7, { iacAlgorithm == 4 }
|
||||||
subMenu = iacStepCrank_curve, "Idle - Stepper Motor Cranking", 7, { iacAlgorithm == 4 || iacAlgorithm == 5 }
|
subMenu = iacStepCrank_curve, "Idle - Stepper Motor Cranking", 7, { iacAlgorithm == 4 || iacAlgorithm == 5 }
|
||||||
subMenu = std_separator
|
subMenu = std_separator
|
||||||
|
|
|
@ -110,79 +110,55 @@ uint16_t TS_CommandButtonsHandler(int buttonCommand)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ5_ON: // cmd group is for injector5 on actions
|
case TS_CMD_INJ5_ON: // cmd group is for injector5 on actions
|
||||||
#if INJ_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector5(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector5(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ5_OFF: // cmd group is for injector5 off actions
|
case TS_CMD_INJ5_OFF: // cmd group is for injector5 off actions
|
||||||
#if INJ_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector5(); BIT_CLEAR(HWTest_INJ_50pc, 5); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector5(); BIT_CLEAR(HWTest_INJ_50pc, 5); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ5_50PC: // cmd group is for injector5 50%dc actions
|
case TS_CMD_INJ5_50PC: // cmd group is for injector5 50%dc actions
|
||||||
#if INJ_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 5); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 5); }
|
if(!BIT_CHECK(HWTest_INJ_50pc, 5)) { closeInjector5(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_INJ_50pc, 5)) { closeInjector5(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ6_ON: // cmd group is for injector6 on actions
|
case TS_CMD_INJ6_ON: // cmd group is for injector6 on actions
|
||||||
#if INJ_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector6(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector6(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ6_OFF: // cmd group is for injector6 off actions
|
case TS_CMD_INJ6_OFF: // cmd group is for injector6 off actions
|
||||||
#if INJ_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector6(); BIT_CLEAR(HWTest_INJ_50pc, 6); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector6(); BIT_CLEAR(HWTest_INJ_50pc, 6); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ6_50PC: // cmd group is for injector6 50% dc actions
|
case TS_CMD_INJ6_50PC: // cmd group is for injector6 50% dc actions
|
||||||
#if INJ_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 6); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 6); }
|
if(!BIT_CHECK(HWTest_INJ_50pc, 6)) { closeInjector6(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_INJ_50pc, 6)) { closeInjector6(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ7_ON: // cmd group is for injector7 on actions
|
case TS_CMD_INJ7_ON: // cmd group is for injector7 on actions
|
||||||
#if INJ_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector7(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector7(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ7_OFF: // cmd group is for injector7 off actions
|
case TS_CMD_INJ7_OFF: // cmd group is for injector7 off actions
|
||||||
#if INJ_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector7(); BIT_CLEAR(HWTest_INJ_50pc, 7); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector7(); BIT_CLEAR(HWTest_INJ_50pc, 7); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ7_50PC: // cmd group is for injector7 50%dc actions
|
case TS_CMD_INJ7_50PC: // cmd group is for injector7 50%dc actions
|
||||||
#if INJ_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 7); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 7); }
|
if(!BIT_CHECK(HWTest_INJ_50pc, 7)) { closeInjector7(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_INJ_50pc, 7)) { closeInjector7(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ8_ON: // cmd group is for injector8 on actions
|
case TS_CMD_INJ8_ON: // cmd group is for injector8 on actions
|
||||||
#if INJ_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector8(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ openInjector8(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ8_OFF: // cmd group is for injector8 off actions
|
case TS_CMD_INJ8_OFF: // cmd group is for injector8 off actions
|
||||||
#if INJ_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector8(); BIT_CLEAR(HWTest_INJ_50pc, 8); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ closeInjector8(); BIT_CLEAR(HWTest_INJ_50pc, 8); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_INJ8_50PC: // cmd group is for injector8 50% dc actions
|
case TS_CMD_INJ8_50PC: // cmd group is for injector8 50% dc actions
|
||||||
#if INJ_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 8); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_INJ_50pc, 8); }
|
if(!BIT_CHECK(HWTest_INJ_50pc, 8)) { closeInjector8(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_INJ_50pc, 8)) { closeInjector8(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN1_ON: // cmd group is for spark1 on actions
|
case TS_CMD_IGN1_ON: // cmd group is for spark1 on actions
|
||||||
|
@ -238,79 +214,55 @@ uint16_t TS_CommandButtonsHandler(int buttonCommand)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN5_ON: // cmd group is for spark5 on actions
|
case TS_CMD_IGN5_ON: // cmd group is for spark5 on actions
|
||||||
#if IGN_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil5Charge(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil5Charge(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN5_OFF: // cmd group is for spark5 off actions
|
case TS_CMD_IGN5_OFF: // cmd group is for spark5 off actions
|
||||||
#if IGN_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil5Charge(); BIT_CLEAR(HWTest_IGN_50pc, 5); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil5Charge(); BIT_CLEAR(HWTest_IGN_50pc, 5); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN5_50PC: // cmd group is for spark4 50%dc actions
|
case TS_CMD_IGN5_50PC: // cmd group is for spark4 50%dc actions
|
||||||
#if IGN_CHANNELS >= 5
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 5); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 5); }
|
if(!BIT_CHECK(HWTest_IGN_50pc, 5)) { coil5Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_IGN_50pc, 5)) { coil5Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN6_ON: // cmd group is for spark6 on actions
|
case TS_CMD_IGN6_ON: // cmd group is for spark6 on actions
|
||||||
#if IGN_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil6Charge(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil6Charge(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN6_OFF: // cmd group is for spark6 off actions
|
case TS_CMD_IGN6_OFF: // cmd group is for spark6 off actions
|
||||||
#if IGN_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil6Charge(); BIT_CLEAR(HWTest_IGN_50pc, 6); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil6Charge(); BIT_CLEAR(HWTest_IGN_50pc, 6); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN6_50PC: // cmd group is for spark6 50%dc actions
|
case TS_CMD_IGN6_50PC: // cmd group is for spark6 50%dc actions
|
||||||
#if IGN_CHANNELS >= 6
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 6); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 6); }
|
if(!BIT_CHECK(HWTest_IGN_50pc, 6)) { coil6Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_IGN_50pc, 6)) { coil6Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN7_ON: // cmd group is for spark7 on actions
|
case TS_CMD_IGN7_ON: // cmd group is for spark7 on actions
|
||||||
#if IGN_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil7Charge(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil7Charge(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN7_OFF: // cmd group is for spark7 off actions
|
case TS_CMD_IGN7_OFF: // cmd group is for spark7 off actions
|
||||||
#if IGN_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil7Charge(); BIT_CLEAR(HWTest_IGN_50pc, 7); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil7Charge(); BIT_CLEAR(HWTest_IGN_50pc, 7); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN7_50PC: // cmd group is for spark7 50%dc actions
|
case TS_CMD_IGN7_50PC: // cmd group is for spark7 50%dc actions
|
||||||
#if IGN_CHANNELS >= 7
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 7); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 7); }
|
if(!BIT_CHECK(HWTest_IGN_50pc, 7)) { coil7Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_IGN_50pc, 7)) { coil7Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN8_ON: // cmd group is for spark8 on actions
|
case TS_CMD_IGN8_ON: // cmd group is for spark8 on actions
|
||||||
#if IGN_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil8Charge(); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { beginCoil8Charge(); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN8_OFF: // cmd group is for spark8 off actions
|
case TS_CMD_IGN8_OFF: // cmd group is for spark8 off actions
|
||||||
#if IGN_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil8Charge(); BIT_CLEAR(HWTest_IGN_50pc, 8); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { endCoil8Charge(); BIT_CLEAR(HWTest_IGN_50pc, 8); }
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TS_CMD_IGN8_50PC: // cmd group is for spark8 50%dc actions
|
case TS_CMD_IGN8_50PC: // cmd group is for spark8 50%dc actions
|
||||||
#if IGN_CHANNELS >= 8
|
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 8); }
|
||||||
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { BIT_TOGGLE(HWTest_IGN_50pc, 8); }
|
if(!BIT_CHECK(HWTest_IGN_50pc, 8)) { coil8Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
||||||
if(!BIT_CHECK(HWTest_IGN_50pc, 8)) { coil8Low(); } //Ensure this output is turned off (Otherwise the output may stay on permanently)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//VSS Calibration routines
|
//VSS Calibration routines
|
||||||
|
|
|
@ -87,7 +87,7 @@ void initialiseIdle()
|
||||||
#elif defined(CORE_TEENSY)
|
#elif defined(CORE_TEENSY)
|
||||||
idle_pwm_max_count = 1000000L / (32 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz
|
idle_pwm_max_count = 1000000L / (32 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz
|
||||||
#endif
|
#endif
|
||||||
idlePID.SetOutputLimits(percentage(configPage2.iacCLminDuty, idle_pwm_max_count), percentage(configPage2.iacCLmaxDuty, idle_pwm_max_count));
|
idlePID.SetOutputLimits(percentage(configPage2.iacCLminDuty, idle_pwm_max_count<<2), percentage(configPage2.iacCLmaxDuty, idle_pwm_max_count<<2));
|
||||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ void initialiseIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
idlePID.SetSampleTime(100);
|
idlePID.SetSampleTime(100);
|
||||||
idlePID.SetOutputLimits(0, (configPage9.iacMaxSteps * 3)); //Maximum number of steps; always less than home steps count.
|
idlePID.SetOutputLimits(0, (configPage9.iacMaxSteps * 3)<<2); //Maximum number of steps; always less than home steps count.
|
||||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||||
break;
|
break;
|
||||||
|
@ -247,6 +247,17 @@ void idleControl()
|
||||||
|
|
||||||
case IAC_ALGORITHM_PWM_CL: //Case 3 is PWM closed loop
|
case IAC_ALGORITHM_PWM_CL: //Case 3 is PWM closed loop
|
||||||
//No cranking specific value for closed loop (yet?)
|
//No cranking specific value for closed loop (yet?)
|
||||||
|
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||||
|
{
|
||||||
|
//Currently cranking. Use the cranking table
|
||||||
|
currentStatus.idleDuty = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||||
|
currentStatus.idleLoad = currentStatus.idleDuty;
|
||||||
|
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
|
||||||
|
idle_pid_target_value = idle_pwm_target_value<<2; //Resolution increased
|
||||||
|
idlePID.Initialize(); //Update output to smooth transition
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
currentStatus.CLIdleTarget = (byte)table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
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
|
idle_cl_target_rpm = (uint16_t)currentStatus.CLIdleTarget * 10; //Multiply the byte target value back out by 10
|
||||||
if( (idleCounter & 31) == 1) { idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD); } //This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
if( (idleCounter & 31) == 1) { idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD); } //This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
||||||
|
@ -254,7 +265,7 @@ void idleControl()
|
||||||
PID_computed = idlePID.Compute(true);
|
PID_computed = idlePID.Compute(true);
|
||||||
if(PID_computed == true)
|
if(PID_computed == true)
|
||||||
{
|
{
|
||||||
idle_pwm_target_value = idle_pid_target_value;
|
idle_pwm_target_value = idle_pid_target_value>>2; //increased resolution
|
||||||
if( idle_pwm_target_value == 0 )
|
if( idle_pwm_target_value == 0 )
|
||||||
{
|
{
|
||||||
disableIdle();
|
disableIdle();
|
||||||
|
@ -267,6 +278,7 @@ void idleControl()
|
||||||
|
|
||||||
}
|
}
|
||||||
idleCounter++;
|
idleCounter++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IAC_ALGORITHM_STEP_OL: //Case 4 is open loop stepper control
|
case IAC_ALGORITHM_STEP_OL: //Case 4 is open loop stepper control
|
||||||
|
@ -291,9 +303,9 @@ void idleControl()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Standard running
|
//Standard running
|
||||||
//Only do a lookup of the required value around 4 times per second (Once every 255 mainloops). Any more than this can create too much jitter and require a hyster value that is too high
|
//Only do a lookup of the required value around 4 times per second. Any more than this can create too much jitter and require a hyster value that is too high
|
||||||
//We must also have more than zero RPM for the running state
|
//We must also have more than zero RPM for the running state
|
||||||
if (((mainLoopCount & 255) == 1) && (currentStatus.RPM > 0))
|
if (BIT_CHECK(LOOP_TIMER, BIT_TIMER_4HZ) && (currentStatus.RPM > 0))
|
||||||
{
|
{
|
||||||
idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here
|
idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here
|
||||||
if(currentStatus.idleUpActive == true) { idleStepper.targetIdleStep += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
if(currentStatus.idleUpActive == true) { idleStepper.targetIdleStep += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||||
|
@ -319,7 +331,7 @@ void idleControl()
|
||||||
//First thing to check is whether there is currently a step going on and if so, whether it needs to be turned off
|
//First thing to check is whether there is currently a step going on and if so, whether it needs to be turned off
|
||||||
if( (checkForStepping() == false) && (isStepperHomed() == true) ) //Check that homing is complete and that there's not currently a step already taking place. MUST BE IN THIS ORDER!
|
if( (checkForStepping() == false) && (isStepperHomed() == true) ) //Check that homing is complete and that there's not currently a step already taking place. MUST BE IN THIS ORDER!
|
||||||
{
|
{
|
||||||
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK )/* ||currentStatus.rpmDOT>=500||currentStatus.rpmDOT<=-500*/)
|
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||||
{
|
{
|
||||||
//Currently cranking. Use the cranking table
|
//Currently cranking. Use the cranking table
|
||||||
idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here
|
idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)) * 3; //All temps are offset by 40 degrees. Step counts are divided by 3 in TS. Multiply back out here
|
||||||
|
@ -332,36 +344,35 @@ void idleControl()
|
||||||
}
|
}
|
||||||
|
|
||||||
doStep();
|
doStep();
|
||||||
|
idle_pid_target_value = idleStepper.targetIdleStep<<2; //Resolution increased
|
||||||
|
idlePID.Initialize(); //Update output to smooth transition
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( (idleCounter & 31) == 1)
|
if( (idleCounter & 31) == 1)
|
||||||
{
|
{
|
||||||
//This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
//This only needs to be run very infrequently, once every 32 calls to idleControl(). This is approx. once per second
|
||||||
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
idlePID.SetTunings(configPage6.idleKP, configPage6.idleKI, configPage6.idleKD);
|
||||||
iacStepTime_uS = configPage6.iacStepTime * 1000;
|
iacStepTime_uS = configPage6.iacStepTime * 1000;
|
||||||
iacCoolTime_uS = configPage9.iacCoolTime * 1000;
|
iacCoolTime_uS = configPage9.iacCoolTime * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
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; //All temps are offset by 40 degrees
|
||||||
|
PID_computed = idlePID.Compute(true);
|
||||||
|
idleStepper.targetIdleStep = idle_pid_target_value>>2; //Increase resolution
|
||||||
|
if(currentStatus.idleUpActive == true) { idleStepper.targetIdleStep += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||||
|
|
||||||
|
//limit to the configured max steps. This must include any idle up adder, to prevent over-opening.
|
||||||
|
if (idleStepper.targetIdleStep > (configPage9.iacMaxSteps * 3) )
|
||||||
|
{
|
||||||
|
idleStepper.targetIdleStep = configPage9.iacMaxSteps * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
doStep();
|
||||||
|
idleCounter++;
|
||||||
}
|
}
|
||||||
|
currentStatus.idleLoad = idleStepper.curIdleStep / 2; //Current step count (Divided by 2 for byte)
|
||||||
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; //All temps are offset by 40 degrees
|
|
||||||
if(currentStatus.idleUpActive == true) { idle_pid_target_value += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
|
||||||
PID_computed = idlePID.Compute(true);
|
|
||||||
idleStepper.targetIdleStep = idle_pid_target_value;
|
|
||||||
|
|
||||||
//limit to the configured max steps. This must include any idle up adder, to prevent over-opening.
|
|
||||||
if (idleStepper.targetIdleStep > (configPage9.iacMaxSteps * 3) )
|
|
||||||
{
|
|
||||||
idleStepper.targetIdleStep = configPage9.iacMaxSteps * 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
doStep();
|
|
||||||
|
|
||||||
idleCounter++;
|
|
||||||
}
|
|
||||||
currentStatus.idleLoad = idleStepper.curIdleStep / 2; //Current step count (Divided by 2 for byte)
|
|
||||||
}
|
}
|
||||||
//Set or clear the idle active flag
|
//Set or clear the idle active flag
|
||||||
if(idleStepper.targetIdleStep != idleStepper.curIdleStep) { BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); }
|
if(idleStepper.targetIdleStep != idleStepper.curIdleStep) { BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); }
|
||||||
|
|
|
@ -213,13 +213,12 @@ integerPID::integerPID(long* Input, long* Output, long* Setpoint,
|
||||||
byte Kp, byte Ki, byte Kd, byte ControllerDirection)
|
byte Kp, byte Ki, byte Kd, byte ControllerDirection)
|
||||||
{
|
{
|
||||||
|
|
||||||
myOutput = Output;
|
myOutput = Output;
|
||||||
myInput = Input;
|
myInput = Input;
|
||||||
mySetpoint = Setpoint;
|
mySetpoint = Setpoint;
|
||||||
inAuto = false;
|
inAuto = false;
|
||||||
|
|
||||||
integerPID::SetOutputLimits(0, 255); //default output limit corresponds to
|
integerPID::SetOutputLimits(0, 255); //default output limit corresponds to the arduino pwm limits
|
||||||
//the arduino pwm limits
|
|
||||||
|
|
||||||
SampleTime = 250; //default Controller Sample Time is 0.25 seconds. This is the 4Hz control time for Idle and VVT
|
SampleTime = 250; //default Controller Sample Time is 0.25 seconds. This is the 4Hz control time for Idle and VVT
|
||||||
|
|
||||||
|
@ -240,45 +239,57 @@ bool integerPID::Compute(bool pOnE)
|
||||||
{
|
{
|
||||||
if(!inAuto) return false;
|
if(!inAuto) return false;
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
//SampleTime = (now - lastTime);
|
|
||||||
unsigned long timeChange = (now - lastTime);
|
unsigned long timeChange = (now - lastTime);
|
||||||
if(timeChange >= SampleTime)
|
if(timeChange >= SampleTime)
|
||||||
{
|
{
|
||||||
/*Compute all the working error variables*/
|
/*Compute all the working error variables*/
|
||||||
long input = *myInput;
|
long input = *myInput;
|
||||||
long error = *mySetpoint - input;
|
if(input > 0) //Fail safe, should never be 0
|
||||||
long dInput = (input - lastInput);
|
|
||||||
|
|
||||||
outputSum += (ki * error)/1024; //Note that ki is multiplied by 1024 so it must be divided by 1024 here
|
|
||||||
if(outputSum > outMax) { outputSum = outMax; }
|
|
||||||
else if(outputSum < outMin) { outputSum = outMin; }
|
|
||||||
|
|
||||||
/*Compute PID Output*/
|
|
||||||
long output;
|
|
||||||
|
|
||||||
if(pOnE)
|
|
||||||
{
|
{
|
||||||
output = (kp * error) + outputSum - ((kd * dInput)/128);
|
long error = *mySetpoint - input;
|
||||||
|
long dInput = (input - lastInput);
|
||||||
|
long outMinResized = outMin<<PID_SHIFTS;
|
||||||
|
long outMaxResized = outMax<<PID_SHIFTS;
|
||||||
|
|
||||||
|
if (ki != 0)
|
||||||
|
{
|
||||||
|
outputSum += (ki * error); //integral += error × dt
|
||||||
|
if(outputSum > outMaxResized) { outputSum = outMaxResized; }
|
||||||
|
else if(outputSum < outMinResized) { outputSum = outMinResized; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Compute PID Output*/
|
||||||
|
long output;
|
||||||
|
|
||||||
|
if(pOnE)
|
||||||
|
{
|
||||||
|
output = (kp * error);
|
||||||
|
if (ki != 0) { output += outputSum; }
|
||||||
|
if (kd != 0) { output -= (kd * dInput)>>2; }
|
||||||
|
output >>= PID_SHIFTS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outputSum -= (kp * dInput);
|
||||||
|
if(outputSum > outMaxResized) { outputSum = outMaxResized; }
|
||||||
|
else if(outputSum < outMinResized) { outputSum = outMinResized; }
|
||||||
|
|
||||||
|
output = outputSum;
|
||||||
|
if (kd != 0) { output -= (kd * dInput)>>2; }
|
||||||
|
output >>= PID_SHIFTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(output > outMax) output = outMax;
|
||||||
|
else if(output < outMin) output = outMin;
|
||||||
|
*myOutput = output;
|
||||||
|
|
||||||
|
/*Remember some variables for next time*/
|
||||||
|
lastInput = input;
|
||||||
|
lastTime = now;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
outputSum -= kp * dInput;
|
|
||||||
if(outputSum > outMax) { outputSum = outMax; }
|
|
||||||
else if(outputSum < outMin) { outputSum = outMin; }
|
|
||||||
|
|
||||||
output = outputSum - ((kd * dInput)/128);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(output > outMax) output = outMax;
|
|
||||||
else if(output < outMin) output = outMin;
|
|
||||||
*myOutput = output;
|
|
||||||
|
|
||||||
/*Remember some variables for next time*/
|
|
||||||
lastInput = input;
|
|
||||||
lastTime = now;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
@ -364,9 +375,10 @@ void integerPID::SetTunings(byte Kp, byte Ki, byte Kd)
|
||||||
kd = Kd / SampleTimeInSec;
|
kd = Kd / SampleTimeInSec;
|
||||||
*/
|
*/
|
||||||
long InverseSampleTimeInSec = 1000 / SampleTime;
|
long InverseSampleTimeInSec = 1000 / SampleTime;
|
||||||
kp = Kp;
|
//New resolution, 2 shifts to improve ki here | kp 1.563% | ki 1.563% | kd 0.195%
|
||||||
ki = (long)((long)Ki * 1024) / InverseSampleTimeInSec;
|
kp = (uint16_t)Kp<<2;
|
||||||
kd = ((long)Kd * InverseSampleTimeInSec);
|
ki = (long)(Ki<<2) / InverseSampleTimeInSec;
|
||||||
|
kd = (long)(Kd<<2) * InverseSampleTimeInSec;
|
||||||
|
|
||||||
if(controllerDirection == REVERSE)
|
if(controllerDirection == REVERSE)
|
||||||
{
|
{
|
||||||
|
@ -409,8 +421,8 @@ void integerPID::SetOutputLimits(long Min, long Max)
|
||||||
if(*myOutput > outMax) *myOutput = outMax;
|
if(*myOutput > outMax) *myOutput = outMax;
|
||||||
else if(*myOutput < outMin) *myOutput = outMin;
|
else if(*myOutput < outMin) *myOutput = outMin;
|
||||||
|
|
||||||
if(outputSum > outMax) { outputSum = outMax; }
|
if((outputSum>>PID_SHIFTS) > outMax) { outputSum = outMax<<PID_SHIFTS; }
|
||||||
else if(outputSum < outMin) { outputSum = outMin; }
|
else if((outputSum>>PID_SHIFTS) < outMin) { outputSum = outMin<<PID_SHIFTS; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,11 +447,11 @@ void integerPID::SetMode(int Mode)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void integerPID::Initialize()
|
void integerPID::Initialize()
|
||||||
{
|
{
|
||||||
outputSum = *myOutput;
|
outputSum = *myOutput<<PID_SHIFTS;
|
||||||
lastInput = *myInput;
|
lastInput = *myInput;
|
||||||
lastMinusOneInput = *myInput;
|
lastMinusOneInput = *myInput;
|
||||||
if(outputSum > outMax) { outputSum = outMax; }
|
if((outputSum>>PID_SHIFTS) > outMax) { outputSum = outMax<<PID_SHIFTS; }
|
||||||
else if(outputSum < outMin) { outputSum = outMin; }
|
else if((outputSum>>PID_SHIFTS) < outMin) { outputSum = outMin<<PID_SHIFTS; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SetControllerDirection(...)*************************************************
|
/* SetControllerDirection(...)*************************************************
|
||||||
|
|
|
@ -88,6 +88,7 @@ class integerPID
|
||||||
#define MANUAL 0
|
#define MANUAL 0
|
||||||
#define DIRECT 0
|
#define DIRECT 0
|
||||||
#define REVERSE 1
|
#define REVERSE 1
|
||||||
|
#define PID_SHIFTS 7 //Increased resolution
|
||||||
|
|
||||||
//commonly used functions **************************************************************************
|
//commonly used functions **************************************************************************
|
||||||
integerPID(long*, long*, long*, // * constructor. links the PID to the Input, Output, and
|
integerPID(long*, long*, long*, // * constructor. links the PID to the Input, Output, and
|
||||||
|
|
|
@ -335,6 +335,14 @@ void doUpdates()
|
||||||
configPage2.aeColdTaperMin = 40;
|
configPage2.aeColdTaperMin = 40;
|
||||||
configPage2.aeColdTaperMax = 100;
|
configPage2.aeColdTaperMax = 100;
|
||||||
|
|
||||||
|
//New PID resolution, old resolution was 100% for each increase, 100% now is stored as 32
|
||||||
|
configPage6.idleKP = configPage6.idleKP<<5;
|
||||||
|
configPage6.idleKI = configPage6.idleKI<<5;
|
||||||
|
configPage6.idleKD = configPage6.idleKD<<5;
|
||||||
|
configPage10.vvtCLKP = configPage10.vvtCLKP<<5;
|
||||||
|
configPage10.vvtCLKI = configPage10.vvtCLKI<<5;
|
||||||
|
configPage10.vvtCLKD = configPage10.vvtCLKD<<5;
|
||||||
|
|
||||||
//Cranking enrichment to run taper added. Default it to 0,1 secs
|
//Cranking enrichment to run taper added. Default it to 0,1 secs
|
||||||
configPage10.crankingEnrichTaper = 1;
|
configPage10.crankingEnrichTaper = 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue