From 650a096175b44a294ccb44ed164bef26b8d45422 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Sun, 12 Feb 2017 18:35:18 +1300 Subject: [PATCH] Initial (untested) commit of Nissan 360. ONLY support 4 cylinder so far --- reference/speeduino.ini | 4 +- speeduino/decoders.ino | 120 +++++++++++++++++++++++++++++++++++++++- speeduino/speeduino.ino | 11 ++++ 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index a68a86c..1501d19 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -247,7 +247,7 @@ page = 4 TrigSpeed = bits, U08, 5,[1:1], "Crank Speed", "Cam Speed" IgInv = bits, U08, 5,[2:2], "Going Low", "Going High" oddfire = bits, U08, 5,[3:3], "No", "Yes" - TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "INVALID", "INVALID", "INVALID", "INVALID" + TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "INVALID", "INVALID", "INVALID" TrigEdgeSec= bits, U08, 6,[0:0], "Leading", "Trailing" fuelPumpPin= bits , U08, 6,[1:6], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" unused4-6h = bits, U08, 6,[7:7], "No", "Yes" @@ -1749,7 +1749,7 @@ menuDialog = main errors = scalar, U08, 36, "bits", 1.000, 0.000 errorNum = bits, U08, 36, [0:1] currentError = bits, U08, 36, [2:7] - boostTarget = scalar, U08, 37, "kPa", 1.000, 0.000 + boostTarget = scalar, U08, 37, "kPa", 2.000, 0.000 ; Computed output channels. See "megatuneExamples.ini" for all the ; pre-defined variables, search for "???" and you'll see them. diff --git a/speeduino/decoders.ino b/speeduino/decoders.ino index 89f3c78..ee80c33 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -180,7 +180,7 @@ int getCrankAngle_missingTooth(int timePerDegree) return crankAngle; } -/* +/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Name: Dual wheel Desc: 2 wheels located either both on the crank or with the primary on the crank and the secondary on the cam. Note: There can be no missing teeth on the primary wheel @@ -1332,3 +1332,121 @@ int getCrankAngle_non360(int timePerDegree) return crankAngle; } + +/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Name: Nissan 360 tooth with cam +Desc: +Note: +*/ +void triggerSetup_Nissan360() +{ + triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * 360)); //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) + secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration + secondDerivEnabled = false; + decoderIsSequential = true; + MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm) +} + + +void triggerPri_Nissan360() +{ + curTime = micros(); + curGap = curTime - toothLastToothTime; + //if ( curGap < triggerFilterTime ) { return; } //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. + toothCurrentCount++; //Increment the tooth counter + //addToothLogEntry(curGap); Disable tooth logging on this decoder due to overhead + + toothLastMinusOneToothTime = toothLastToothTime; + toothLastToothTime = curTime; + + if ( !currentStatus.hasSync ) { return; } + + if ( toothCurrentCount == 360 ) + { + toothCurrentCount = 1; + toothOneMinusOneTime = toothOneTime; + toothOneTime = curTime; + currentStatus.startRevolutions++; //Counter + } + + //setFilter(curGap); //Recalc the new filter value +} + +void triggerSec_Nissan360() +{ + curTime2 = micros(); + curGap2 = curTime2 - toothLastSecToothTime; + //if ( curGap2 < triggerSecFilterTime ) { return; } + toothLastSecToothTime = curTime2; + //triggerSecFilterTime = curGap2 >> 2; //Set filter at 25% of the current speed + + + //Calculate number of primary teeth that this window has been active for + if(secondaryToothCount == 0) { secondaryToothCount = toothCurrentCount; return; } //This occurs on the first rotation upon powerup + if(digitalRead(pinTrigger2) == HIGH) { secondaryToothCount = toothCurrentCount; return; } //This represents the start of a secondary window + + //If we reach here, we are at the end of a secondary window + byte secondaryDuration = toothCurrentCount - secondaryToothCount; //How many primary teeth have passed during the duration of this secondary window + + if(!currentStatus.hasSync) + { + if(configPage1.nCylinders == 4) + { + if(secondaryDuration >= 15 || secondaryDuration <= 17) //Duration of window = 16 primary teeth + { + toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC + currentStatus.hasSync == true; + } + else if(secondaryDuration >= 11 || secondaryDuration <= 13) //Duration of window = 12 primary teeth + { + toothCurrentCount = 102; //End of second window is after 90+12 primary teeth + currentStatus.hasSync == true; + } + else if(secondaryDuration >= 7 || secondaryDuration <= 9) //Duration of window = 8 primary teeth + { + toothCurrentCount = 188; //End of third window is after 90+90+8 primary teeth + currentStatus.hasSync == true; + } + else if(secondaryDuration >= 3 || secondaryDuration <= 5) //Duration of window = 4 primary teeth + { + toothCurrentCount = 274; //End of fourth window is after 90+90+90+4 primary teeth + currentStatus.hasSync == true; + } + } + else if(configPage1.nCylinders == 6) + { + //I don't have this info yet :( + } + else { currentStatus.hasSync == false; return ;} //This should really never happen + } + else + { + //Already have sync, but do a verify every 720 degrees. + //Not sure if this works for 6 cylinder??? + if(secondaryDuration >= 15) //Duration of window = 16 primary teeth + { + toothCurrentCount = 16; //End of first window (The longest) occurs 16 teeth after TDC + } + } + +} + +int getRPM_Nissan360() +{ + if( !currentStatus.hasSync) { return 0; } + //if(currentStatus.RPM < configPage2.crankRPM) { return crankingGetRPM(configPage2.triggerTeeth); } + return stdGetRPM(); +} + +int getCrankAngle_Nissan360(int timePerDegree) +{ + //As each tooth represents 2 crank degrees, we only need to dtermine whether we're more or less than halfway between teeth to know whether to add another 1 degrees + unsigned long halfTooth = (toothLastToothTime - toothLastMinusOneToothTime) >> 1; + if ( (micros() - toothLastToothTime) > halfTooth) + { + //Means we're over halfway to the next tooth, so add on 1 degree + return (toothCurrentCount * 2) + 1; + } + return (toothCurrentCount * 2); +} diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index f8c6047..8f0f1ab 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -451,6 +451,17 @@ void setup() attachInterrupt(triggerInterrupt2, triggerSec_DualWheel, FALLING); //Note the use of the Dual Wheel trigger function here. No point in having the same code in twice. break; + case 12: + triggerSetup_Nissan360(); + trigger = triggerPri_Nissan360; //Is identical to the dual wheel decoder, so that is used. Same goes for the secondary below + getRPM = getRPM_Nissan360; + getCrankAngle = getCrankAngle_Nissan360; + + if(configPage2.TrigEdge == 0) { attachInterrupt(triggerInterrupt, trigger, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering) + else { attachInterrupt(triggerInterrupt, trigger, FALLING); } + attachInterrupt(triggerInterrupt2, triggerSec_Nissan360, CHANGING); + break; + default: trigger = triggerPri_missingTooth; getRPM = getRPM_missingTooth;