Dwell error correction (#1049)

* Initial work on dwell error correction

* Fix error message in TS

* Add averaging to schedules 5-8

* Cleanup warning

* Final cleanup and comments
This commit is contained in:
Josh Stewart 2023-05-22 13:37:40 +10:00 committed by GitHub
parent 72dd807fb3
commit 1502b6ff88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 205 additions and 160 deletions

View File

@ -602,7 +602,8 @@ page = 4
vvt2CL0DutyAng = scalar, S16, 121, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes) vvt2CL0DutyAng = scalar, S16, 121, "deg", 1.0, 0.0, -360.0, 360.0, 0 ; * ( 2 bytes)
vvt2PWMdir = bits, U08, 123, [0:0], "Advance", "Retard" vvt2PWMdir = bits, U08, 123, [0:0], "Advance", "Retard"
inj4CylPairing = bits, U08, 123, [1:2], "1+3 & 2+4", "1+4 & 2+3", "INVALID", "INVALID" inj4CylPairing = bits, U08, 123, [1:2], "1+3 & 2+4", "1+4 & 2+3", "INVALID", "INVALID"
unusedBits4_123 = bits, U08, 123, [3:7] dwellErrCorrect = bits, U08, 123, [3:3], "Off", "On"
unusedBits4_123 = bits, U08, 123, [4:7]
ANGLEFILTER_VVT = scalar, U08, 124, "%", 1.0, 0.0, 0, 100, 0 ANGLEFILTER_VVT = scalar, U08, 124, "%", 1.0, 0.0, 0, 100, 0
FILTER_FLEX = scalar, U08, 125, "%", 1.0, 0.0, 0, 240, 0 FILTER_FLEX = scalar, U08, 125, "%", 1.0, 0.0, 0, 240, 0
@ -1683,6 +1684,7 @@ page = 15
defaultValue = useTachoSweep, 0 defaultValue = useTachoSweep, 0
defaultValue = tachoSweepMaxRPM, 6000 defaultValue = tachoSweepMaxRPM, 6000
defaultValue = perToothIgn, 0 defaultValue = perToothIgn, 0
defaultValue = dwellErrCorrect, 0
defaultValue = resetControlPin, 0 defaultValue = resetControlPin, 0
;Default ADC filter values ;Default ADC filter values
@ -2025,6 +2027,8 @@ menuDialog = main
sparkDur = "The duration of the spark at full dwell. Typically around 1ms" sparkDur = "The duration of the spark at full dwell. Typically around 1ms"
fixAngEnable = "If enabled, timing will be locked/fixed and the ignition map will be ignored. Note that this value will be overridden by the fixed cranking value when cranking" fixAngEnable = "If enabled, timing will be locked/fixed and the ignition map will be ignored. Note that this value will be overridden by the fixed cranking value when cranking"
FixAng = "Timing will be locked at this value if the above is enabled" FixAng = "Timing will be locked at this value if the above is enabled"
perToothIgn = "This ignition mode works by adjusting in progress ignition events each time a new RPM trigger pulse is received. This can improve timing accuracy significantly where supported."
dwellErrCorrect = "A basic closed loop adjustment will be made to the dwell time to account for variations due to accel/decel. This is generally only needed on lower resolution trigger arrangements"
crankRPM = "The cranking RPM threshold. When RPM is lower than this value (and above 0) the system will be considered to be cranking" crankRPM = "The cranking RPM threshold. When RPM is lower than this value (and above 0) the system will be considered to be cranking"
tpsflood = "Keep throttle over this value to disable the priming pulse and cranking fuel. Used to prevent flood or clear already flooded engine" tpsflood = "Keep throttle over this value to disable the priming pulse and cranking fuel. Used to prevent flood or clear already flooded engine"
@ -2850,10 +2854,12 @@ menuDialog = main
field = "Fixed Angle", FixAng, { fixAngEnable } field = "Fixed Angle", FixAng, { fixAngEnable }
field = "#Note: During cranking the fixed/locked timing angle is overridden by the Cranking advance angle value above" field = "#Note: During cranking the fixed/locked timing angle is overridden by the Cranking advance angle value above"
dialog = newIgnitionMode, "New Ignition Mode" dialog = newIgnitionMode, "Per tooth ignition events"
field = "This option is currently will improve accuracy on most compatible triggers" field = "This option is will generally improve accuracy on most compatible triggers"
field = "However if timing issues are encountered, please disable this" field = "However if timing issues are encountered, please disable this"
field = "Use new ignition mode", perToothIgn field = "Enable per tooth timing", perToothIgn
field = "Dwell error correction", dwellErrCorrect,{ perToothIgn }
dialog = sparkSettings,"Spark Settings",4 dialog = sparkSettings,"Spark Settings",4
topicHelp = "https://wiki.speeduino.com/en/configuration/Spark_Settings" topicHelp = "https://wiki.speeduino.com/en/configuration/Spark_Settings"
@ -2863,7 +2869,7 @@ menuDialog = main
field = "Cranking advance Angle", CrankAng field = "Cranking advance Angle", CrankAng
field = "Spark Outputs triggers", IgInv field = "Spark Outputs triggers", IgInv
panel = lockSparkSettings panel = lockSparkSettings
panel = newIgnitionMode, {}, {TrigPattern == 0 || TrigPattern == 1 || TrigPattern == 2 || TrigPattern == 3 || TrigPattern == 4 || TrigPattern == 9 || TrigPattern == 12 || TrigPattern == 13 || TrigPattern == 16 || TrigPattern == 18 || TrigPattern == 19 || TrigPattern == 22 || TrigPattern == 24} ;Only works for missing tooth, distributor, dual wheel, GM 7X, 4g63, Miata 99-05, nissan 360, Subaru 6/7, 420a, weber-marelli, NGC Renix, panel = newIgnitionMode, { 1 }, {TrigPattern == 0 || TrigPattern == 1 || TrigPattern == 2 || TrigPattern == 3 || TrigPattern == 4 || TrigPattern == 9 || TrigPattern == 12 || TrigPattern == 13 || TrigPattern == 16 || TrigPattern == 18 || TrigPattern == 19 || TrigPattern == 22 || TrigPattern == 24} ;Only works for missing tooth, distributor, dual wheel, GM 7X, 4g63, Miata 99-05, nissan 360, Subaru 6/7, 420a, weber-marelli, NGC Renix,
dialog = dwellSettings, "Dwell Settings", 4 dialog = dwellSettings, "Dwell Settings", 4
topicHelp = "https://wiki.speeduino.com/en/configuration/Dwell" topicHelp = "https://wiki.speeduino.com/en/configuration/Dwell"
@ -4932,7 +4938,8 @@ cmdVSSratio6 = "E\x99\x06"
advanceGauge = advance, "Advance (Current)", "deg", 50, -10, 0, 0, 35, 45, 0, 0 advanceGauge = advance, "Advance (Current)", "deg", 50, -10, 0, 0, 35, 45, 0, 0
advance1Gauge = advance1, "Advance1 (Spark Table 1)", "deg",50, -10, 0, 0, 35, 45, 0, 0 advance1Gauge = advance1, "Advance1 (Spark Table 1)", "deg",50, -10, 0, 0, 35, 45, 0, 0
advance2Gauge = advance2, "Advance2 (Spark Table 2)", "deg",50, -10, 0, 0, 35, 45, 0, 0 advance2Gauge = advance2, "Advance2 (Spark Table 2)", "deg",50, -10, 0, 0, 35, 45, 0, 0
dwellGauge = dwell, "Ign Dwell", "mSec", 0, 35.0, 1.0, 1.2, 20, 25, 3, 3 dwellGauge = dwell, "Dwell (Requested)", "mSec", 0, 35.0, 1.0, 1.2, 20, 25, 3, 3
dwellActualGauge = dwellActual, "Dwell (Measured)", "mSec", 0, 35.0, 1.0, 1.2, 20, 25, 3, 3
boostTargetGauge = boostTarget, "Target Boost", "kPa", 0, {maphigh}, 0, 20, {mapwarn}, {mapdang}, 0, 0 boostTargetGauge = boostTarget, "Target Boost", "kPa", 0, {maphigh}, 0, 20, {mapwarn}, {mapdang}, 0, 0
boostDutyGauge = boostDuty, "Boost Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1 boostDutyGauge = boostDuty, "Boost Duty Cycle", "%", 0, 100, -1, -1, 101, 110, 1, 1
afrTargetGauge = afrTarget, "Target AFR", "", 7, 25, {12 / 14.7 * stoich}, {13 / 14.7 * stoich}, {15 / 14.7 * stoich}, {16 / 14.7 * stoich}, 2, 2 afrTargetGauge = afrTarget, "Target AFR", "", 7, 25, {12 / 14.7 * stoich}, {13 / 14.7 * stoich}, {15 / 14.7 * stoich}, {16 / 14.7 * stoich}, 2, 2
@ -5102,7 +5109,7 @@ cmdVSSratio6 = "E\x99\x06"
; you change it. ; you change it.
ochGetCommand = "r\$tsCanId\x30%2o%2c" ochGetCommand = "r\$tsCanId\x30%2o%2c"
ochBlockSize = 125 ochBlockSize = 127
secl = scalar, U08, 0, "sec", 1.000, 0.000 secl = scalar, U08, 0, "sec", 1.000, 0.000
status1 = scalar, U08, 1, "bits", 1.000, 0.000 status1 = scalar, U08, 1, "bits", 1.000, 0.000
@ -5256,6 +5263,7 @@ cmdVSSratio6 = "E\x99\x06"
airConCLTLockout = bits, U08, 124, [5:5] airConCLTLockout = bits, U08, 124, [5:5]
airConFanStatus = bits, U08, 124, [6:6] airConFanStatus = bits, U08, 124, [6:6]
airConUnusedBits = bits, U08, 124, [7:7] airConUnusedBits = bits, U08, 124, [7:7]
dwellActual = scalar, U16, 125, "ms", 0.001, 0.000
;sd_filenum = scalar, U16, 125, "", 1, 0 ;sd_filenum = scalar, U16, 125, "", 1, 0
;sd_error = scalar, U08, 127, "", 1, 0 ;sd_error = scalar, U08, 127, "", 1, 0
;sd_phase = scalar, U08, 128, "", 1, 0 ;sd_phase = scalar, U08, 128, "", 1, 0
@ -5400,7 +5408,8 @@ cmdVSSratio6 = "E\x99\x06"
entry = dutyCycle, "DutyCycle1", float, "%.1f" entry = dutyCycle, "DutyCycle1", float, "%.1f"
entry = TPSdot, "TPS DOT", int, "%d", { aeMode == 0 } entry = TPSdot, "TPS DOT", int, "%d", { aeMode == 0 }
entry = advance, "Advance (Current)",int, "%d" entry = advance, "Advance (Current)",int, "%d"
entry = dwell, "Dwell", float, "%.1f" entry = dwell, "Dwell", float, "%.3f"
entry = dwellActual, "Dwell (Measured)", float, "%.3f", { perToothIgn }
entry = batteryVoltage, "Battery V", float, "%.1f" entry = batteryVoltage, "Battery V", float, "%.1f"
entry = rpmDOT, "rpm/s", int, "%d" entry = rpmDOT, "rpm/s", int, "%d"
entry = flex, "Eth %", int, "%d", { flexEnabled } entry = flex, "Eth %", int, "%d", { flexEnabled }

