diff --git a/kartduino.ino b/kartduino.ino index c83f5eaa..c36c45bd 100644 --- a/kartduino.ino +++ b/kartduino.ino @@ -6,9 +6,9 @@ /* 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 engineInjectorSize 100 // In cc/min +#define engineInjectorSize 80 // In cc/min #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 engineDwell 3000 //The spark dwell time in uS @@ -111,21 +111,43 @@ void loop() //Perform lookup into fuel map for RPM vs MAP value int VE = getTableValue(fuelTable, MAP, rpm); //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 - int advance = getTableValue(ignitionTable, MAP, rpm); + int ignitionAdvance = getTableValue(ignitionTable, MAP, rpm); //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 if (crankAngle > 360) { crankAngle -= 360; } //Not sure if this is actually required - //Determine next firing angles - - - //Finally calculate the time (uS) until we reach the 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 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); diff --git a/scheduler.h b/scheduler.h index 31bd3afa..a4f33b2b 100644 --- a/scheduler.h +++ b/scheduler.h @@ -28,10 +28,14 @@ See page 136 of the processors datasheet: http://www.atmel.com/Images/doc2549.pd //#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; -void (*schedule1Callback)(); //Callback function for schedule1 -void (*schedule2Callback)(); +unsigned long schedule1Duration; //How long (uS) after calling the start callback to we call the end callback +unsigned long schedule2Duration; +void (*schedule1StartCallback)(); //Start Callback function for schedule1 +void (*schedule2StartCallback)(); +void (*schedule1EndCallback)(); //End Callback function for schedule1 +void (*schedule2EndCallback)(); 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: -callback: The function to be called once the timeout is reach -timeout: The number of uS in the future that the callback should be triggered +startCallback: The function to be called once the timeout1 is reached +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 //As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency)) //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 = 0; - schedule1Callback = callback; //Name the callback function - schedule1Active = 1; //Turn this schedule on + schedule1Duration = duration; + schedule1StartCallback = startCallback; //Name the start callback function + schedule1EndCallback = endCallback; //Name the start callback function + schedule1Active = 1; //Turn this schedule on and set it } //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 ???? 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 } @@ -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 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 - schedule1Active = 0; //Turn off the callback + schedule1StartCallback(); //Replace with user provided 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 } //AS above for schedule2 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 - schedule2Active = 0; //Turn off the callback + schedule2StartCallback(); + 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 - TIFR3 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag + TIFR4 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag }