Low RPM timing fix

This commit is contained in:
Josh Stewart 2015-08-23 11:36:18 +10:00
parent f4968d8791
commit 60ffd8366f
3 changed files with 27 additions and 14 deletions

View File

@ -196,7 +196,7 @@ page = 3
page = 4
TrigAng = scalar, S16, 0, "Deg", 1, 0, -360, 360, 0
FixAng = scalar, U08, 2, "Deg", 1, 0, 0, 80, 0
CrankAng = scalar, U08, 3, "Deg", 1, -28.4, -10, 80, 0
CrankAng = scalar, U08, 3, "Deg", 1, 0, -10, 80, 0
IgHold = scalar, U08, 4, "", 1, 0, 0, 100, 0
TrigEdge = bits, U08, 5[0:0], "Leading", "Trailing"
TrigSpeed = bits, U08, 5[1:1], "Crank Speed", "Cam Speed"

View File

@ -259,10 +259,12 @@ ISR(TIMER5_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule1
{
if (ignitionSchedule1.Status == PENDING) //Check to see if this schedule is turn on
{
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.StartCallback();
unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule1.duration >> 4);
ign1LastRev = startRevolutions;
//unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule1.duration >> 2); //Divide by 4
OCR5A = absoluteTimeout;
}
@ -278,10 +280,12 @@ ISR(TIMER5_COMPB_vect, ISR_NOBLOCK) //ignitionSchedule2
{
if (ignitionSchedule2.Status == PENDING) //Check to see if this schedule is turn on
{
if ( ign2LastRev == startRevolutions ) { return; }
ignitionSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule2.startTime = currentLoopTime;
ignitionSchedule2.StartCallback();
unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule2.duration >> 4);
ign2LastRev = startRevolutions;
//unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule2.duration >> 2); //Divide by 4
OCR5B = absoluteTimeout;
}
@ -297,10 +301,12 @@ ISR(TIMER5_COMPC_vect, ISR_NOBLOCK) //ignitionSchedule3
{
if (ignitionSchedule3.Status == PENDING) //Check to see if this schedule is turn on
{
if ( ign3LastRev == startRevolutions ) { return; }
ignitionSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule3.startTime = currentLoopTime;
ignitionSchedule3.StartCallback();
unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule2.duration >> 4);
ign3LastRev = startRevolutions;
//unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule3.duration >> 2); //Divide by 4
OCR5C = absoluteTimeout;
}
@ -316,11 +322,13 @@ ISR(TIMER4_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule4
{
if (ignitionSchedule4.Status == PENDING) //Check to see if this schedule is turn on
{
if ( ign4LastRev == startRevolutions ) { return; }
ignitionSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule4.startTime = currentLoopTime;
ignitionSchedule4.StartCallback();
//unsigned int absoluteTimeout = TCNT5 + (ignitionSchedule2.duration / 16);
unsigned int absoluteTimeout = TCNT4 + (ignitionSchedule4.duration >> 4); //Divide by 16
ign4LastRev = startRevolutions;
OCR4A = absoluteTimeout;
}
else if (ignitionSchedule4.Status == RUNNING)
@ -328,6 +336,6 @@ ISR(TIMER4_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule4
ignitionSchedule4.Status = OFF; //Turn off the schedule
ignitionSchedule4.EndCallback();
ignitionCount += 1; //Increment the igintion counter
TIMSK4 &= ~(1 << OCIE4A); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
TIMSK4 &= ~(1 << OCIE4A); //Turn off this output compare unit (This simply writes 0 to the OCIE4A bit of TIMSK4)
}
}

View File

@ -53,6 +53,10 @@ int req_fuel_uS, inj_opentime_uS;
#define MAX_RPM 10000 //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
volatile byte startRevolutions = 0; //A counter for how many revolutions have been completed since sync was achieved.
volatile byte ign1LastRev;
volatile byte ign2LastRev;
volatile byte ign3LastRev;
volatile byte ign4LastRev;
bool ignitionOn = false; //The current state of the ignition system
bool fuelOn = false; //The current state of the ignition system
bool fuelPumpOn = false; //The current status of the fuel pump
@ -527,21 +531,19 @@ void loop()
//Speed Density
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value
currentStatus.PW = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS);
if (configPage2.FixAng == 0) //Check whether the user has set a fixed timing angle
{ currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); } //As above, but for ignition advance
else
{ currentStatus.advance = configPage2.FixAng; }
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance
}
else
{
//Alpha-N
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.TPS, currentStatus.RPM); //Perform lookup into fuel map for RPM vs TPS value
currentStatus.PW = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS)
if (configPage2.FixAng == 0) //Check whether the user has set a fixed timing angle
{ currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); } //As above, but for ignition advance
else
{ currentStatus.advance = configPage2.FixAng; }
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); //As above, but for ignition advance
}
//Check for fixed ignition angles
if (configPage2.FixAng != 0) { currentStatus.advance = configPage2.FixAng; } //Check whether the user has set a fixed timing angle
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { currentStatus.advance = configPage2.CrankAng; } //Use the fixed cranking ignition angle
int injector1StartAngle = 0;
int injector2StartAngle = 0;
@ -559,9 +561,12 @@ void loop()
//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
timePerDegree = ldiv( 166666L, currentStatus.RPM ).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 / )
//Check that the duty cycle of the chosen pulsewidth isn't too high
unsigned int 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 (currentStatus.PW > pwLimit) { currentStatus.PW = pwLimit; }
//Check that the duty cycle of the chosen pulsewidth isn't too high. This is disabled at cranking
if( !BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
{
unsigned int 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 (currentStatus.PW > pwLimit) { currentStatus.PW = pwLimit; }
}
//***********************************************************************************************
@ -773,7 +778,7 @@ void loop()
if(ignitionOn && (currentStatus.RPM < ((unsigned int)(configPage2.HardRevLim) * 100) ))
{
if ( (ignition1StartAngle > crankAngle) )
{
{
setIgnitionSchedule1(beginCoil1Charge,
((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
currentStatus.dwell,