Potential fix for erratic spark behaviour
This commit is contained in:
parent
2d4ce39605
commit
c779f42d9e
|
@ -121,7 +121,9 @@ int getCrankAngle_missingTooth(int timePerDegree)
|
|||
int crankAngle = (tempToothCurrentCount - 1) * triggerToothAngle + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
|
||||
crankAngle += ( (micros() - tempToothLastToothTime) / timePerDegree); //Estimate the number of degrees travelled since the last tooth
|
||||
|
||||
if (crankAngle > 360) { crankAngle -= 360; }
|
||||
if (crankAngle >= 720) { crankAngle -= 720; }
|
||||
else if (crankAngle > 360) { crankAngle -= 360; }
|
||||
if (crankAngle < 0) { crankAngle += 360; }
|
||||
|
||||
return crankAngle;
|
||||
}
|
||||
|
|
|
@ -122,13 +122,9 @@ void setIgnitionSchedule1(void (*startCallback)(), unsigned long timeout, unsign
|
|||
if(ignitionSchedule1.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
|
||||
|
||||
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
|
||||
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
|
||||
//unsigned int absoluteTimeout = TCNT5 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
|
||||
//unsigned char sreg;
|
||||
//sreg = SREG;
|
||||
//noInterrupts();
|
||||
//unsigned int absoluteTimeout = TCNT5 + (timeout >> 4); //As above, but with bit shift instead of / 16
|
||||
OCR5A = TCNT5 + (timeout >> 2); //Divid timeout by 4 (Each tick represent 4uS)
|
||||
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
|
||||
if (timeout > 262140) { return; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65525), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
OCR5A = TCNT5 + (timeout >> 2); //Divide timeout by 4 (Each tick represent 4uS)
|
||||
|
||||
//SREG = sreg;
|
||||
ignitionSchedule1.duration = duration;
|
||||
|
@ -262,11 +258,10 @@ ISR(TIMER5_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule1
|
|||
{
|
||||
if (ignitionSchedule1.Status == PENDING) //Check to see if this schedule is turn on
|
||||
{
|
||||
if ( ign1LastRev == startRevolutions ) { return; }
|
||||
//if ( ign1LastRev == startRevolutions ) { return; }
|
||||
ignitionSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule1.startTime = currentLoopTime;
|
||||
ignitionSchedule1.startTime = micros();
|
||||
ignitionSchedule1.StartCallback();
|
||||
//unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule1.duration >> 4);
|
||||
ign1LastRev = startRevolutions;
|
||||
unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule1.duration >> 2); //Divide by 4
|
||||
OCR5A = absoluteTimeout;
|
||||
|
|
|
@ -727,16 +727,17 @@ void loop()
|
|||
int tempCrankAngle;
|
||||
int tempStartAngle;
|
||||
|
||||
//********************************************************
|
||||
//How fast are we going? Need to know how long (uS) it will take to get from one tooth to the next. We then use that to estimate how far we are between the last tooth and the next one
|
||||
//We use a 1st Deriv accleration prediction, but only when there is an even spacing between primary sensor teeth
|
||||
//Any decoder that has uneven spacing has its triggerToothAngle set to 0
|
||||
if(triggerToothAngle > 0 && toothHistoryIndex >= 3 && currentStatus.RPM < 3000 ) //toothHistoryIndex must be greater than or equal to 3 as we need the last 3 entries. Currently this mode only runs below 3000 rpm
|
||||
if(triggerToothAngle > 0 && toothHistoryIndex >= 3 && currentStatus.RPM < 1 ) //toothHistoryIndex must be greater than or equal to 3 as we need the last 3 entries. Currently this mode only runs below 3000 rpm
|
||||
{
|
||||
//Only recalculate deltaV if the tooth has changed since last time
|
||||
//Only recalculate deltaV if the tooth has changed since last time (DeltaV stays the same until the next tooth)
|
||||
if (deltaToothCount != toothCurrentCount)
|
||||
{
|
||||
deltaToothCount = toothCurrentCount;
|
||||
int angle1, angle2; //These represent that crank angles that are travelled for the last 2 pulses
|
||||
int angle1, angle2; //These represent the crank angles that are travelled for the last 2 pulses
|
||||
if(configPage2.TrigPattern == 4)
|
||||
{
|
||||
//Special case for 70/110 pattern on 4g63
|
||||
|
@ -744,14 +745,22 @@ void loop()
|
|||
if (angle2 == 70) { angle1 = 110; }
|
||||
else { angle1 = 70; }
|
||||
}
|
||||
else if(configPage2.TrigPattern == 0)
|
||||
{
|
||||
//Special case for missing tooth decoder where the missing tooth was one of the last 2 seen
|
||||
if(toothCurrentCount == 1) { angle2 = 2*triggerToothAngle; angle1 = triggerToothAngle; }
|
||||
else if(toothCurrentCount == 2) { angle1 = 2*triggerToothAngle; angle2 = triggerToothAngle; }
|
||||
else { angle1 = angle2 = triggerToothAngle; }
|
||||
}
|
||||
else { angle1 = angle2 = triggerToothAngle; }
|
||||
|
||||
long toothDeltaV = (1000000L * angle2 / toothHistory[toothHistoryIndex]) - (1000000L * angle1 / toothHistory[toothHistoryIndex-1]);
|
||||
long toothDeltaT = toothHistory[toothHistoryIndex];
|
||||
long timeToLastTooth = micros() - toothLastToothTime; //Cannot be unsigned
|
||||
|
||||
rpmDelta = (toothDeltaV * timeToLastTooth) / (6 * toothDeltaT);
|
||||
}
|
||||
|
||||
rpmDelta = (toothDeltaV << 10) / (6 * toothDeltaT);
|
||||
}
|
||||
|
||||
|
||||
timePerDegree = ldiv( 166666L, (currentStatus.RPM + rpmDelta)).quot; //There is a small amount of rounding in this calculation, however it is less than 0.001 of a uS (Faster as ldiv than / )
|
||||
}
|
||||
|
@ -977,18 +986,22 @@ void loop()
|
|||
crankAngle = getCrankAngle(timePerDegree); //Refresh with the latest crank angle
|
||||
if(ignitionOn && (currentStatus.RPM < ((unsigned int)(configPage2.HardRevLim) * 100) ))
|
||||
{
|
||||
if ( (ignition1StartAngle > crankAngle) && ign1LastRev != startRevolutions)
|
||||
//if (ign1LastRev != startRevolutions)
|
||||
//if ( (ignition1StartAngle > crankAngle))// && ign1LastRev != startRevolutions)
|
||||
//if ((ignition1StartAngle > crankAngle) == 0)
|
||||
//if ((ignition1StartAngle < crankAngle))
|
||||
{
|
||||
unsigned long ignition1StartTime;
|
||||
long ignition1StartTime;
|
||||
if(ignition1StartAngle > crankAngle) { ignition1StartTime = ((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree); }
|
||||
else { ignition1StartTime = ((unsigned long)(360 - crankAngle + ignition1StartAngle) * (unsigned long)timePerDegree); }
|
||||
else if (ignition1StartAngle < crankAngle) { ignition1StartTime = ((long)(360 - crankAngle + ignition1StartAngle) * (long)timePerDegree); }
|
||||
else { ignition1StartTime = 0; }
|
||||
|
||||
if(ignition1StartTime > 0) {
|
||||
setIgnitionSchedule1(ign1StartFunction,
|
||||
((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
|
||||
ignition1StartTime,
|
||||
currentStatus.dwell,
|
||||
ign1EndFunction
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tempCrankAngle = crankAngle - channel2IgnDegrees;
|
||||
|
|
Loading…
Reference in New Issue