mirror of https://github.com/rusefi/speeduino.git
Allow min and max duty cycles for closed loop idle and boost
This commit is contained in:
parent
a881ddc405
commit
0d055dc7f1
|
@ -199,24 +199,27 @@ page = 2
|
||||||
dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0
|
dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||||
flexFreqLow = scalar, U08, 41, "Hz", 1.0, 0.0, 0.0, 250.0, 0
|
flexFreqLow = scalar, U08, 41, "Hz", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
flexFreqHigh = scalar, U08, 42, "Hz", 1.0, 0.0, 0.0, 250.0, 0
|
flexFreqHigh = scalar, U08, 42, "Hz", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
taeColdM = scalar, U08, 43, "%", 1.0, 0.0, 0.0, 250.0, 0
|
|
||||||
tpsMin = scalar, U08, 44, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
tpsMin = scalar, U08, 43, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
||||||
tpsMax = scalar, U08, 45, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
tpsMax = scalar, U08, 44, "ADC", 1.0, 0.0, 0.0, 255.0, 0
|
||||||
mapMin = scalar, U08, 46, "kpa", 1.0, 0.0, 0.0, 255.0, 0
|
mapMin = scalar, U08, 45, "kpa", 1.0, 0.0, 0.0, 255.0, 0
|
||||||
mapMax = scalar, U16, 47, "kpa", 1.0, 0.0, 0.0, 25500, 0
|
mapMax = scalar, U16, 46, "kpa", 1.0, 0.0, 0.0, 25500, 0
|
||||||
fpPrime = scalar, U08, 49, "s", 1.0, 0.0, 0.0, 255.0, 0
|
fpPrime = scalar, U08, 48, "s", 1.0, 0.0, 0.0, 255.0, 0
|
||||||
stoich = scalar, U08, 50, ":1", 0.1, 0.0, 0.0, 25.5, 1
|
stoich = scalar, U08, 49, ":1", 0.1, 0.0, 0.0, 25.5, 1
|
||||||
oddfire2 = scalar, U16, 51, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
oddfire2 = scalar, U16, 50, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
||||||
oddfire3 = scalar, U16, 53, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
oddfire3 = scalar, U16, 52, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
||||||
oddfire4 = scalar, U16, 55, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
oddfire4 = scalar, U16, 54, "deg", 1.0, 0.0, 0.0, 720, 0 ; * ( 2 byte)
|
||||||
|
|
||||||
flexFuelLow = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0
|
flexFuelLow = scalar, U08, 56, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
flexFuelHigh = scalar, U08, 58, "%", 1.0, 0.0, 0.0, 250.0, 0
|
flexFuelHigh = scalar, U08, 57, "%", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
flexAdvLow = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
flexAdvLow = scalar, U08, 58, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
flexAdvHigh = scalar, U08, 60, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
flexAdvHigh = scalar, U08, 59, "Deg", 1.0, 0.0, 0.0, 250.0, 0
|
||||||
unused2-61 = scalar, U08, 61, "RPM", 100.0, 0.0, 100, 25500, 0
|
|
||||||
unused2-62 = scalar, U08, 62, "RPM", 100.0, 0.0, 100, 25500, 0
|
iacCLminDuty = scalar, U08, 60, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles when using closed loop idle
|
||||||
unused2-63 = scalar, U08, 63, "RPM", 100.0, 0.0, 100, 25500, 0
|
iacCLmaxDuty = scalar, U08, 61, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||||
|
boostMinDuty = scalar, U08, 62, "%", 1.0, 0.0, 0.0, 100.0, 0 ; Minimum and maximum duty cycles for boost control
|
||||||
|
boostMaxDuty = scalar, U08, 63, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||||
|
|
||||||
|
|
||||||
;--------------------------------------------------
|
;--------------------------------------------------
|
||||||
;Start Ignition table (Page 3)
|
;Start Ignition table (Page 3)
|
||||||
|
@ -671,6 +674,10 @@ page = 10
|
||||||
requiresPowerCycle = oddfire2
|
requiresPowerCycle = oddfire2
|
||||||
requiresPowerCycle = oddfire3
|
requiresPowerCycle = oddfire3
|
||||||
requiresPowerCycle = oddfire4
|
requiresPowerCycle = oddfire4
|
||||||
|
requiresPowerCycle = iacCLminDuty
|
||||||
|
requiresPowerCycle = iacCLmaxDuty
|
||||||
|
requiresPowerCycle = boostMinDuty
|
||||||
|
requiresPowerCycle = boostMaxDuty
|
||||||
|
|
||||||
defaultValue = pinLayout, 1
|
defaultValue = pinLayout, 1
|
||||||
defaultValue = TrigPattern, 0
|
defaultValue = TrigPattern, 0
|
||||||
|
@ -702,6 +709,10 @@ page = 10
|
||||||
defaultValue = flexAdvHigh, 13
|
defaultValue = flexAdvHigh, 13
|
||||||
defaultValue = fuelPumpPin, 0
|
defaultValue = fuelPumpPin, 0
|
||||||
defaultValue = fanPin, 0
|
defaultValue = fanPin, 0
|
||||||
|
defaultValue = iacCLminDuty, 0
|
||||||
|
defaultValue = iacCLmaxDuty, 100
|
||||||
|
defaultValue = boostMinDuty, 0
|
||||||
|
defaultValue = boostMaxDuty, 100
|
||||||
|
|
||||||
|
|
||||||
[Menu]
|
[Menu]
|
||||||
|
@ -847,13 +858,14 @@ menuDialog = main
|
||||||
iacStepTime = "Time between each stepper motor step.\nIncrease this if the motor appears to behave intermittently."
|
iacStepTime = "Time between each stepper motor step.\nIncrease this if the motor appears to behave intermittently."
|
||||||
iacStepHome = "On startup the stepper motor moves this many steps to return to its home position. Set this value to a few more than the actual number to ensure the motor has returned to its full position."
|
iacStepHome = "On startup the stepper motor moves this many steps to return to its home position. Set this value to a few more than the actual number to ensure the motor has returned to its full position."
|
||||||
iacStepHyster = "The minimum number of steps to move in any one go."
|
iacStepHyster = "The minimum number of steps to move in any one go."
|
||||||
|
|
||||||
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)"
|
|
||||||
oddfire4 = "The ATDC angle of channel 4 for oddfire engines. This is relative to the TDC angle of channel 1 (NOT channel 3)"
|
|
||||||
|
|
||||||
iacAlgorithm = "Selects method of idle control.\nNone = no idle control valve.\nOn/Off valve.\nPWM valve (2,3 wire).\nStepper Valve (4,6,8 wire)."
|
iacAlgorithm = "Selects method of idle control.\nNone = no idle control valve.\nOn/Off valve.\nPWM valve (2,3 wire).\nStepper Valve (4,6,8 wire)."
|
||||||
iacPWMdir = "Normal PWM valves increase RPM with higher duty. If RPM decreases with higher duty then select Reverse"
|
iacPWMdir = "Normal PWM valves increase RPM with higher duty. If RPM decreases with higher duty then select Reverse"
|
||||||
|
iacCLminDuty= "When using closed loop idle control, this is the minimum duty cycle that the PID loop will allow. Combined with the maximum value, this specifies the working range of your idle valve
|
||||||
|
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
|
||||||
|
|
||||||
|
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)"
|
||||||
|
oddfire4 = "The ATDC angle of channel 4 for oddfire engines. This is relative to the TDC angle of channel 1 (NOT channel 3)"
|
||||||
|
|
||||||
dfcoRPM = "The RPM above which DFCO will be active. Typically set a few hundred RPM above maximum idle speed"
|
dfcoRPM = "The RPM above which DFCO will be active. Typically set a few hundred RPM above maximum idle speed"
|
||||||
dfcoHyster = "Hysteresis for DFCO RPM. 200-300 RPM is typical for this, however a higher value may be needed if the RPM is fluctuating around the cutout speed"
|
dfcoHyster = "Hysteresis for DFCO RPM. 200-300 RPM is typical for this, however a higher value may be needed if the RPM is fluctuating around the cutout speed"
|
||||||
|
@ -1071,6 +1083,8 @@ menuDialog = main
|
||||||
field = "P", idleKP, { iacAlgorithm == 3 }
|
field = "P", idleKP, { iacAlgorithm == 3 }
|
||||||
field = "I", idleKI, { iacAlgorithm == 3 }
|
field = "I", idleKI, { iacAlgorithm == 3 }
|
||||||
field = "D", idleKD, { iacAlgorithm == 3 }
|
field = "D", idleKD, { iacAlgorithm == 3 }
|
||||||
|
field = "Minimum valve duty", iacCLminDuty, { iacAlgorithm == 3 }
|
||||||
|
field = "Maximum valve duty", iacCLmaxDuty, { iacAlgorithm == 3 }
|
||||||
|
|
||||||
dialog = idleSettings, "Idle Settings"
|
dialog = idleSettings, "Idle Settings"
|
||||||
topicHelp = "http://speeduino.com/wiki/index.php/Idle"
|
topicHelp = "http://speeduino.com/wiki/index.php/Idle"
|
||||||
|
@ -1215,6 +1229,8 @@ menuDialog = main
|
||||||
field = "P", boostKP, { boostEnabled }
|
field = "P", boostKP, { boostEnabled }
|
||||||
field = "I", boostKI, { boostEnabled }
|
field = "I", boostKI, { boostEnabled }
|
||||||
field = "D", boostKD, { boostEnabled }
|
field = "D", boostKD, { boostEnabled }
|
||||||
|
field = "Valve minimum duty cycle", boostMinDuty, { boostEnabled }
|
||||||
|
field = "Valve maximum duty cycle", boostMaxDuty, { boostEnabled }
|
||||||
|
|
||||||
dialog = vvtSettings, "VVT Control"
|
dialog = vvtSettings, "VVT Control"
|
||||||
field = "VVT Control Enabled", vvtEnabled
|
field = "VVT Control Enabled", vvtEnabled
|
||||||
|
|
|
@ -48,7 +48,7 @@ void initialiseAuxPWM()
|
||||||
//TIMSK1 |= (1 << OCIE1A); //Turn on the A compare unit (ie turn on the interrupt) //Shouldn't be needed with closed loop as its turned on below
|
//TIMSK1 |= (1 << OCIE1A); //Turn on the A compare unit (ie turn on the interrupt) //Shouldn't be needed with closed loop as its turned on below
|
||||||
TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt)
|
TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt)
|
||||||
|
|
||||||
boostPID.SetOutputLimits(0, boost_pwm_max_count);
|
boostPID.SetOutputLimits(percentage(configPage1.boostMinDuty, boost_pwm_max_count) , percentage(configPage1.boostMaxDuty, boost_pwm_max_count));
|
||||||
boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD);
|
boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD);
|
||||||
boostPID.SetMode(AUTOMATIC); //Turn PID on
|
boostPID.SetMode(AUTOMATIC); //Turn PID on
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,6 @@ struct config1 {
|
||||||
byte dutyLim;
|
byte dutyLim;
|
||||||
byte flexFreqLow; //Lowest valid frequency reading from the flex sensor
|
byte flexFreqLow; //Lowest valid frequency reading from the flex sensor
|
||||||
byte flexFreqHigh; //Highest valid frequency reading from the flex sensor
|
byte flexFreqHigh; //Highest valid frequency reading from the flex sensor
|
||||||
byte taeColdM;
|
|
||||||
byte tpsMin;
|
byte tpsMin;
|
||||||
byte tpsMax;
|
byte tpsMax;
|
||||||
byte mapMin;
|
byte mapMin;
|
||||||
|
@ -293,9 +292,11 @@ struct config1 {
|
||||||
byte flexFuelHigh; //Fuel % to be used for the highest ethanol reading (Typically 163%)
|
byte flexFuelHigh; //Fuel % to be used for the highest ethanol reading (Typically 163%)
|
||||||
byte flexAdvLow; //Additional advance (in degrees) at lowest ethanol reading (Typically 0)
|
byte flexAdvLow; //Additional advance (in degrees) at lowest ethanol reading (Typically 0)
|
||||||
byte flexAdvHigh; //Additional advance (in degrees) at highest ethanol reading (Varies, usually 10-20)
|
byte flexAdvHigh; //Additional advance (in degrees) at highest ethanol reading (Varies, usually 10-20)
|
||||||
byte unused61;
|
|
||||||
byte unused62;
|
byte iacCLminDuty;
|
||||||
byte unused63;
|
byte iacCLmaxDuty;
|
||||||
|
byte boostMinDuty;
|
||||||
|
byte boostMaxDuty;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,18 @@ integerPID idlePID(¤tStatus.longRPM, &idle_pwm_target_value, &idle_cl_targ
|
||||||
|
|
||||||
void initialiseIdle()
|
void initialiseIdle()
|
||||||
{
|
{
|
||||||
//By default, turn off the PWM interrupt (It gets turned on below if needed)
|
//By default, turn off the PWM interrupt (It gets turned on below if needed)
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
TIMSK4 &= ~(1 << OCIE4C); // Disable timer channel for idle
|
TIMSK4 &= ~(1 << OCIE4C); // Disable timer channel for idle
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Initialising comprises of setting the 2D tables with the relevant values from the config pages
|
//Initialising comprises of setting the 2D tables with the relevant values from the config pages
|
||||||
switch(configPage4.iacAlgorithm)
|
switch(configPage4.iacAlgorithm)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
//Case 0 is no idle control ('None')
|
//Case 0 is no idle control ('None')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
//Case 1 is on/off idle control
|
//Case 1 is on/off idle control
|
||||||
if (currentStatus.coolant < configPage4.iacFastTemp)
|
if (currentStatus.coolant < configPage4.iacFastTemp)
|
||||||
|
@ -36,34 +36,14 @@ void initialiseIdle()
|
||||||
digitalWrite(pinIdle1, HIGH);
|
digitalWrite(pinIdle1, HIGH);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
//Case 2 is PWM open loop
|
//Case 2 is PWM open loop
|
||||||
iacPWMTable.xSize = 10;
|
iacPWMTable.xSize = 10;
|
||||||
iacPWMTable.valueSize = SIZE_BYTE;
|
iacPWMTable.valueSize = SIZE_BYTE;
|
||||||
iacPWMTable.values = configPage4.iacOLPWMVal;
|
iacPWMTable.values = configPage4.iacOLPWMVal;
|
||||||
iacPWMTable.axisX = configPage4.iacBins;
|
iacPWMTable.axisX = configPage4.iacBins;
|
||||||
|
|
||||||
iacCrankDutyTable.xSize = 4;
|
|
||||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
|
||||||
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
|
||||||
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
|
||||||
|
|
||||||
idle_pin_port = portOutputRegister(digitalPinToPort(pinIdle1));
|
|
||||||
idle_pin_mask = digitalPinToBitMask(pinIdle1);
|
|
||||||
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
|
||||||
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
|
||||||
idle_pwm_max_count = 1000000L / (16 * configPage3.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
|
|
||||||
enableIdle();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
//Case 3 is PWM closed loop
|
|
||||||
iacClosedLoopTable.xSize = 10;
|
|
||||||
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
|
||||||
iacClosedLoopTable.values = configPage4.iacCLValues;
|
|
||||||
iacClosedLoopTable.axisX = configPage4.iacBins;
|
|
||||||
|
|
||||||
iacCrankDutyTable.xSize = 4;
|
iacCrankDutyTable.xSize = 4;
|
||||||
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||||
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
||||||
|
@ -74,39 +54,59 @@ void initialiseIdle()
|
||||||
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
||||||
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
||||||
idle_pwm_max_count = 1000000L / (16 * configPage3.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 / (16 * configPage3.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
|
||||||
idlePID.SetOutputLimits(0, idle_pwm_max_count);
|
enableIdle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
//Case 3 is PWM closed loop
|
||||||
|
iacClosedLoopTable.xSize = 10;
|
||||||
|
iacClosedLoopTable.valueSize = SIZE_BYTE;
|
||||||
|
iacClosedLoopTable.values = configPage4.iacCLValues;
|
||||||
|
iacClosedLoopTable.axisX = configPage4.iacBins;
|
||||||
|
|
||||||
|
iacCrankDutyTable.xSize = 4;
|
||||||
|
iacCrankDutyTable.valueSize = SIZE_BYTE;
|
||||||
|
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
||||||
|
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
||||||
|
|
||||||
|
idle_pin_port = portOutputRegister(digitalPinToPort(pinIdle1));
|
||||||
|
idle_pin_mask = digitalPinToBitMask(pinIdle1);
|
||||||
|
idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2));
|
||||||
|
idle2_pin_mask = digitalPinToBitMask(pinIdle2);
|
||||||
|
idle_pwm_max_count = 1000000L / (16 * configPage3.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
|
||||||
|
idlePID.SetOutputLimits(percentage(configPage1.iacCLminDuty, idle_pwm_max_count), percentage(configPage1.iacCLmaxDuty, idle_pwm_max_count));
|
||||||
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
idlePID.SetTunings(configPage3.idleKP, configPage3.idleKI, configPage3.idleKD);
|
||||||
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
idlePID.SetMode(AUTOMATIC); //Turn PID on
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
//Case 2 is Stepper open loop
|
//Case 2 is Stepper open loop
|
||||||
iacStepTable.xSize = 10;
|
iacStepTable.xSize = 10;
|
||||||
iacStepTable.valueSize = SIZE_BYTE;
|
iacStepTable.valueSize = SIZE_BYTE;
|
||||||
iacStepTable.values = configPage4.iacOLStepVal;
|
iacStepTable.values = configPage4.iacOLStepVal;
|
||||||
iacStepTable.axisX = configPage4.iacBins;
|
iacStepTable.axisX = configPage4.iacBins;
|
||||||
|
|
||||||
iacCrankStepsTable.xSize = 4;
|
iacCrankStepsTable.xSize = 4;
|
||||||
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
||||||
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
||||||
iacStepTime = configPage4.iacStepTime * 1000;
|
iacStepTime = configPage4.iacStepTime * 1000;
|
||||||
|
|
||||||
//homeStepper(); //Returns the stepper to the 'home' position
|
//homeStepper(); //Returns the stepper to the 'home' position
|
||||||
completedHomeSteps = 0;
|
completedHomeSteps = 0;
|
||||||
idleStepper.stepperStatus = SOFF;
|
idleStepper.stepperStatus = SOFF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
//Case 5 is Stepper closed loop
|
//Case 5 is Stepper closed loop
|
||||||
iacClosedLoopTable.xSize = 10;
|
iacClosedLoopTable.xSize = 10;
|
||||||
iacClosedLoopTable.values = configPage4.iacCLValues;
|
iacClosedLoopTable.values = configPage4.iacCLValues;
|
||||||
iacClosedLoopTable.axisX = configPage4.iacBins;
|
iacClosedLoopTable.axisX = configPage4.iacBins;
|
||||||
|
|
||||||
iacCrankStepsTable.xSize = 4;
|
iacCrankStepsTable.xSize = 4;
|
||||||
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
||||||
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
||||||
iacStepTime = configPage4.iacStepTime * 1000;
|
iacStepTime = configPage4.iacStepTime * 1000;
|
||||||
|
|
||||||
homeStepper(); //Returns the stepper to the 'home' position
|
homeStepper(); //Returns the stepper to the 'home' position
|
||||||
idleStepper.stepperStatus = SOFF;
|
idleStepper.stepperStatus = SOFF;
|
||||||
break;
|
break;
|
||||||
|
@ -117,12 +117,12 @@ void initialiseIdle()
|
||||||
void idleControl()
|
void idleControl()
|
||||||
{
|
{
|
||||||
if(idleInitComplete != configPage4.iacAlgorithm) { initialiseIdle(); }
|
if(idleInitComplete != configPage4.iacAlgorithm) { initialiseIdle(); }
|
||||||
|
|
||||||
switch(configPage4.iacAlgorithm)
|
switch(configPage4.iacAlgorithm)
|
||||||
{
|
{
|
||||||
case 0: //Case 0 is no idle control ('None')
|
case 0: //Case 0 is no idle control ('None')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: //Case 1 is on/off idle control
|
case 1: //Case 1 is on/off idle control
|
||||||
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees
|
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,7 @@ void idleControl()
|
||||||
}
|
}
|
||||||
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
|
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: //Case 2 is PWM open loop
|
case 2: //Case 2 is PWM open loop
|
||||||
//Check for cranking pulsewidth
|
//Check for cranking pulsewidth
|
||||||
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
||||||
|
@ -151,7 +151,7 @@ void idleControl()
|
||||||
idleOn = true;
|
idleOn = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: //Case 3 is PWM closed loop
|
case 3: //Case 3 is PWM closed loop
|
||||||
//No cranking specific value for closed loop (yet?)
|
//No cranking specific value for closed loop (yet?)
|
||||||
idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees
|
idle_cl_target_rpm = table2D_getValue(&iacClosedLoopTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) * 10; //All temps are offset by 40 degrees
|
||||||
|
@ -162,7 +162,7 @@ void idleControl()
|
||||||
else{ enableIdle(); } //Turn on the C compare unit (ie turn on the interrupt)
|
else{ enableIdle(); } //Turn on the C compare unit (ie turn on the interrupt)
|
||||||
//idle_pwm_target_value = 104;
|
//idle_pwm_target_value = 104;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: //Case 4 is open loop stepper control
|
case 4: //Case 4 is open loop stepper control
|
||||||
//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(idleStepper.stepperStatus == STEPPING || idleStepper.stepperStatus == COOLING)
|
if(idleStepper.stepperStatus == STEPPING || idleStepper.stepperStatus == COOLING)
|
||||||
|
@ -179,7 +179,7 @@ void idleControl()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Means we're in COOLING status but have been in this state long enough to
|
//Means we're in COOLING status but have been in this state long enough to
|
||||||
idleStepper.stepperStatus = SOFF;
|
idleStepper.stepperStatus = SOFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,11 +207,11 @@ void idleControl()
|
||||||
if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check
|
if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check
|
||||||
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards
|
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards
|
||||||
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards
|
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards
|
||||||
|
|
||||||
digitalWrite(pinStepperStep, HIGH);
|
digitalWrite(pinStepperStep, HIGH);
|
||||||
idleStepper.stepStartTime = micros();
|
idleStepper.stepStartTime = micros();
|
||||||
idleStepper.stepperStatus = STEPPING;
|
idleStepper.stepperStatus = STEPPING;
|
||||||
idleOn = true;
|
idleOn = true;
|
||||||
}
|
}
|
||||||
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacStepTable.axisX[IDLE_TABLE_SIZE-1])
|
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacStepTable.axisX[IDLE_TABLE_SIZE-1])
|
||||||
{
|
{
|
||||||
|
@ -224,13 +224,13 @@ void idleControl()
|
||||||
if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check
|
if ( idleStepper.targetIdleStep > (idleStepper.curIdleStep - configPage4.iacStepHyster) && idleStepper.targetIdleStep < (idleStepper.curIdleStep + configPage4.iacStepHyster) ) { return; } //Hysteris check
|
||||||
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards
|
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); idleStepper.curIdleStep--; }//Sets stepper direction to backwards
|
||||||
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards
|
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); idleStepper.curIdleStep++; }//Sets stepper direction to forwards
|
||||||
|
|
||||||
digitalWrite(pinStepperStep, HIGH);
|
digitalWrite(pinStepperStep, HIGH);
|
||||||
idleStepper.stepStartTime = micros();
|
idleStepper.stepStartTime = micros();
|
||||||
idleStepper.stepperStatus = STEPPING;
|
idleStepper.stepperStatus = STEPPING;
|
||||||
idleOn = true;
|
idleOn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ void homeStepper()
|
||||||
delayMicroseconds(iacStepTime);
|
delayMicroseconds(iacStepTime);
|
||||||
}
|
}
|
||||||
digitalWrite(pinStepperDir, STEPPER_FORWARD);
|
digitalWrite(pinStepperDir, STEPPER_FORWARD);
|
||||||
idleStepper.curIdleStep = 0;
|
idleStepper.curIdleStep = 0;
|
||||||
idleStepper.targetIdleStep = 0;
|
idleStepper.targetIdleStep = 0;
|
||||||
idleStepper.stepperStatus = SOFF;
|
idleStepper.stepperStatus = SOFF;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ void homeStepper()
|
||||||
static inline void disableIdle()
|
static inline void disableIdle()
|
||||||
{
|
{
|
||||||
TIMSK4 &= ~(1 << OCIE4C); //Turn off interrupt
|
TIMSK4 &= ~(1 << OCIE4C); //Turn off interrupt
|
||||||
digitalWrite(pinIdle1, LOW);
|
digitalWrite(pinIdle1, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Any common functions associated with starting the Idle
|
//Any common functions associated with starting the Idle
|
||||||
|
@ -275,8 +275,8 @@ ISR(TIMER4_COMPC_vect)
|
||||||
{
|
{
|
||||||
if (idle_pwm_state)
|
if (idle_pwm_state)
|
||||||
{
|
{
|
||||||
if (configPage4.iacPWMdir == 0)
|
if (configPage4.iacPWMdir == 0)
|
||||||
{
|
{
|
||||||
//Normal direction
|
//Normal direction
|
||||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||||
if(configPage4.iacChannels) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
if(configPage4.iacChannels) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||||
|
@ -288,12 +288,12 @@ ISR(TIMER4_COMPC_vect)
|
||||||
if(configPage4.iacChannels) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
if(configPage4.iacChannels) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||||
}
|
}
|
||||||
OCR4C = TCNT4 + (idle_pwm_max_count - idle_pwm_cur_value);
|
OCR4C = TCNT4 + (idle_pwm_max_count - idle_pwm_cur_value);
|
||||||
idle_pwm_state = false;
|
idle_pwm_state = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (configPage4.iacPWMdir == 0)
|
if (configPage4.iacPWMdir == 0)
|
||||||
{
|
{
|
||||||
//Normal direction
|
//Normal direction
|
||||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||||
if(configPage4.iacChannels) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
if(configPage4.iacChannels) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||||
|
@ -306,15 +306,15 @@ ISR(TIMER4_COMPC_vect)
|
||||||
}
|
}
|
||||||
OCR4C = TCNT4 + idle_pwm_target_value;
|
OCR4C = TCNT4 + idle_pwm_target_value;
|
||||||
idle_pwm_cur_value = idle_pwm_target_value;
|
idle_pwm_cur_value = idle_pwm_target_value;
|
||||||
idle_pwm_state = true;
|
idle_pwm_state = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#elif defined (CORE_TEENSY)
|
#elif defined (CORE_TEENSY)
|
||||||
//This function simply turns off the idle PWM and sets the pin low
|
//This function simply turns off the idle PWM and sets the pin low
|
||||||
static inline void disableIdle()
|
static inline void disableIdle()
|
||||||
{
|
{
|
||||||
digitalWrite(pinIdle1, LOW);
|
digitalWrite(pinIdle1, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void enableIdle() { }
|
static inline void enableIdle() { }
|
||||||
|
|
Loading…
Reference in New Issue