Conclude all scheduler call calculations, adjust scheduler to automatically run an end function after a set duration
This commit is contained in:
parent
f8ccd8ac6d
commit
2e9b01c28e
|
@ -6,9 +6,9 @@
|
||||||
/*
|
/*
|
||||||
Need to calculate the req_fuel figure here, preferably in pre-processor macro
|
Need to calculate the req_fuel figure here, preferably in pre-processor macro
|
||||||
*/
|
*/
|
||||||
#define engineCapacity 100 // In cc
|
#define engineCapacity 148 // In cc
|
||||||
#define engineCylinders 1 // May support more than 1 cyl later. Always will assume 1 injector per cylinder.
|
#define engineCylinders 1 // May support more than 1 cyl later. Always will assume 1 injector per cylinder.
|
||||||
#define engineInjectorSize 100 // In cc/min
|
#define engineInjectorSize 80 // In cc/min
|
||||||
#define engineStoich 14.7 // Stoichiometric ratio of fuel used
|
#define engineStoich 14.7 // Stoichiometric ratio of fuel used
|
||||||
#define engineStrokes 4 //Can be 2 stroke or 4 stroke, any other value will cause problems
|
#define engineStrokes 4 //Can be 2 stroke or 4 stroke, any other value will cause problems
|
||||||
#define engineDwell 3000 //The spark dwell time in uS
|
#define engineDwell 3000 //The spark dwell time in uS
|
||||||
|
@ -111,21 +111,43 @@ void loop()
|
||||||
//Perform lookup into fuel map for RPM vs MAP value
|
//Perform lookup into fuel map for RPM vs MAP value
|
||||||
int VE = getTableValue(fuelTable, MAP, rpm);
|
int VE = getTableValue(fuelTable, MAP, rpm);
|
||||||
//Calculate an injector pulsewidth form the VE
|
//Calculate an injector pulsewidth form the VE
|
||||||
int pulseWidth = PW(req_fuel, VE, MAP, 100, engineInjectorDeadTime); //The 100 here is just a placeholder for any enrichment factors (Cold start, acceleration etc). To add 10% extra fuel, this would be 110
|
unsigned long pulseWidth = PW(req_fuel, VE, MAP, 100, engineInjectorDeadTime); //The 100 here is just a placeholder for any enrichment factors (Cold start, acceleration etc). To add 10% extra fuel, this would be 110
|
||||||
|
|
||||||
//Perform a lookup to get the desired ignition advance
|
//Perform a lookup to get the desired ignition advance
|
||||||
int advance = getTableValue(ignitionTable, MAP, rpm);
|
int ignitionAdvance = getTableValue(ignitionTable, MAP, rpm);
|
||||||
|
|
||||||
//Determine the current crank angle
|
//Determine the current crank angle
|
||||||
int crankAngle = (toothCurrentCount - 1) * triggerToothAngle + triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is from TDC
|
int crankAngle = (toothCurrentCount - 1) * triggerToothAngle + triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is from TDC
|
||||||
if (crankAngle > 360) { crankAngle -= 360; } //Not sure if this is actually required
|
if (crankAngle > 360) { crankAngle -= 360; } //Not sure if this is actually required
|
||||||
|
|
||||||
//Determine next firing angles
|
//How fast are we going? Can possibly work this out from RPM, but I don't think it's going to take a lot of CPU
|
||||||
|
|
||||||
|
|
||||||
//Finally calculate the time (uS) until we reach the firing angles
|
|
||||||
unsigned long timePerDegree = (toothLastToothTime - toothLastMinusOneToothTime) / triggerToothAngle; //The time (uS) it is currently taking to move 1 degree
|
unsigned long timePerDegree = (toothLastToothTime - toothLastMinusOneToothTime) / triggerToothAngle; //The time (uS) it is currently taking to move 1 degree
|
||||||
|
|
||||||
|
//Determine next firing angles
|
||||||
|
int injectorStartAngle = 355 - (pulseWidth / timePerDegree); //This is a bit rough, but is based on the idea that all fuel needs to be delivered before the inlet valve opens. I am using 355 as the point at which the injector MUST be closed by. See http://www.extraefi.co.uk/sequential_fuel.html for more detail
|
||||||
|
int ignitionStartAngle = 360 - ignitionAdvance; //Simple
|
||||||
|
|
||||||
|
|
||||||
|
//Finally calculate the time (uS) until we reach the firing angles and set the schedules
|
||||||
|
//We only need to set the shcedule if we're BEFORE the open angle
|
||||||
|
//This may potentially be called a number of times as we get closer and closer to the opening time
|
||||||
|
if (injectorStartAngle > crankAngle)
|
||||||
|
{
|
||||||
|
setSchedule1(openInjector,
|
||||||
|
(injectorStartAngle - crankAngle) * timePerDegree,
|
||||||
|
pulseWidth,
|
||||||
|
closeInjector
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//Likewise for the ignition
|
||||||
|
if (ignitionStartAngle > crankAngle)
|
||||||
|
{
|
||||||
|
setSchedule2(beginCoilCharge,
|
||||||
|
(ignitionStartAngle - crankAngle) * timePerDegree,
|
||||||
|
engineDwell,
|
||||||
|
endCoilCharge
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Serial.println(VE);
|
//Serial.println(VE);
|
||||||
|
|
62
scheduler.h
62
scheduler.h
|
@ -28,10 +28,14 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd
|
||||||
|
|
||||||
//#define clockspeed 16000000
|
//#define clockspeed 16000000
|
||||||
|
|
||||||
int schedule1Active;
|
int schedule1Active; //Value=0 means do nothing, value=1 means call the startCallback, value=2 means call the endCallback
|
||||||
int schedule2Active;
|
int schedule2Active;
|
||||||
void (*schedule1Callback)(); //Callback function for schedule1
|
unsigned long schedule1Duration; //How long (uS) after calling the start callback to we call the end callback
|
||||||
void (*schedule2Callback)();
|
unsigned long schedule2Duration;
|
||||||
|
void (*schedule1StartCallback)(); //Start Callback function for schedule1
|
||||||
|
void (*schedule2StartCallback)();
|
||||||
|
void (*schedule1EndCallback)(); //End Callback function for schedule1
|
||||||
|
void (*schedule2EndCallback)();
|
||||||
|
|
||||||
void initialiseScheduler()
|
void initialiseScheduler()
|
||||||
{
|
{
|
||||||
|
@ -58,28 +62,32 @@ void initialiseScheduler()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This turns schedule 1 on, gives it a callback functino and resets the relevant timer based on the time in the future that this should be triggered
|
This turns schedule 1 on, gives it callback functions and resets the relevant timer based on the time in the future that this should be triggered
|
||||||
Args:
|
Args:
|
||||||
callback: The function to be called once the timeout is reach
|
startCallback: The function to be called once the timeout1 is reached
|
||||||
timeout: The number of uS in the future that the callback should be triggered
|
timeout1: The number of uS in the future that the callback should be triggered
|
||||||
|
duration: The number of uS before endCallback is called
|
||||||
|
endCallback
|
||||||
*/
|
*/
|
||||||
void setSchedule1(void (*callback)(), unsigned long timeout)
|
void setSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||||
{
|
{
|
||||||
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
|
//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))
|
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
|
||||||
//TODO: Need to add check for timeout > 1048576 ????
|
//TODO: Need to add check for timeout > 1048576 ????
|
||||||
TCNT3 = 65536 - (timeout / 16); //Each tick occurs every 16uS with a 256 prescaler so divide the timeout by 16 to get ther required number of ticks. Subtract this from the total number of tick (65536 for 16-bit timer)
|
TCNT3 = 65536 - (timeout / 16); //Each tick occurs every 16uS with a 256 prescaler so divide the timeout by 16 to get ther required number of ticks. Subtract this from the total number of tick (65536 for 16-bit timer)
|
||||||
//TCNT3 = 0;
|
schedule1Duration = duration;
|
||||||
schedule1Callback = callback; //Name the callback function
|
schedule1StartCallback = startCallback; //Name the start callback function
|
||||||
schedule1Active = 1; //Turn this schedule on
|
schedule1EndCallback = endCallback; //Name the start callback function
|
||||||
|
schedule1Active = 1; //Turn this schedule on and set it
|
||||||
}
|
}
|
||||||
|
|
||||||
//As above, but for schedule2
|
//As above, but for schedule2
|
||||||
void setSchedule2(void (*callback)(), unsigned long timeout)
|
void setSchedule2(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
|
||||||
{
|
{
|
||||||
//TODO: Need to add check for timeout > 1048576 ????
|
//TODO: Need to add check for timeout > 1048576 ????
|
||||||
TCNT4 = 65536 - (timeout / 16); //Each tick occurs every 16uS with a 256 prescaler so divide the timeout by 16 to get ther required number of ticks. Subtract this from the total number of tick (65536 for 16-bit timer)
|
TCNT4 = 65536 - (timeout / 16); //Each tick occurs every 16uS with a 256 prescaler so divide the timeout by 16 to get ther required number of ticks. Subtract this from the total number of tick (65536 for 16-bit timer)
|
||||||
schedule2Callback = callback; //Name the callback function
|
schedule2StartCallback = startCallback; //Name the callback function
|
||||||
|
schedule2EndCallback = endCallback; //Name the callback function
|
||||||
schedule2Active = 1; //Turn this schedule on
|
schedule2Active = 1; //Turn this schedule on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,25 +95,37 @@ void setSchedule2(void (*callback)(), unsigned long timeout)
|
||||||
//This needs to call the callback function if one has been provided and rest the timer
|
//This needs to call the callback function if one has been provided and rest the timer
|
||||||
ISR(TIMER3_OVF_vect)
|
ISR(TIMER3_OVF_vect)
|
||||||
{
|
{
|
||||||
if (schedule1Active > 0) //Check to see if this schedule is turn on
|
if (schedule1Active == 1) //Check to see if this schedule is turn on
|
||||||
{
|
{
|
||||||
schedule1Callback(); //Replace with user provided callback
|
schedule1StartCallback(); //Replace with user provided callback
|
||||||
schedule1Active = 0; //Turn off the callback
|
schedule1Active = 2; //Turn off the callback
|
||||||
|
TCNT3 = 65536 - (schedule2Duration / 16);
|
||||||
|
}
|
||||||
|
else if (schedule1Active == 2)
|
||||||
|
{
|
||||||
|
schedule1EndCallback();
|
||||||
|
schedule1Active = 0; //Turn off the callback
|
||||||
|
TCNT3 = 0; //Reset Timer to 0 out of 255
|
||||||
}
|
}
|
||||||
|
|
||||||
TCNT3 = 0; //Reset Timer to 0 out of 255
|
|
||||||
TIFR3 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
TIFR3 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
||||||
}
|
}
|
||||||
|
|
||||||
//AS above for schedule2
|
//AS above for schedule2
|
||||||
ISR(TIMER4_OVF_vect)
|
ISR(TIMER4_OVF_vect)
|
||||||
{
|
{
|
||||||
if (schedule2Active > 0) //Check to see if this schedule is turn on
|
if (schedule2Active == 1) //A value of 1 means call the start callback
|
||||||
{
|
{
|
||||||
schedule2Callback(); //Replace with user provided callback
|
schedule2StartCallback();
|
||||||
schedule2Active = 0; //Turn off the callback
|
schedule2Active = 2; //Set to call the end callback on the next run
|
||||||
|
TCNT4 = 65536 - (schedule2Duration / 16);
|
||||||
|
}
|
||||||
|
else if (schedule2Active == 2)
|
||||||
|
{
|
||||||
|
schedule2EndCallback();
|
||||||
|
schedule2Active = 0; //Turn off the callback
|
||||||
|
TCNT4 = 0; //Reset Timer to 0 out of 255
|
||||||
}
|
}
|
||||||
|
|
||||||
TCNT3 = 0; //Reset Timer to 0 out of 255
|
TIFR4 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
||||||
TIFR3 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue