Complete but untested idle control

This commit is contained in:
Josh Stewart 2015-08-21 14:14:47 +10:00
parent 3c6a39a9af
commit c63c581e61
4 changed files with 95 additions and 37 deletions

View File

@ -342,6 +342,8 @@ byte pinSpareOut4; //Generic output
byte pinSpareOut5; //Generic output
byte pinSpareOut6; //Generic output
byte pinFan; // Cooling fan output
byte pinStepperDir; //Direction pin for the stepper motor driver
byte pinStepperStep; //Step pin for the stepper motor driver
// global variables // from speeduino.ino
extern struct statuses currentStatus; // from speeduino.ino

2
idle.h
View File

@ -1,6 +1,7 @@
#define STEPPER_FORWARD 1
#define STEPPER_BACKWARD 0
#define IDLE_TABLE_SIZE 10
#define DRV8825_STEP_TIME 800 //The time in uS between steps for the DRV8825
enum StepperStatus {SOFF, STEPPING}; //The 2 statuses that a stepper can have. STEPPING means that a high pulse is currently being sent and will need to be turned off at some point.
@ -19,6 +20,7 @@ struct table2D iacStepTable;
struct table2D iacCrankStepsTable;
struct table2D iacCrankDutyTable;
struct StepperIdle idleStepper;
bool idleOn; //Simply tracks whether idle was on last time around
void initialiseIdle();

View File

@ -60,6 +60,8 @@ void initialiseIdle()
iacCrankStepsTable.xSize = 4;
iacCrankStepsTable.values = configPage4.iacCrankSteps;
iacCrankStepsTable.axisX = configPage4.iacCrankBins;
homeStepper(); //Returns the stepper to the 'home' position
break;
case 5:
@ -113,20 +115,68 @@ void idleControl()
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
analogWrite(pinIdle1, table2D_getValue(&iacCrankStepsTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
idleOn = true;
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
analogWrite(pinIdle1, table2D_getValue(&iacStepTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET)); //All temps are offset by 40 degrees
idleOn = true;
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;
}
else if (idleOn) { digitalWrite(pinIdle1, LOW); idleOn = false; }
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;
}

View File

@ -10,16 +10,16 @@ Returns how much free dynamic memory exists (between heap and stack)
*/
#include "utils.h"
int freeRam ()
int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void setPinMapping(byte boardID)
{
switch(boardID)
switch (boardID)
{
case 0:
//Pin mappings as per the v0.1 shield
@ -105,8 +105,10 @@ void setPinMapping(byte boardID)
pinTachOut = 49; //Tacho output pin
pinIdle1 = 5; //Single wire idle control
pinFuelPump = 45; //Fuel pump output
break;
pinStepperDir = 16; //Direction pin for DRV8825 driver
pinStepperStep = 17; //Step pin for DRV8825 driver
break;
case 10:
//Pin mappings for user turtanas PCB
pinInjector1 = 4; //Output pin injector 1 is on
@ -136,8 +138,8 @@ void setPinMapping(byte boardID)
pinTachOut = 41; //Tacho output pin transistori puuttuu 2n2222 tähän ja 1k 12v
pinFuelPump = 42; //Fuel pump output 2n2222
break;
case 20:
case 20:
//Pin mappings as per the Plazomat In/Out shields Rev 0.1
pinInjector1 = 8; //Output pin injector 1 is on
pinInjector2 = 9; //Output pin injector 2 is on
@ -163,7 +165,7 @@ void setPinMapping(byte boardID)
pinTPS = A2;//TPS input pin
pinCLT = A1; //CLS sensor pin
pinIAT = A0; //IAT sensor pin
default:
//Pin mappings as per the v0.2 shield
pinInjector1 = 8; //Output pin injector 1 is on
@ -199,7 +201,7 @@ void setPinMapping(byte boardID)
pinMode(pinIdle1, OUTPUT);
pinMode(pinIdle2, OUTPUT);
pinMode(pinFuelPump, OUTPUT);
//And for inputs
pinMode(pinMAP, INPUT);
pinMode(pinO2, INPUT);
@ -207,7 +209,7 @@ void setPinMapping(byte boardID)
pinMode(pinIAT, INPUT);
pinMode(pinCLT, INPUT);
pinMode(pinBat, INPUT);
//
digitalWrite(pinMAP, HIGH);
//digitalWrite(pinO2, LOW);
@ -223,31 +225,33 @@ GammaE: Sum of Enrichment factors (Cold start, acceleration). This is a multipli
injDT: Injector dead time. The time the injector take to open minus the time it takes to close (Both in uS)
TPS: Throttle position (0% to 100%)
This function is called by PW_SD and PW_AN for speed0density and pure Alpha-N calculations respectively.
This function is called by PW_SD and PW_AN for speed0density and pure Alpha-N calculations respectively.
*/
unsigned int PW(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen, byte TPS)
{
//Standard float version of the calculation
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(TPS/100.0) * (float)(corrections/100.0) + injOpen);
//Note: The MAP and TPS portions are currently disabled, we use VE and corrections only
//100% float free version, does sacrifice a little bit of accuracy.
int iVE = ((int)VE << 7) / 100;
//int iVE = divs100( ((int)VE << 7));
//int iMAP = ((int)MAP << 7) / 100;
int iCorrections = (corrections << 7) / 100;
//int iTPS = ((int)TPS << 7) / 100;
{
//Standard float version of the calculation
//return (REQ_FUEL * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(TPS/100.0) * (float)(corrections/100.0) + injOpen);
//Note: The MAP and TPS portions are currently disabled, we use VE and corrections only
unsigned long intermediate = ((long)REQ_FUEL * (long)iVE) >>7; //Need to use an intermediate value to avoid overflowing the long
//intermediate = (intermediate * iMAP) >> 7;
intermediate = (intermediate * iCorrections) >> 7;
//intermediate = (intermediate * iTPS) >> 7;
intermediate += injOpen; //Add the injector opening time
if ( intermediate > 65535) { intermediate = 65535; } //Make sure this won't overflow when we convert to uInt. This means the maximum pulsewidth possible is 65.535mS
return (unsigned int)(intermediate);
//100% float free version, does sacrifice a little bit of accuracy.
int iVE = ((int)VE << 7) / 100;
//int iVE = divs100( ((int)VE << 7));
//int iMAP = ((int)MAP << 7) / 100;
int iCorrections = (corrections << 7) / 100;
//int iTPS = ((int)TPS << 7) / 100;
unsigned long intermediate = ((long)REQ_FUEL * (long)iVE) >> 7; //Need to use an intermediate value to avoid overflowing the long
//intermediate = (intermediate * iMAP) >> 7;
intermediate = (intermediate * iCorrections) >> 7;
//intermediate = (intermediate * iTPS) >> 7;
intermediate += injOpen; //Add the injector opening time
if ( intermediate > 65535) {
intermediate = 65535; //Make sure this won't overflow when we convert to uInt. This means the maximum pulsewidth possible is 65.535mS
}
return (unsigned int)(intermediate);
}
//Convenience functions for Speed Density and Alpha-N
unsigned int PW_SD(int REQ_FUEL, byte VE, byte MAP, int corrections, int injOpen)
{