diff --git a/decoders.h b/decoders.h index 0bec10f..c2185a5 100644 --- a/decoders.h +++ b/decoders.h @@ -15,7 +15,7 @@ volatile unsigned long toothLastSecToothTime = 0; //The time (micros()) that the volatile unsigned long toothLastMinusOneToothTime = 0; //The time (micros()) that the tooth before the last tooth was registered volatile unsigned long toothOneTime = 0; //The time (micros()) that tooth 1 last triggered volatile unsigned long toothOneMinusOneTime = 0; //The 2nd to last time (micros()) that tooth 1 last triggered -volatile bool revolutionOne; // For sequential operation, this tracks whether the current revolution is 1 or 2 (not 1) +volatile bool revolutionOne = 0; // For sequential operation, this tracks whether the current revolution is 1 or 2 (not 1) volatile unsigned int toothHistory[TOOTH_LOG_BUFFER]; volatile unsigned int toothHistoryIndex = 0; diff --git a/decoders.ino b/decoders.ino index e09f7e3..2dd223a 100644 --- a/decoders.ino +++ b/decoders.ino @@ -107,6 +107,7 @@ void triggerPri_missingTooth() if ( curGap > targetGap || toothCurrentCount > triggerActualTeeth) { toothCurrentCount = 1; + revolutionOne = !revolutionOne; //Flip sequential revolution tracker toothOneMinusOneTime = toothOneTime; toothOneTime = curTime; currentStatus.hasSync = true; @@ -123,7 +124,10 @@ void triggerPri_missingTooth() toothLastToothTime = curTime; } -void triggerSec_missingTooth(){ return; } //This function currently is not used +void triggerSec_missingTooth() +{ + if(!currentStatus.hasSync) { revolutionOne = 0; } //Sequential revolution reset +} int getRPM_missingTooth() { @@ -147,6 +151,9 @@ int getCrankAngle_missingTooth(int 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; } + //Sequential check (simply sets whether we're on the first or 2nd revoltuion of the cycle) + if (revolutionOne) { crankAngle += 360; } + if (crankAngle >= 720) { crankAngle -= 720; } else if (crankAngle > CRANK_ANGLE_MAX) { crankAngle -= CRANK_ANGLE_MAX; } if (crankAngle < 0) { crankAngle += 360; } diff --git a/globals.h b/globals.h index b08123a..7082896 100644 --- a/globals.h +++ b/globals.h @@ -55,9 +55,15 @@ const byte packetSize = 35; #define TOOTH_LOG_SIZE 128 #define TOOTH_LOG_BUFFER 256 -#define INJ_SIMULTANEOUS 0 +#define INJ_PAIRED 0 #define INJ_SEMISEQUENTIAL 1 -#define INJ_SEQUENTIAL 2 +#define INJ_BANKED 2 +#define INJ_SEQUENTIAL 3 + +#define IGN_MODE_WASTED 0 +#define IGN_MODE_SINGLE 1 +#define IGN_MODE_WASTEDCOP 2 +#define IGN_MODE_SEQUENTIAL 3 #define SIZE_BYTE 8 #define SIZE_INT 16 diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 089b163..68c5af4 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -185,7 +185,7 @@ page = 2 flexEnabled= bits, U08, 38, [1:1], "Off", "On" algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N" baroCorr = bits, U08, 38, [3:3], "Off", "On" - injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "Banked", "INVALID" + injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "INVALID", "Sequential" canEnable = bits, U08, 38, [6:6], "Disable", "Enable" primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1 diff --git a/speeduino.ino b/speeduino.ino index ffeebc5..e6a6f57 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -97,9 +97,10 @@ unsigned long MAPrunningValue; //Used for tracking either the total of all MAP r unsigned int MAPcount; //Number of samples taken in the current MAP cycle byte MAPcurRev = 0; //Tracks which revolution we're sampling on -int CRANK_ANGLE_MAX = 360; // The number of crank degrees that the system track over. 360 for wasted / timed batch and 720 for sequential -bool useSequentialFuel; // Whether sequential fueling is to be used (1 squirt per cycle) -bool useSequentialIgnition; // Whether sequential ignition is used (1 spark per cycle) +int CRANK_ANGLE_MAX = 720; +int CRANK_ANGLE_MAX_IGN, CRANK_ANGLE_MAX_INJ = 360; // The number of crank degrees that the system track over. 360 for wasted / timed batch and 720 for sequential +//bool useSequentialFuel; // Whether sequential fueling is to be used (1 squirt per cycle) +//bool useSequentialIgnition; // Whether sequential ignition is used (1 spark per cycle) static byte coilHIGH = HIGH; static byte coilLOW = LOW; @@ -485,11 +486,14 @@ void setup() case 2: channel1IgnDegrees = 0; - if (configPage1.engineType == EVEN_FIRE ) { channel2IgnDegrees = 180; } + if (configPage1.engineType == EVEN_FIRE ) + { + channel2IgnDegrees = 180; + } else { channel2IgnDegrees = configPage1.oddfire2; } - - //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL) + + //For alternating injection, the squirt occurs at different times for each channel + if(configPage1.injLayout == INJ_SEMISEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = channel2IgnDegrees; //Set to the same as the ignition degrees (Means there's no need for another if to check for oddfire) @@ -514,17 +518,19 @@ void setup() } //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL) + if(configPage1.injLayout == INJ_SEMISEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = channel2IgnDegrees; channel3InjDegrees = channel2IgnDegrees; } - else if (configPage1.injTiming == INJ_SEQUENTIAL) + else if (configPage1.injLayout == INJ_SEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = 240; channel3InjDegrees = 480; + CRANK_ANGLE_MAX_INJ = 720; + req_fuel_uS = req_fuel_uS * 2; } else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = 0; } //For simultaneous, all squirts happen at the same time @@ -539,10 +545,12 @@ void setup() { channel2IgnDegrees = 180; - if(useSequentialIgnition) + if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL) { channel3IgnDegrees = 360; channel4IgnDegrees = 540; + + CRANK_ANGLE_MAX_IGN = 720; } } else @@ -553,17 +561,23 @@ void setup() } //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL) + if(configPage1.injLayout == INJ_SEMISEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = channel2IgnDegrees; } - else if (useSequentialFuel) + else if (configPage1.injLayout == INJ_SEQUENTIAL) { channel1InjDegrees = 0; - channel2InjDegrees = channel2IgnDegrees; - channel3InjDegrees = channel3IgnDegrees; - channel4InjDegrees = channel4IgnDegrees; + channel2InjDegrees = 180; + channel3InjDegrees = 360; + channel4InjDegrees = 540; + + channel3InjEnabled = true; + channel4InjEnabled = true; + + CRANK_ANGLE_MAX_INJ = 720; + req_fuel_uS = req_fuel_uS * 2; } else { channel1InjDegrees = channel2InjDegrees = 0; } //For simultaneous, all squirts happen at the same time @@ -577,16 +591,18 @@ void setup() channel4IgnDegrees = 216; channel5IgnDegrees = 288; - if(useSequentialIgnition) + if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL) { channel2IgnDegrees = 144; channel3IgnDegrees = 288; channel4IgnDegrees = 432; channel5IgnDegrees = 576; + + CRANK_ANGLE_MAX_IGN = 720; } //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL) + if(configPage1.injLayout == INJ_SEMISEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = 72; @@ -594,13 +610,15 @@ void setup() channel4InjDegrees = 216; channel5InjDegrees = 288; } - else if (useSequentialFuel) + else if (configPage1.injLayout == INJ_SEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = 144; channel3InjDegrees = 288; channel4InjDegrees = 432; channel5InjDegrees = 576; + + CRANK_ANGLE_MAX_INJ = 720; } else { channel1InjDegrees = channel2InjDegrees = channel3InjDegrees = channel4InjDegrees = channel5InjDegrees = 0; } //For simultaneous, all squirts happen at the same time @@ -616,7 +634,7 @@ void setup() channel3IgnDegrees = 240; //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL || configPage1.injTiming == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders + if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injLayout == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders { channel1InjDegrees = 0; channel2InjDegrees = 120; @@ -637,7 +655,7 @@ void setup() channel4IgnDegrees = 270; //For alternatiing injection, the squirt occurs at different times for each channel - if(configPage1.injTiming == INJ_SEMISEQUENTIAL || configPage1.injTiming == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders + if(configPage1.injLayout == INJ_SEMISEQUENTIAL || configPage1.injTiming == INJ_SEQUENTIAL) //No full sequential for more than 4 cylinders { channel1InjDegrees = 0; channel2InjDegrees = 90; @@ -984,6 +1002,7 @@ void loop() if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { unsigned long pwLimit = percentage(configPage1.dutyLim, revolutionTime); //The pulsewidth limit is determined to be the duty cycle limit (Eg 85%) by the total time it takes to perform 1 revolution + if ( if (currentStatus.PW > pwLimit) { currentStatus.PW = pwLimit; } } @@ -993,53 +1012,66 @@ void loop() //Determine next firing angles int PWdivTimerPerDegree = div(currentStatus.PW, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed injector1StartAngle = configPage1.inj1Ang - ( PWdivTimerPerDegree ); //This is a little primitive, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. See http://www.extraefi.co.uk/sequential_fuel.html for more detail - if(injector1StartAngle < 0) {injector1StartAngle += CRANK_ANGLE_MAX;} + if(injector1StartAngle < 0) {injector1StartAngle += CRANK_ANGLE_MAX_INJ;} //Repeat the above for each cylinder switch (configPage1.nCylinders) { //2 cylinders case 2: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} break; //3 cylinders case 3: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree )); - if(injector3StartAngle > CRANK_ANGLE_MAX) {injector3StartAngle -= CRANK_ANGLE_MAX;} + if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;} break; //4 cylinders case 4: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} + + if(configPage1.injLayout == INJ_SEQUENTIAL) + { + injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree )); + if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;} + injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree )); + if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;} + + injector1StartAngle += 360; + injector2StartAngle += 360; + injector3StartAngle += 360; + injector4StartAngle += 360; + } break; //5 cylinders case 5: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree )); - if(injector3StartAngle > CRANK_ANGLE_MAX) {injector3StartAngle -= CRANK_ANGLE_MAX;} + if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;} injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree )); - if(injector4StartAngle > CRANK_ANGLE_MAX) {injector4StartAngle -= CRANK_ANGLE_MAX;} + if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;} injector5StartAngle = (configPage1.inj1Ang + channel5InjDegrees - ( PWdivTimerPerDegree )); - if(injector5StartAngle > CRANK_ANGLE_MAX) {injector5StartAngle -= CRANK_ANGLE_MAX;} + if(injector5StartAngle > CRANK_ANGLE_MAX_INJ) {injector5StartAngle -= CRANK_ANGLE_MAX_INJ;} break; //6 cylinders case 6: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree )); - if(injector3StartAngle > CRANK_ANGLE_MAX) {injector3StartAngle -= CRANK_ANGLE_MAX;} + if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;} break; //8 cylinders case 8: injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree )); - if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;} + if(injector2StartAngle > CRANK_ANGLE_MAX_INJ) {injector2StartAngle -= CRANK_ANGLE_MAX_INJ;} injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree )); - if(injector3StartAngle > CRANK_ANGLE_MAX) {injector3StartAngle -= CRANK_ANGLE_MAX;} + if(injector3StartAngle > CRANK_ANGLE_MAX_INJ) {injector3StartAngle -= CRANK_ANGLE_MAX_INJ;} injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree )); - if(injector4StartAngle > CRANK_ANGLE_MAX) {injector4StartAngle -= CRANK_ANGLE_MAX;} + if(injector4StartAngle > CRANK_ANGLE_MAX_INJ) {injector4StartAngle -= CRANK_ANGLE_MAX_INJ;} break; //Will hit the default case on 1 cylinder or >8 cylinders. Do nothing in these cases default: @@ -1065,45 +1097,53 @@ void loop() //Calculate start angle for each channel //1 cylinder (Everyone gets this) - ignition1StartAngle = CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; // 360 - desired advance angle - number of degrees the dwell will take - if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX;} + ignition1StartAngle = CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; // 360 - desired advance angle - number of degrees the dwell will take + if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX_IGN;} //This test for more cylinders and do the same thing switch (configPage1.nCylinders) { //2 cylinders case 2: - ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition2StartAngle > CRANK_ANGLE_MAX) {ignition2StartAngle -= CRANK_ANGLE_MAX;} + ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;} break; //3 cylinders case 3: - ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition2StartAngle > CRANK_ANGLE_MAX) {ignition2StartAngle -= CRANK_ANGLE_MAX;} + ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;} ignition3StartAngle = channel3IgnDegrees + 360 - currentStatus.advance - dwellAngle; - if(ignition3StartAngle > CRANK_ANGLE_MAX) {ignition3StartAngle -= CRANK_ANGLE_MAX;} + if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;} break; //4 cylinders case 4: - ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition2StartAngle > CRANK_ANGLE_MAX) {ignition2StartAngle -= CRANK_ANGLE_MAX;} - if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX;} + ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;} + if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;} + + if(configPage2.sparkMode == IGN_MODE_SEQUENTIAL) + { + ignition3StartAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;} + ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; + if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;} + } break; //6 cylinders case 6: - ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition2StartAngle > CRANK_ANGLE_MAX) {ignition2StartAngle -= CRANK_ANGLE_MAX;} - ignition3StartAngle = channel3IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition3StartAngle > CRANK_ANGLE_MAX) {ignition3StartAngle -= CRANK_ANGLE_MAX;} + ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;} + ignition3StartAngle = channel3IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;} break; //8 cylinders case 8: - ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition2StartAngle > CRANK_ANGLE_MAX) {ignition2StartAngle -= CRANK_ANGLE_MAX;} + ignition2StartAngle = channel2IgnDegrees + CRANK_ANGLE_MAX_IGN - currentStatus.advance - dwellAngle; + if(ignition2StartAngle > CRANK_ANGLE_MAX_IGN) {ignition2StartAngle -= CRANK_ANGLE_MAX_IGN;} ignition3StartAngle = channel3IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition3StartAngle > CRANK_ANGLE_MAX) {ignition3StartAngle -= CRANK_ANGLE_MAX;} + if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;} ignition4StartAngle = channel4IgnDegrees + CRANK_ANGLE_MAX - currentStatus.advance - dwellAngle; - if(ignition4StartAngle > CRANK_ANGLE_MAX) {ignition4StartAngle -= CRANK_ANGLE_MAX;} + if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;} break; //Will hit the default case on 1 cylinder or >8 cylinders. Do nothing in these cases @@ -1119,13 +1159,14 @@ void loop() //Determine the current crank angle int crankAngle = getCrankAngle(timePerDegree); + if (crankAngle > CRANK_ANGLE_MAX_INJ ) { crankAngle -= 360; } if (fuelOn && currentStatus.PW > 0 && !BIT_CHECK(currentStatus.squirt, BIT_SQUIRT_BOOSTCUT)) { - if (injector1StartAngle <= crankAngle && fuelSchedule1.schedulesSet == 0) { injector1StartAngle += 360; } + if (injector1StartAngle <= crankAngle && fuelSchedule1.schedulesSet == 0) { injector1StartAngle += CRANK_ANGLE_MAX_INJ; } if (injector1StartAngle > crankAngle) { - if (configPage1.injLayout == 1) + if (configPage1.injLayout == INJ_SEMISEQUENTIAL) { setFuelSchedule1(openInjector1and4, ((unsigned long)(injector1StartAngle - crankAngle) * (unsigned long)timePerDegree), @@ -1157,10 +1198,10 @@ void loop() if(channel2InjEnabled) { tempCrankAngle = crankAngle - channel2InjDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; } tempStartAngle = injector2StartAngle - channel2InjDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } - if (tempStartAngle <= tempCrankAngle && fuelSchedule2.schedulesSet == 0) { tempStartAngle += 360; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } + if (tempStartAngle <= tempCrankAngle && fuelSchedule2.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } if ( tempStartAngle > tempCrankAngle ) { if (configPage1.injLayout == 1) @@ -1185,10 +1226,10 @@ void loop() if(channel3InjEnabled) { tempCrankAngle = crankAngle - channel3InjDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; } tempStartAngle = injector3StartAngle - channel3InjDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } - if (tempStartAngle <= tempCrankAngle && fuelSchedule3.schedulesSet == 0) { tempStartAngle += 360; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } + if (tempStartAngle <= tempCrankAngle && fuelSchedule3.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } if ( tempStartAngle > tempCrankAngle ) { setFuelSchedule3(openInjector3, @@ -1202,10 +1243,10 @@ void loop() if(channel4InjEnabled) { tempCrankAngle = crankAngle - channel4InjDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; } tempStartAngle = injector4StartAngle - channel4InjDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } - if (tempStartAngle <= tempCrankAngle && fuelSchedule4.schedulesSet == 0) { tempStartAngle += 360; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } + if (tempStartAngle <= tempCrankAngle && fuelSchedule4.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } if ( tempStartAngle > tempCrankAngle ) { setFuelSchedule4(openInjector4, @@ -1219,10 +1260,10 @@ void loop() if(channel5InjEnabled) { tempCrankAngle = crankAngle - channel5InjDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; } tempStartAngle = injector5StartAngle - channel5InjDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } - if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += 360; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } + if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; } if ( tempStartAngle > tempCrankAngle ) { setFuelSchedule5(openInjector5, @@ -1236,14 +1277,15 @@ void loop() //*********************************************************************************************** //| BEGIN IGNITION SCHEDULES //Likewise for the ignition - //Perform an initial check to see if the ignition is turned on (Ignition only turns on after a preset number of cranking revolutions and: - //Check for hard cut rev limit (If we're above the hardcut limit, we simply don't set a spark schedule) - //crankAngle = getCrankAngle(timePerDegree); //Refresh with the latest crank angle + crankAngle = getCrankAngle(timePerDegree); //Refresh with the latest crank angle + if (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= 360; } //fixedCrankingOverride is used to extend the dwell during cranking so that the decoder can trigger the spark upon seeing a certain tooth. Currently only available on the basic distributor and 4g63 decoders. if ( configPage2.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) { fixedCrankingOverride = currentStatus.dwell; } else { fixedCrankingOverride = 0; } - + + //Perform an initial check to see if the ignition is turned on (Ignition only turns on after a preset number of cranking revolutions and: + //Check for hard cut rev limit (If we're above the hardcut limit, we simply don't set a spark schedule) if(ignitionOn && !currentStatus.launchingHard && !BIT_CHECK(currentStatus.spark, BIT_SPARK_BOOSTCUT) && !BIT_CHECK(currentStatus.spark, BIT_SPARK_HRDLIM)) { @@ -1266,9 +1308,9 @@ void loop() } tempCrankAngle = crankAngle - channel2IgnDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; } tempStartAngle = ignition2StartAngle - channel2IgnDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; } //if ( (tempStartAngle > tempCrankAngle) && ign2LastRev != startRevolutions) //if ( ign2LastRev != startRevolutions ) { @@ -1287,9 +1329,9 @@ void loop() } tempCrankAngle = crankAngle - channel3IgnDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; } tempStartAngle = ignition3StartAngle - channel3IgnDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; } //if (tempStartAngle > tempCrankAngle) { long ignition3StartTime = 0; @@ -1307,9 +1349,9 @@ void loop() } tempCrankAngle = crankAngle - channel4IgnDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; } tempStartAngle = ignition4StartAngle - channel4IgnDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; } //if (tempStartAngle > tempCrankAngle) { @@ -1328,9 +1370,9 @@ void loop() } tempCrankAngle = crankAngle - channel5IgnDegrees; - if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; } + if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; } tempStartAngle = ignition5StartAngle - channel5IgnDegrees; - if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; } + if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; } //if (tempStartAngle > tempCrankAngle) {