View File

@ -942,26 +942,45 @@ uint16_t correctionsDwell(uint16_t dwell)
{ {
uint16_t tempDwell = dwell; uint16_t tempDwell = dwell;
uint16_t sparkDur_uS = (configPage4.sparkDur * 100); //Spark duration is in mS*10. Multiple it by 100 to get spark duration in uS uint16_t sparkDur_uS = (configPage4.sparkDur * 100); //Spark duration is in mS*10. Multiple it by 100 to get spark duration in uS
if(currentStatus.actualDwell == 0) { currentStatus.actualDwell = tempDwell; } //Initialise the actualDwell value if this is the first time being called
//**************************************************************************************************************************
//Pull battery voltage based dwell correction and apply if needed //Pull battery voltage based dwell correction and apply if needed
currentStatus.dwellCorrection = table2D_getValue(&dwellVCorrectionTable, currentStatus.battery10); currentStatus.dwellCorrection = table2D_getValue(&dwellVCorrectionTable, currentStatus.battery10);
if (currentStatus.dwellCorrection != 100) { tempDwell = div100(dwell) * currentStatus.dwellCorrection; } if (currentStatus.dwellCorrection != 100) { tempDwell = div100(dwell) * currentStatus.dwellCorrection; }
//Dwell limiter
//**************************************************************************************************************************
//Dwell error correction is a basic closed loop to keep the dwell time consistent even when adjusting its end time for the per tooth timing.
//This is mostly of benefit to low resolution triggers at low rpm (<1500)
if( (configPage2.perToothIgn == true) && (configPage4.dwellErrCorrect == 1) )
{
int16_t error = tempDwell - currentStatus.actualDwell;
if(tempDwell > INT16_MAX) { tempDwell = INT16_MAX; } //Prevent overflow when casting to signed int
if(error > ((int16_t)tempDwell / 2)) { error += error; } //Double correction amount if actual dwell is less than 50% of the requested dwell
if(error > 0) { tempDwell += error; }
}
//**************************************************************************************************************************
/*
Dwell limiter - If the total required dwell time per revolution is longer than the maximum time available at the current RPM, reduce dwell. This can occur if there are multiple sparks per revolution
This only times this can occur are:
1. Single channel spark mode where there will be nCylinders/2 sparks per revolution
2. Rotary ignition in wasted spark configuration (FC/FD), results in 2 pulses per rev. RX-8 is fully sequential resulting in 1 pulse, so not required
*/
uint16_t dwellPerRevolution = tempDwell + sparkDur_uS; uint16_t dwellPerRevolution = tempDwell + sparkDur_uS;
int8_t pulsesPerRevolution = 1; int8_t pulsesPerRevolution = 1;
//Single channel spark mode is the only time there will be more than 1 pulse per revolution on any given output
//For rotary ignition this also holds true in wasted spark configuration (FC/FD) resulting in 2 pulses. RX-8 however is fully sequential resulting in 1 pulse
if( ( (configPage4.sparkMode == IGN_MODE_SINGLE) || ((configPage4.sparkMode == IGN_MODE_ROTARY) && (configPage10.rotaryType != ROTARY_IGN_RX8)) ) && (configPage2.nCylinders > 1) ) //No point in running this for 1 cylinder engines if( ( (configPage4.sparkMode == IGN_MODE_SINGLE) || ((configPage4.sparkMode == IGN_MODE_ROTARY) && (configPage10.rotaryType != ROTARY_IGN_RX8)) ) && (configPage2.nCylinders > 1) ) //No point in running this for 1 cylinder engines
{ {
pulsesPerRevolution = (configPage2.nCylinders >> 1); pulsesPerRevolution = (configPage2.nCylinders >> 1);
dwellPerRevolution = dwellPerRevolution * pulsesPerRevolution; dwellPerRevolution = dwellPerRevolution * pulsesPerRevolution;
} }
if(dwellPerRevolution > revolutionTime) if(dwellPerRevolution > revolutionTime)
{ {
//Possibly need some method of reducing spark duration here as well, but this is a start //Possibly need some method of reducing spark duration here as well, but this is a start
uint16_t adjustedSparkDur = (sparkDur_uS * revolutionTime) / dwellPerRevolution; uint16_t adjustedSparkDur = (sparkDur_uS * revolutionTime) / dwellPerRevolution;
tempDwell = (revolutionTime / pulsesPerRevolution) - adjustedSparkDur; tempDwell = (revolutionTime / pulsesPerRevolution) - adjustedSparkDur;
} }
return tempDwell; return tempDwell;
} }

