From bcf9063aaa130a05cf3f7a5fbbc2ed3a4e6d9cd1 Mon Sep 17 00:00:00 2001 From: metacomgd Date: Thu, 21 May 2020 23:27:20 -0400 Subject: [PATCH] Added 36-2-1 basic support (#366) Co-authored-by: k --- speeduino/decoders.h | 7 +++ speeduino/decoders.ino | 129 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/speeduino/decoders.h b/speeduino/decoders.h index 139d5889..edf87ce0 100644 --- a/speeduino/decoders.h +++ b/speeduino/decoders.h @@ -140,6 +140,13 @@ uint16_t getRPM_ThirtySixMinus222(); int getCrankAngle_ThirtySixMinus222(); void triggerSetEndTeeth_ThirtySixMinus222(); +void triggerSetup_ThirtySixMinus21(); +void triggerPri_ThirtySixMinus21(); +void triggerSec_ThirtySixMinus21(); +uint16_t getRPM_ThirtySixMinus21(); +int getCrankAngle_ThirtySixMinus21(); +void triggerSetEndTeeth_ThirtySixMinus21(); + extern void (*triggerHandler)(); //Pointer for the trigger function (Gets pointed to the relevant decoder) extern void (*triggerSecondaryHandler)(); //Pointer for the secondary trigger function (Gets pointed to the relevant decoder) extern uint16_t (*getRPM)(); //Pointer to the getRPM function (Gets pointed to the relevant decoder) diff --git a/speeduino/decoders.ino b/speeduino/decoders.ino index 727eedc8..44f0bad7 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -3396,3 +3396,132 @@ void triggerSetEndTeeth_ThirtySixMinus222() lastToothCalcAdvance = currentStatus.advance; } + + +//************************************************************************************************************************ + +/* +Name: 36-2-1, For the 4B11 +Desc: A crank based trigger with a nominal 36 teeth, but with 1 single and 1 double missing tooth. +*/ +void triggerSetup_ThirtySixMinus21() +{ + triggerToothAngle = 10; //The number of degrees that passes from tooth to tooth + triggerActualTeeth = 33; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt. Not Used + triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.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; + decoderIsSequential = false; + checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth. + toothLastMinusOneToothTime = 0; + toothCurrentCount = 0; + toothOneTime = 0; + toothOneMinusOneTime = 0; + MAX_STALL_TIME = (3333UL * triggerToothAngle * 2 ); //Minimum 50rpm. (3333uS is the time per degree at 50rpm) +} + +void triggerPri_ThirtySixMinus21() +{ + curTime = micros(); + curGap = curTime - toothLastToothTime; + if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS) + { + toothCurrentCount++; //Increment the tooth counter + validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters) + + //Begin the missing tooth detection + //If the time between the current tooth and the last is greater than 2x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after a gap + + targetGap2 = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) ; //Multiply by 3 (Checks for a gap 3x greater than the last one) + targetGap = targetGap2 >> 1; //Multiply by 1.5 (Checks for a gap 1.5x greater than the last one) (Uses bitshift to divide by 2 as in the missing tooth deocder) + + if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; } + + if ( (curGap > targetGap) ) + { + if ( (curGap < targetGap2)) + { + //we are at the tooth after the single gap + toothCurrentCount = 20; //it's either 19 or 20, need to clarify engine direction! + currentStatus.hasSync = true; + } + else + { + //we are at the tooth after the double gap + toothCurrentCount = 1; + currentStatus.hasSync = true; + } + + triggerToothAngleIsCorrect = false; //The tooth angle is double at this point + triggerFilterTime = 0; //This is used to prevent a condition where serious intermitent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state + } + } + else + { + if( (toothCurrentCount > 36) || ( toothCurrentCount==1) ) + { + //Means a complete rotation has occured. + toothCurrentCount = 1; + revolutionOne = !revolutionOne; //Flip sequential revolution tracker + toothOneMinusOneTime = toothOneTime; + toothOneTime = curTime; + currentStatus.startRevolutions++; //Counter + + } + + //Filter can only be recalc'd for the regular teeth, not the missing one. + setFilter(curGap); + + triggerToothAngleIsCorrect = true; + + } + + toothLastMinusOneToothTime = toothLastToothTime; + toothLastToothTime = curTime; + + //EXPERIMENTAL! + if(configPage2.perToothIgn == true) + { + uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle; + checkPerToothTiming(crankAngle, toothCurrentCount); + } + + +} + +void triggerSec_ThirtySixMinus21() +{ + //NOT USED - This pattern uses the missing tooth version of this function +} + +uint16_t getRPM_ThirtySixMinus21() +{ + uint16_t tempRPM = 0; + if( currentStatus.RPM < currentStatus.crankRPM) + { + if( (toothCurrentCount != 20) && (triggerToothAngleIsCorrect == true) ) + { + tempRPM = crankingGetRPM(36); + } + else { tempRPM = currentStatus.RPM; } //Can't do per tooth RPM if we're at tooth #1 as the missing tooth messes the calculation + } + else + { + tempRPM = stdGetRPM(360); + } + return tempRPM; +} + +int getCrankAngle_ThirtySixMinus21() +{ + //NOT USED - This pattern uses the missing tooth version of this function + return 0; +} + +void triggerSetEndTeeth_ThirtySixMinus21() +{ + ignition1EndTooth = 10; + ignition2EndTooth = 28; // Arbritrarilly picked at 180°. + + + lastToothCalcAdvance = currentStatus.advance; +}