diff --git a/decoders.h b/decoders.h index 04de0445..7ff95ea5 100644 --- a/decoders.h +++ b/decoders.h @@ -24,6 +24,7 @@ volatile unsigned long triggerFilterTime; // The shortest time (in uS) that puls unsigned int triggerSecFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) for the secondary input int triggerToothAngle; //The number of crank degrees that elapse per tooth unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that) +bool secondDerivEnabled; //The use of the 2nd derivative calculation is limited to certain decoders. This is set to either true or false in each decoders setup routine int toothAngles[24]; //An array for storing fixed tooth angles. Currently sized at 24 for the GM 24X decoder, but may grow later if there are other decoders that use this style diff --git a/decoders.ino b/decoders.ino index eefea708..301f5203 100644 --- a/decoders.ino +++ b/decoders.ino @@ -67,6 +67,7 @@ void triggerSetup_missingTooth() triggerToothAngle = 360 / configPage2.triggerTeeth; //The number of degrees that passes from tooth to tooth triggerActualTeeth = configPage2.triggerTeeth - configPage2.triggerMissingTeeth; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //Trigger filter time is the shortest possible time (in uS) that there can be between crank teeth (ie at max RPM). Any pulses that occur faster than this time will be disgarded as noise + secondDerivEnabled = false; } void triggerPri_missingTooth() @@ -142,6 +143,7 @@ void triggerSetup_DualWheel() toothCurrentCount = 255; //Default value triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.triggerTeeth)); //Trigger filter time is the shortest possible time (in uS) that there can be between crank teeth (ie at max RPM). Any pulses that occur faster than this time will be disgarded as noise triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed) + secondDerivEnabled = false; } @@ -227,6 +229,7 @@ void triggerSetup_BasicDistributor() triggerToothAngle = 360 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth triggerFilterTime = 60000000L / MAX_RPM / configPage1.nCylinders; // Minimum time required between teeth triggerFilterTime = triggerFilterTime / 2; //Safety margin + secondDerivEnabled = false; } void triggerPri_BasicDistributor() @@ -288,6 +291,7 @@ Note: Within the code below, the sync tooth is referred to as tooth #3 rather th void triggerSetup_GM7X() { triggerToothAngle = 360 / 6; //The number of degrees that passes from tooth to tooth + secondDerivEnabled = false; } void triggerPri_GM7X() @@ -374,6 +378,7 @@ void triggerSetup_4G63() { triggerToothAngle = 180; //The number of degrees that passes from tooth to tooth (primary) toothCurrentCount = 99; //Fake tooth count represents no sync + secondDerivEnabled = false; //Note that these angles are for every rising and falling edge @@ -511,6 +516,7 @@ void triggerSetup_24X() toothAngles[23] = 357; toothCurrentCount = 25; //We set the initial tooth value to be something that should never be reached. This indicates no sync + secondDerivEnabled = false; } void triggerPri_24X() @@ -596,6 +602,7 @@ void triggerSetup_Jeep2000() toothAngles[11] = 474; toothCurrentCount = 13; //We set the initial tooth value to be something that should never be reached. This indicates no sync + secondDerivEnabled = false; } void triggerPri_Jeep2000() diff --git a/scheduler.ino b/scheduler.ino index 27ab75da..7bd6a129 100644 --- a/scheduler.ino +++ b/scheduler.ino @@ -167,7 +167,8 @@ void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsign if(ignitionSchedule4.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)) + //The timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency)) + //Note this is different to the other ignition timers unsigned int absoluteTimeout = TCNT4 + (timeout >> 4); //As above, but with bit shift instead of / 16 OCR4A = absoluteTimeout; diff --git a/speeduino.ino b/speeduino.ino index 273fc904..fe16aee5 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -731,7 +731,7 @@ 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 //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 < 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 + if(secondDerivEnabled && toothHistoryIndex >= 3 && currentStatus.RPM < 2000 ) //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 (DeltaV stays the same until the next tooth) if (deltaToothCount != toothCurrentCount)