View File

@ -1082,7 +1082,7 @@ void triggerSec_BasicDistributor(void) { return; } //Not required
uint16_t getRPM_BasicDistributor(void) uint16_t getRPM_BasicDistributor(void)
{ {
uint16_t tempRPM; uint16_t tempRPM;
if( currentStatus.RPM < currentStatus.crankRPM) if( currentStatus.RPM < currentStatus.crankRPM || currentStatus.RPM < 1500)
{ {
tempRPM = crankingGetRPM(triggerActualTeeth, 720); tempRPM = crankingGetRPM(triggerActualTeeth, 720);
} }

View File

@ -661,6 +661,7 @@ struct statuses {
int O2ADC; int O2ADC;
int O2_2ADC; int O2_2ADC;
int dwell; ///< dwell (coil primary winding/circuit on) time (in ms * 10 ? See @ref correctionsDwell) int dwell; ///< dwell (coil primary winding/circuit on) time (in ms * 10 ? See @ref correctionsDwell)
volatile int16_t actualDwell; ///< actual dwell time if new ignition mode is used (in uS)
byte dwellCorrection; /**< The amount of correction being applied to the dwell time (in unit ...). */ byte dwellCorrection; /**< The amount of correction being applied to the dwell time (in unit ...). */
byte battery10; /**< The current BRV in volts (multiplied by 10. Eg 12.5V = 125) */ byte battery10; /**< The current BRV in volts (multiplied by 10. Eg 12.5V = 125) */
int8_t advance; /**< The current advance value being used in the spark calculation. Can be the same as advance1 or advance2, or a calculated value of both */ int8_t advance; /**< The current advance value being used in the spark calculation. Can be the same as advance1 or advance2, or a calculated value of both */
@ -1010,7 +1011,8 @@ struct config4 {
int16_t vvt2CL0DutyAng; int16_t vvt2CL0DutyAng;
byte vvt2PWMdir : 1; byte vvt2PWMdir : 1;
byte inj4cylPairing : 2; byte inj4cylPairing : 2;
byte unusedBits4 : 5; byte dwellErrCorrect : 1;
byte unusedBits4 : 4;
byte ANGLEFILTER_VVT; byte ANGLEFILTER_VVT;
byte FILTER_FLEX; byte FILTER_FLEX;
byte vvtMinClt; byte vvtMinClt;

View File

@ -169,6 +169,8 @@ byte getTSLogEntry(uint16_t byteNum)
case 122: statusValue = highByte(currentStatus.EMAP); break; case 122: statusValue = highByte(currentStatus.EMAP); break;
case 123: statusValue = currentStatus.fanDuty; break; case 123: statusValue = currentStatus.fanDuty; break;
case 124: statusValue = currentStatus.airConStatus; break; case 124: statusValue = currentStatus.airConStatus; break;
case 125: statusValue = lowByte(currentStatus.actualDwell); break;
case 126: statusValue = highByte(currentStatus.actualDwell); break;
} }
return statusValue; return statusValue;
@ -291,6 +293,7 @@ int16_t getReadableLogEntry(uint16_t logIndex)
case 87: statusValue = currentStatus.EMAP; break; case 87: statusValue = currentStatus.EMAP; break;
case 88: statusValue = currentStatus.fanDuty; break; case 88: statusValue = currentStatus.fanDuty; break;
case 89: statusValue = currentStatus.airConStatus; break; case 89: statusValue = currentStatus.airConStatus; break;
case 90: statusValue = currentStatus.actualDwell; break;
} }
return statusValue; return statusValue;

