Staged injection (Table and automatic modes)

This commit is contained in:
Josh Stewart 2017-12-07 13:46:04 +11:00
parent 98ea973a80
commit 35fa068575
5 changed files with 45 additions and 1 deletions

View File

@ -59,6 +59,7 @@ volatile unsigned long triggerFilterTime; // The shortest time (in uS) that puls
unsigned long triggerSecFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) for the secondary input
unsigned int triggerSecFilterTime_duration; // The shortest valid time (in uS) pulse DURATION
volatile int triggerToothAngle; //The number of crank degrees that elapse per tooth
volatile bool triggerToothAngleIsCorrect = false; //Whether or not the triggerToothAngle variable is currently accurate. Some patterns have times when the triggerToothAngle variable cannot be accurately set.
bool secondDerivEnabled; //The use of the 2nd derivative calculation is limited to certain decoders. This is set to either true or false in each decoders setup routine
bool decoderIsSequential; //Whether or not the decoder supports sequential operation
bool decoderIsLowRes = false; //Is set true, certain extra calculations are performed for better timing accuracy

View File

@ -173,6 +173,7 @@ void triggerPri_missingTooth()
triggerFilterTime = 0; //This is used to prevent a condition where serious intermitent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
}
}
else
@ -181,6 +182,7 @@ void triggerPri_missingTooth()
setFilter(curGap);
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = true;
}
}
@ -238,6 +240,7 @@ int getCrankAngle_missingTooth(int timePerDegree)
//crankAngle += DIV_ROUND_CLOSEST(elapsedTime, timePerDegree);
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
//crankAngle += uSToDegrees(elapsedTime);
//Sequential check (simply sets whether we're on the first or 2nd revoltuion of the cycle)
if (tempRevolutionOne) { crankAngle += 360; }
@ -289,6 +292,7 @@ void triggerSetup_DualWheel()
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
secondDerivEnabled = false;
decoderIsSequential = true;
triggerToothAngleIsCorrect = true; //This is always true for this pattern
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
}
@ -437,6 +441,7 @@ void triggerSetup_BasicDistributor()
decoderIsSequential = false;
toothCurrentCount = 0; //Default value
decoderHasFixedCrankingTiming = true;
triggerToothAngleIsCorrect = true;
if(configPage1.nCylinders <= 4) { MAX_STALL_TIME = (1851UL * triggerToothAngle); }//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
else { MAX_STALL_TIME = (3200UL * triggerToothAngle); } //Minimum 50rpm. (3200uS is the time per degree at 50rpm).
@ -648,6 +653,7 @@ void triggerSetup_4G63()
secondDerivEnabled = false;
decoderIsSequential = true;
decoderHasFixedCrankingTiming = true;
triggerToothAngleIsCorrect = true;
MAX_STALL_TIME = 366667UL; //Minimum 50rpm based on the 110 degree tooth spacing
if(initialisationComplete == false) { toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
//decoderIsLowRes = true;
@ -1167,6 +1173,7 @@ void triggerSetup_Audi135()
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
secondDerivEnabled = false;
decoderIsSequential = true;
triggerToothAngleIsCorrect = true;
}
void triggerPri_Audi135()
@ -1408,6 +1415,7 @@ void triggerSetup_Miata9905()
triggerFilterTime = 1500; //10000 rpm, assuming we're triggering on both edges off the crank tooth.
triggerSecFilterTime = 0; //Need to figure out something better for this
decoderHasFixedCrankingTiming = true;
triggerToothAngleIsCorrect = true;
}
void triggerPri_Miata9905()

View File

@ -134,6 +134,9 @@
#define EGO_ALGORITHM_SIMPLE 0
#define EGO_ALGORITHM_PID 2
#define STAGING_MODE_TABLE 0
#define STAGING_MODE_AUTO 1
#define MAX_RPM 18000 //This is the maximum rpm that the ECU will attempt to run at. It is NOT related to the rev limiter, but is instead dictates how fast certain operations will be allowed to run. Lower number gives better performance
#define engineSquirtsPerCycle 2 //Would be 1 for a 2 stroke
@ -634,7 +637,9 @@ struct config11 {
uint16_t boostSens;
byte boostIntv;
byte unused11_28_192[164];
uint16_t stagedInjSizePri;
uint16_t stagedInjSizeSec;
byte unused11_28_192[160];
#if defined(CORE_AVR)
};

View File

@ -6,6 +6,7 @@ unsigned long percentage(byte, unsigned long);
//#define degreesToUS(degrees) (decoderIsLowRes == true ) ? ((degrees * 166666UL) / currentStatus.RPM) : (degrees * (unsigned long)timePerDegree)
#define degreesToUS(degrees) ((degrees * revolutionTime) / 360)
#define fastDegreesToUS(degrees) (degrees * (unsigned long)timePerDegree)
//#define degreesToUS(degrees) ((degrees * revolutionTime * 3054198967ULL) >> 40) //Fast version of divide by 360
//#define degreesToUS(degrees) (degrees * (unsigned long)timePerDegree)

View File

@ -51,6 +51,8 @@ struct config10 configPage10;
struct config11 configPage11;
int req_fuel_uS, inj_opentime_uS;
uint16_t staged_req_fuel_mult_pri;
uint16_t staged_req_fuel_mult_sec;
bool ignitionOn = false; //The current state of the ignition system
bool fuelOn = false; //The current state of the ignition system
@ -281,6 +283,23 @@ void setup()
req_fuel_uS = configPage1.reqFuel * 100; //Convert to uS and an int. This is the only variable to be used in calculations
inj_opentime_uS = configPage1.injOpen * 100; //Injector open time. Comes through as ms*10 (Eg 15.5ms = 155).
if(configPage11.stagingEnabled == true)
{
uint32_t totalInjector = configPage11.stagedInjSizePri + configPage11.stagedInjSizeSec;
/*
These values are a percentage of the req_fuel value that would be required for each injector channel to deliver that much fuel.
Eg:
Pri injectors are 250cc
Sec injectors are 500cc
Total injector capacity = 750cc
staged_req_fuel_mult_pri = 300% (The primary injectors would have to run 3x the overall PW in order to be the equivalent of the full 750cc capacity
staged_req_fuel_mult_sec = 150% (The secondary injectors would have to run 1.5x the overall PW in order to be the equivalent of the full 750cc capacity
*/
staged_req_fuel_mult_pri = (100 * totalInjector) / configPage11.stagedInjSizePri;
staged_req_fuel_mult_sec = (100 * totalInjector) / configPage11.stagedInjSizeSec;
}
//Begin the main crank trigger interrupt pin setup
//The interrupt numbering is a bit odd - See here for reference: http://arduino.cc/en/Reference/AttachInterrupt
//These assignments are based on the Arduino Mega AND VARY BETWEEN BOARDS. Please confirm the board you are using and update acordingly.
@ -433,6 +452,16 @@ void setup()
}
if (!configPage1.injTiming) { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time
//Check if injector staging is enabled
if(configPage11.stagingEnabled == true)
{
channel3InjEnabled = true;
channel4InjEnabled = true;
channel3InjDegrees = channel1InjDegrees;
channel4InjDegrees = channel2InjDegrees;
}
channel1InjEnabled = true;
channel2InjEnabled = true;
break;