PWM and on/off idle fixes/cleanup (#806)
* Idle fixes #1 * Idle fixes #2 Co-authored-by: Josh Stewart <josh@noisymime.org>
This commit is contained in:
parent
2cda68277b
commit
5dee6135b7
|
@ -4832,6 +4832,7 @@ cmdVSSratio6 = "E\x99\x06"
|
|||
indicator = { vvt1Error }, "VVT1 Ok", "VVT1 Error", white, black, red, black
|
||||
indicator = { vvt2Error }, "VVT2 Ok", "VVT2 Error", white, black, red, black
|
||||
indicator = { fanStatus }, "Fan OFF", "Fan ON", white, black, red, black
|
||||
indicator = { idleControlOn }, "Idle OFF", "Idle ON", white, black, green, black
|
||||
indicator = { (batteryVoltage < batlow) || (batteryVoltage > bathigh) }, "Battery Voltage OK", "Battery Voltage Warning", white, black, red, black
|
||||
indicator = { outputsStatus0 }, "Programmable out 1 Off", "Programmable out 1 ON", white, black, green, black
|
||||
indicator = { outputsStatus1 }, "Programmable out 2 Off", "Programmable out 2 ON", white, black, green, black
|
||||
|
|
|
@ -311,7 +311,7 @@ void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portTy
|
|||
fullStatus[87] = highByte(currentStatus.ignLoad);
|
||||
fullStatus[88] = lowByte(currentStatus.injAngle);
|
||||
fullStatus[89] = highByte(currentStatus.injAngle);
|
||||
fullStatus[90] = currentStatus.idleDuty;
|
||||
fullStatus[90] = currentStatus.idleLoad;
|
||||
fullStatus[91] = currentStatus.CLIdleTarget; //closed loop idle target
|
||||
fullStatus[92] = currentStatus.mapDOT; //rate of change of the map
|
||||
fullStatus[93] = (int8_t)currentStatus.vvt1Angle;
|
||||
|
|
|
@ -669,7 +669,6 @@ struct statuses {
|
|||
byte fuelTempCorrection; /**< Amount of correction being applied to compensate for fuel temperature */
|
||||
int8_t flexIgnCorrection;/**< Amount of additional advance being applied based on flex. Note the type as this allows for negative values */
|
||||
byte afrTarget; /**< Current AFR Target looked up from AFR target table (x10 ? See @ref afrTable)*/
|
||||
byte idleDuty; /**< The current idle duty cycle amount if PWM idle is selected and active */
|
||||
byte CLIdleTarget; /**< The target idle RPM (when closed loop idle control is active) */
|
||||
bool idleUpActive; /**< Whether the externally controlled idle up is currently active */
|
||||
bool CTPSActive; /**< Whether the externally controlled closed throttle position sensor is currently active */
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#define IDLE_PIN_LOW() *idle_pin_port &= ~(idle_pin_mask)
|
||||
#define IDLE_PIN_HIGH() *idle_pin_port |= (idle_pin_mask)
|
||||
#define IDLE2_PIN_LOW() *idle2_pin_port &= ~(idle2_pin_mask)
|
||||
#define IDLE2_PIN_HIGH() *idle2_pin_port |= (idle2_pin_mask)
|
||||
|
||||
#define STEPPER_FORWARD 0
|
||||
#define STEPPER_BACKWARD 1
|
||||
|
|
|
@ -54,7 +54,7 @@ void initialiseIdle()
|
|||
//Case 1 is on/off idle control
|
||||
if ((currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage6.iacFastTemp)
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
IDLE_PIN_HIGH();
|
||||
idleOn = true;
|
||||
}
|
||||
break;
|
||||
|
@ -451,15 +451,17 @@ void idleControl()
|
|||
case IAC_ALGORITHM_ONOFF: //Case 1 is on/off idle control
|
||||
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage6.iacFastTemp) //All temps are offset by 40 degrees
|
||||
{
|
||||
digitalWrite(pinIdle1, HIGH);
|
||||
IDLE_PIN_HIGH();
|
||||
idleOn = true;
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
currentStatus.idleLoad = 100;
|
||||
}
|
||||
else if (idleOn)
|
||||
{
|
||||
digitalWrite(pinIdle1, LOW);
|
||||
IDLE_PIN_LOW();
|
||||
idleOn = false;
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
currentStatus.idleLoad = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -468,7 +470,7 @@ void idleControl()
|
|||
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 = 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,7 +478,7 @@ void idleControl()
|
|||
if( configPage6.iacPWMrun == true)
|
||||
{
|
||||
//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
|
||||
currentStatus.idleLoad = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
idleTaper = 0;
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +487,7 @@ void idleControl()
|
|||
if ( idleTaper < configPage2.idleTaperTime )
|
||||
{
|
||||
//Tapering between cranking IAC value and running
|
||||
currentStatus.idleDuty = map(idleTaper, 0, configPage2.idleTaperTime,\
|
||||
currentStatus.idleLoad = 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++; }
|
||||
|
@ -493,22 +495,13 @@ void idleControl()
|
|||
else
|
||||
{
|
||||
//Standard running
|
||||
currentStatus.idleDuty = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
currentStatus.idleLoad = table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
}
|
||||
}
|
||||
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
if( currentStatus.idleDuty > 100 ) { currentStatus.idleDuty = 100; } //Safety Check
|
||||
if( currentStatus.idleDuty == 0 )
|
||||
{
|
||||
disableIdle();
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag off
|
||||
break;
|
||||
}
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
|
||||
currentStatus.idleLoad = currentStatus.idleDuty;
|
||||
idleOn = true;
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleLoad += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
if( currentStatus.idleLoad > 100 ) { currentStatus.idleLoad = 100; } //Safety Check
|
||||
idle_pwm_target_value = percentage(currentStatus.idleLoad, idle_pwm_max_count);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -517,9 +510,8 @@ void idleControl()
|
|||
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);
|
||||
currentStatus.idleLoad = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
idle_pwm_target_value = percentage(currentStatus.idleLoad, idle_pwm_max_count);
|
||||
idle_pid_target_value = idle_pwm_target_value << 2; //Resolution increased
|
||||
idlePID.Initialize(); //Update output to smooth transition
|
||||
}
|
||||
|
@ -528,9 +520,8 @@ void idleControl()
|
|||
if( configPage6.iacPWMrun == true)
|
||||
{
|
||||
//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
|
||||
currentStatus.idleLoad = currentStatus.idleDuty;
|
||||
idle_pwm_target_value = percentage(currentStatus.idleDuty, idle_pwm_max_count);
|
||||
currentStatus.idleLoad = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
idle_pwm_target_value = percentage(currentStatus.idleLoad, idle_pwm_max_count);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -543,15 +534,8 @@ void idleControl()
|
|||
if(PID_computed == true)
|
||||
{
|
||||
idle_pwm_target_value = idle_pid_target_value>>2; //increased resolution
|
||||
if( idle_pwm_target_value == 0 )
|
||||
{
|
||||
disableIdle();
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag off
|
||||
break;
|
||||
}
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
currentStatus.idleLoad = ((unsigned long)(idle_pwm_target_value * 100UL) / idle_pwm_max_count);
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleLoad += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
|
||||
}
|
||||
idleCounter++;
|
||||
|
@ -564,12 +548,20 @@ void idleControl()
|
|||
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);
|
||||
currentStatus.idleLoad = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
idle_pwm_target_value = percentage(currentStatus.idleLoad, idle_pwm_max_count);
|
||||
idle_pid_target_value = idle_pwm_target_value << 2; //Resolution increased
|
||||
idlePID.Initialize(); //Update output to smooth transition
|
||||
}
|
||||
else if ( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_RUN))
|
||||
{
|
||||
if( configPage6.iacPWMrun == true)
|
||||
{
|
||||
//Engine is not running or cranking, but the run before crank flag is set. Use the cranking table
|
||||
currentStatus.idleLoad = table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //All temps are offset by 40 degrees
|
||||
idle_pwm_target_value = percentage(currentStatus.idleLoad, idle_pwm_max_count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Read the OL table as feedforward term
|
||||
|
@ -586,15 +578,8 @@ void idleControl()
|
|||
if(PID_computed == true)
|
||||
{
|
||||
idle_pwm_target_value = idle_pid_target_value>>2; //increased resolution
|
||||
if( idle_pwm_target_value == 0 )
|
||||
{
|
||||
disableIdle();
|
||||
BIT_CLEAR(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag off
|
||||
break;
|
||||
}
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
currentStatus.idleLoad = ((unsigned long)(idle_pwm_target_value * 100UL) / idle_pwm_max_count);
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleDuty += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
if(currentStatus.idleUpActive == true) { currentStatus.idleLoad += configPage2.idleUpAdder; } //Add Idle Up amount if active
|
||||
|
||||
}
|
||||
idleCounter++;
|
||||
|
@ -753,15 +738,35 @@ void idleControl()
|
|||
}
|
||||
lastDFCOValue = BIT_CHECK(currentStatus.status1, BIT_STATUS1_DFCO);
|
||||
|
||||
//Check for 100% DC on PWM idle
|
||||
//Check for 100% and 0% DC on PWM idle
|
||||
if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OLCL) )
|
||||
{
|
||||
if(currentStatus.idleLoad == 100)
|
||||
if(currentStatus.idleLoad >= 100)
|
||||
{
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
IDLE_TIMER_DISABLE();
|
||||
IDLE_PIN_HIGH();
|
||||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
IDLE_PIN_HIGH(); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_LOW(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
IDLE_PIN_LOW(); // Switch pin to low
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_HIGH(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
}
|
||||
else if (currentStatus.idleLoad == 0)
|
||||
{
|
||||
disableIdle();
|
||||
}
|
||||
else
|
||||
{
|
||||
BIT_SET(currentStatus.spark, BIT_SPARK_IDLE); //Turn the idle control flag on
|
||||
IDLE_TIMER_ENABLE();
|
||||
}
|
||||
else if(currentStatus.idleLoad > 0) { IDLE_TIMER_ENABLE(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,7 +777,18 @@ void disableIdle()
|
|||
if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) )
|
||||
{
|
||||
IDLE_TIMER_DISABLE();
|
||||
digitalWrite(pinIdle1, LOW);
|
||||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
IDLE_PIN_LOW(); // Switch pin to low
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_HIGH(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
IDLE_PIN_HIGH(); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_LOW(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
}
|
||||
else if( (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_CL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_STEP_OLCL) )
|
||||
{
|
||||
|
@ -809,14 +825,14 @@ void idleInterrupt() //Most ARM chips can simply call a function
|
|||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||
if(configPage6.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
IDLE_PIN_LOW(); // Switch pin to low (1 pin mode)
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_HIGH(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
IDLE_PIN_HIGH(); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_LOW(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
SET_COMPARE(IDLE_COMPARE, IDLE_COUNTER + (idle_pwm_max_count - idle_pwm_cur_value) );
|
||||
idle_pwm_state = false;
|
||||
|
@ -826,14 +842,14 @@ void idleInterrupt() //Most ARM chips can simply call a function
|
|||
if (configPage6.iacPWMdir == 0)
|
||||
{
|
||||
//Normal direction
|
||||
*idle_pin_port |= (idle_pin_mask); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { *idle2_pin_port &= ~(idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
IDLE_PIN_HIGH(); // Switch pin high
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_LOW(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
else
|
||||
{
|
||||
//Reversed direction
|
||||
*idle_pin_port &= ~(idle_pin_mask); // Switch pin to low (1 pin mode)
|
||||
if(configPage6.iacChannels == 1) { *idle2_pin_port |= (idle2_pin_mask); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
IDLE_PIN_LOW(); // Switch pin to low (1 pin mode)
|
||||
if(configPage6.iacChannels == 1) { IDLE2_PIN_HIGH(); } //If 2 idle channels are in use, flip idle2 to be the opposite of idle1
|
||||
}
|
||||
SET_COMPARE(IDLE_COMPARE, IDLE_COUNTER + idle_pwm_target_value);
|
||||
idle_pwm_cur_value = idle_pwm_target_value;
|
||||
|
|
Loading…
Reference in New Issue