View File

@ -46,6 +46,10 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
#define USE_IGN_REFRESH #define USE_IGN_REFRESH
#define IGNITION_REFRESH_THRESHOLD 30 //Time in uS that the refresh functions will check to ensure there is enough time before changing the end compare #define IGNITION_REFRESH_THRESHOLD 30 //Time in uS that the refresh functions will check to ensure there is enough time before changing the end compare
#define DWELL_AVERAGE_ALPHA 30
#define DWELL_AVERAGE(input) (((long)input * (256 - DWELL_AVERAGE_ALPHA) + ((long)currentStatus.actualDwell * DWELL_AVERAGE_ALPHA))) >> 8
//#define DWELL_AVERAGE(input) (currentStatus.dwell) //Can be use to disable the above for testing
extern void (*inj1StartFunction)(void); extern void (*inj1StartFunction)(void);
extern void (*inj1EndFunction)(void); extern void (*inj1EndFunction)(void);
extern void (*inj2StartFunction)(void); extern void (*inj2StartFunction)(void);

View File

@ -1199,6 +1199,7 @@ inline void ignitionSchedule1Interrupt(void)
ignitionSchedule1.schedulesSet = 0; ignitionSchedule1.schedulesSet = 0;
ignitionSchedule1.endScheduleSetByDecoder = false; ignitionSchedule1.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule1.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule1.hasNextSchedule == true) if(ignitionSchedule1.hasNextSchedule == true)
@ -1240,6 +1241,7 @@ inline void ignitionSchedule2Interrupt(void)
ignitionSchedule2.schedulesSet = 0; ignitionSchedule2.schedulesSet = 0;
ignitionSchedule2.endScheduleSetByDecoder = false; ignitionSchedule2.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule2.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule2.hasNextSchedule == true) if(ignitionSchedule2.hasNextSchedule == true)
@ -1281,6 +1283,7 @@ inline void ignitionSchedule3Interrupt(void)
ignitionSchedule3.schedulesSet = 0; ignitionSchedule3.schedulesSet = 0;
ignitionSchedule3.endScheduleSetByDecoder = false; ignitionSchedule3.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule3.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule3.hasNextSchedule == true) if(ignitionSchedule3.hasNextSchedule == true)
@ -1322,6 +1325,7 @@ inline void ignitionSchedule4Interrupt(void)
ignitionSchedule4.schedulesSet = 0; ignitionSchedule4.schedulesSet = 0;
ignitionSchedule4.endScheduleSetByDecoder = false; ignitionSchedule4.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule4.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule4.hasNextSchedule == true) if(ignitionSchedule4.hasNextSchedule == true)
@ -1363,6 +1367,7 @@ inline void ignitionSchedule5Interrupt(void)
ignitionSchedule5.schedulesSet = 0; ignitionSchedule5.schedulesSet = 0;
ignitionSchedule5.endScheduleSetByDecoder = false; ignitionSchedule5.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule5.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule5.hasNextSchedule == true) if(ignitionSchedule5.hasNextSchedule == true)
@ -1404,6 +1409,7 @@ inline void ignitionSchedule6Interrupt(void)
ignitionSchedule6.schedulesSet = 0; ignitionSchedule6.schedulesSet = 0;
ignitionSchedule6.endScheduleSetByDecoder = false; ignitionSchedule6.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule6.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule6.hasNextSchedule == true) if(ignitionSchedule6.hasNextSchedule == true)
@ -1445,6 +1451,7 @@ inline void ignitionSchedule7Interrupt(void)
ignitionSchedule7.schedulesSet = 0; ignitionSchedule7.schedulesSet = 0;
ignitionSchedule7.endScheduleSetByDecoder = false; ignitionSchedule7.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule7.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule7.hasNextSchedule == true) if(ignitionSchedule7.hasNextSchedule == true)
@ -1486,6 +1493,7 @@ inline void ignitionSchedule8Interrupt(void)
ignitionSchedule8.schedulesSet = 0; ignitionSchedule8.schedulesSet = 0;
ignitionSchedule8.endScheduleSetByDecoder = false; ignitionSchedule8.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the ignition counter ignitionCount += 1; //Increment the ignition counter
currentStatus.actualDwell = DWELL_AVERAGE( (micros() - ignitionSchedule8.startTime) );
//If there is a next schedule queued up, activate it //If there is a next schedule queued up, activate it
if(ignitionSchedule8.hasNextSchedule == true) if(ignitionSchedule8.hasNextSchedule == true)