183 lines
6.6 KiB
C++
183 lines
6.6 KiB
C++
/*
|
|
Speeduino - Simple engine management for the Arduino Mega 2560 platform
|
|
Copyright (C) Josh Stewart
|
|
A full copy of the license may be found in the projects root directory
|
|
*/
|
|
|
|
/*
|
|
These functions over the PWM and stepper idle control
|
|
*/
|
|
|
|
/*
|
|
Idle Control
|
|
Currently limited to on/off control and open loop PWM and stepper drive
|
|
*/
|
|
void initialiseIdle()
|
|
{
|
|
//Initialising comprises of setting the 2D tables with the relevant values from the config pages
|
|
switch(configPage4.iacAlgorithm)
|
|
{
|
|
case 0:
|
|
//Case 0 is no idle control ('None')
|
|
break;
|
|
|
|
case 1:
|
|
//Case 1 is on/off idle control
|
|
if (currentStatus.coolant < configPage4.iacFastTemp)
|
|
{
|
|
digitalWrite(pinIdle1, HIGH);
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
//Case 2 is PWM open loop
|
|
iacPWMTable.xSize = 10;
|
|
iacPWMTable.values = configPage4.iacOLPWMVal;
|
|
iacPWMTable.axisX = configPage4.iacBins;
|
|
|
|
iacCrankDutyTable.xSize = 4;
|
|
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
|
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
|
break;
|
|
|
|
case 3:
|
|
//Case 3 is PWM closed loop
|
|
iacClosedLoopTable.xSize = 10;
|
|
iacClosedLoopTable.values = configPage4.iacCLValues;
|
|
iacClosedLoopTable.axisX = configPage4.iacBins;
|
|
|
|
iacCrankDutyTable.xSize = 4;
|
|
iacCrankDutyTable.values = configPage4.iacCrankDuty;
|
|
iacCrankDutyTable.axisX = configPage4.iacCrankBins;
|
|
break;
|
|
|
|
case 4:
|
|
//Case 2 is Stepper open loop
|
|
iacStepTable.xSize = 10;
|
|
iacStepTable.values = configPage4.iacOLStepVal;
|
|
iacStepTable.axisX = configPage4.iacBins;
|
|
|
|
iacCrankStepsTable.xSize = 4;
|
|
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
|
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
|
|
|
homeStepper(); //Returns the stepper to the 'home' position
|
|
break;
|
|
|
|
case 5:
|
|
//Case 5 is Stepper closed loop
|
|
iacClosedLoopTable.xSize = 10;
|
|
iacClosedLoopTable.values = configPage4.iacCLValues;
|
|
iacClosedLoopTable.axisX = configPage4.iacBins;
|
|
|
|
iacCrankStepsTable.xSize = 4;
|
|
iacCrankStepsTable.values = configPage4.iacCrankSteps;
|
|
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void idleControl()
|
|
{
|
|
switch(configPage4.iacAlgorithm)
|
|
{
|
|
case 0: //Case 0 is no idle control ('None')
|
|
break;
|
|
|
|
case 1: //Case 1 is on/off idle control
|
|
if ( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < configPage4.iacFastTemp) //All temps are offset by 40 degrees
|
|
{
|
|
digitalWrite(pinIdle1, HIGH);
|
|
idleOn = true;
|
|
}
|
|
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
|
|
break;
|
|
|
|
case 2: //Case 2 is PWM open loop
|
|
//Check for cranking pulsewidth
|
|
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
|
{
|
|
//Currently cranking. Use the cranking table
|
|
analogWrite(pinIdle1, table2D_getValue(&iacCrankDutyTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
|
|
idleOn = true;
|
|
}
|
|
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacPWMTable.values[IDLE_TABLE_SIZE-1])
|
|
{
|
|
//Standard running
|
|
analogWrite(pinIdle1, table2D_getValue(&iacPWMTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
|
|
idleOn = true;
|
|
}
|
|
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
|
|
break;
|
|
|
|
case 3: //Case 3 is PWM closed loop (Not currently implemented)
|
|
break;
|
|
|
|
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
|
|
if(idleStepper.stepperStatus == STEPPING)
|
|
{
|
|
if(micros() > (idleStepper.stepStartTime + DRV8825_STEP_TIME) )
|
|
{
|
|
//Means we're currently in a step, but it needs to be turned off
|
|
digitalWrite(pinStepperStep, LOW); //Turn off the step
|
|
idleStepper.stepperStatus = SOFF;
|
|
}
|
|
else
|
|
{
|
|
//Means we're in a step, but it doesn't need to turn off yet. No further action at this time
|
|
return;
|
|
}
|
|
}
|
|
|
|
//Check for cranking pulsewidth
|
|
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
|
{
|
|
//Currently cranking. Use the cranking table
|
|
idleStepper.targetIdleStep = table2D_getValue(&iacCrankStepsTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
|
|
if (idleStepper.targetIdleStep == idleStepper.curIdleStep) { return; } //No action required
|
|
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); }//Sets stepper direction to backwards
|
|
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); }//Sets stepper direction to forwards
|
|
|
|
digitalWrite(pinStepperStep, HIGH);
|
|
idleStepper.stepStartTime = micros();
|
|
idleStepper.stepperStatus = STEPPING;
|
|
idleOn = true;
|
|
}
|
|
else if( (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET) < iacStepTable.values[IDLE_TABLE_SIZE-1])
|
|
{
|
|
//Standard running
|
|
idleStepper.targetIdleStep = table2D_getValue(&iacStepTable, (currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
|
|
if (idleStepper.targetIdleStep == idleStepper.curIdleStep) { return; } //No action required
|
|
else if(idleStepper.targetIdleStep < idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_BACKWARD); }//Sets stepper direction to backwards
|
|
else if (idleStepper.targetIdleStep > idleStepper.curIdleStep) { digitalWrite(pinStepperDir, STEPPER_FORWARD); }//Sets stepper direction to forwards
|
|
|
|
digitalWrite(pinStepperStep, HIGH);
|
|
idleStepper.stepStartTime = micros();
|
|
idleStepper.stepperStatus = STEPPING;
|
|
idleOn = true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
A simple function to home the stepper motor (If in use)
|
|
*/
|
|
void homeStepper()
|
|
{
|
|
//Need to 'home' the stepper on startup
|
|
digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards
|
|
for(int x=0; x < configPage4.iacStepHome; x++)
|
|
{
|
|
digitalWrite(pinStepperStep, HIGH);
|
|
delayMicroseconds(DRV8825_STEP_TIME);
|
|
}
|
|
digitalWrite(pinStepperDir, STEPPER_FORWARD);
|
|
idleStepper.curIdleStep = 0;
|
|
idleStepper.targetIdleStep = 0;
|
|
idleStepper.stepperStatus = SOFF;
|
|
}
|