diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 2e7b068e..1c4509d4 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -110,6 +110,7 @@ #define trigger_Harley = 15 #define trigger_ThirtySixMinus222 = 16 #define trigger_ThirtySixMinus21 = 17 + #define trigger_420a = 18 [Constants] @@ -401,7 +402,7 @@ page = 4 TrigEdge = bits, U08, 5,[0:0], "RISING", "FALLING" TrigSpeed = bits, U08, 5,[1:1], "Crank Speed", "Cam Speed" IgInv = bits, U08, 5,[2:2], "Going Low", "Going High" - TrigPattern= bits, U08, 5,[3:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "Harley EVO", "36-2-2-2", "36-2-1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" + TrigPattern= bits, U08, 5,[3:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "Daihatsu +1", "Harley EVO", "36-2-2-2", "36-2-1", "DSM 420a", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" TrigEdgeSec= bits, U08, 6,[0:0], "RISING", "FALLING" 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", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID" useResync = bits, U08, 6,[7:7], "No", "Yes" @@ -2259,7 +2260,7 @@ menuDialog = main field = "Cranking advance Angle", CrankAng field = "Spark Outputs triggers", IgInv panel = lockSparkSettings - panel = newIgnitionMode, {}, {TrigPattern == 0 || TrigPattern == 1 || TrigPattern == 2 || TrigPattern == 3 || TrigPattern == 4 || TrigPattern == 9 || TrigPattern == 12 || TrigPattern == 13 } ;Only works for missing tooth, distributor, dual wheel, GM 7X, 4g63, Miata 99-05, nissan 360, Subaru 6/7 + panel = newIgnitionMode, {}, {TrigPattern == 0 || TrigPattern == 1 || TrigPattern == 2 || TrigPattern == 3 || TrigPattern == 4 || TrigPattern == 9 || TrigPattern == 12 || TrigPattern == 13 || TrigPattern == 18} ;Only works for missing tooth, distributor, dual wheel, GM 7X, 4g63, Miata 99-05, nissan 360, Subaru 6/7, 420a dialog = dwellSettings, "Dwell Settings", 4 diff --git a/speeduino/decoders.h b/speeduino/decoders.h index edf87ce0..bec3dc70 100644 --- a/speeduino/decoders.h +++ b/speeduino/decoders.h @@ -147,6 +147,13 @@ uint16_t getRPM_ThirtySixMinus21(); int getCrankAngle_ThirtySixMinus21(); void triggerSetEndTeeth_ThirtySixMinus21(); +void triggerSetup_420a(); +void triggerPri_420a(); +void triggerSec_420a(); +uint16_t getRPM_420a(); +int getCrankAngle_420a(); +void triggerSetEndTeeth_420a(); + 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 44f0bad7..52d9d052 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -3523,5 +3523,188 @@ void triggerSetEndTeeth_ThirtySixMinus21() ignition2EndTooth = 28; // Arbritrarilly picked at 180°. + lastToothCalcAdvance = currentStatus.advance; +} + +//************************************************************************************************************************ + +/* +Name: DSM 420a, For the DSM Eclipse +Desc: https://github.com/noisymime/speeduino/issues/133 + 16 teeth total on the crank. Tracks the falling side of the signal + Sync is determined by watching for a falling edge on the secondary signal and checking if the primary signal is high then. +*/ +void triggerSetup_420a() +{ + triggerFilterTime = (1000000 / (MAX_RPM / 60 * 360UL)); //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 = 0; + secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration + secondDerivEnabled = false; + decoderIsSequential = true; + toothCurrentCount = 1; + triggerToothAngle = 20; //Is only correct for the 4 short pulses before each TDC + triggerToothAngleIsCorrect = false; + toothSystemCount = 0; + MAX_STALL_TIME = (3333UL * 93); //Minimum 50rpm. (3333uS is the time per degree at 50rpm) + + toothAngles[0] = 711; //tooth #1, just before #1 TDC + toothAngles[1] = 111; + toothAngles[2] = 131; + toothAngles[3] = 151; + toothAngles[4] = 171; //Just before #3 TDC + toothAngles[5] = toothAngles[1] + 180; + toothAngles[6] = toothAngles[2] + 180; + toothAngles[7] = toothAngles[3] + 180; + toothAngles[8] = toothAngles[4] + 180; //Just before #4 TDC + toothAngles[9] = toothAngles[1] + 360; + toothAngles[10] = toothAngles[2] + 360; + toothAngles[11] = toothAngles[3] + 360; + toothAngles[12] = toothAngles[4] + 360; //Just before #4 TDC + toothAngles[13] = toothAngles[1] + 540; + toothAngles[14] = toothAngles[2] + 540; + toothAngles[15] = toothAngles[3] + 540; +} + +void triggerPri_420a() +{ + 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) + + if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; } + + if( (toothCurrentCount > 16) && (currentStatus.hasSync == true) ) + { + //Means a complete rotation has occured. + toothCurrentCount = 1; + toothOneMinusOneTime = toothOneTime; + toothOneTime = curTime; + currentStatus.startRevolutions++; //Counter + } + + //Filter can only be recalc'd for the regular teeth, not the missing one. + //setFilter(curGap); + triggerFilterTime = 0; + + triggerToothAngleIsCorrect = false; + + toothLastMinusOneToothTime = toothLastToothTime; + toothLastToothTime = curTime; + + //EXPERIMENTAL! + if(configPage2.perToothIgn == true) + { + uint16_t crankAngle = ( toothAngles[(toothCurrentCount-1)] ) + configPage4.triggerAngle; + checkPerToothTiming(crankAngle, toothCurrentCount); + } + } +} + +void triggerSec_420a() +{ + //Secondary trigger is only on falling edge + + if(READ_PRI_TRIGGER() == true) + { + //Secondary signal is falling and primary signal is HIGH + if( currentStatus.hasSync == false ) + { + //If we don't have sync, then assume the signal is good + toothCurrentCount = 13; + currentStatus.hasSync = true; + } + else + { + //If we DO have sync, then check that the tooth count matches what we expect + if(toothCurrentCount != 13) + { + currentStatus.syncLossCounter++; + toothCurrentCount = 13; + } + } + + } + else + { + //Secondary signal is falling and primary signal is LOW + if( currentStatus.hasSync == false ) + { + //If we don't have sync, then assume the signal is good + toothCurrentCount = 5; + currentStatus.hasSync = true; + } + else + { + //If we DO have sync, then check that the tooth count matches what we expect + if(toothCurrentCount != 5) + { + currentStatus.syncLossCounter++; + toothCurrentCount = 5; + } + } + } +} + +uint16_t getRPM_420a() +{ + uint16_t tempRPM = 0; + if( currentStatus.RPM < currentStatus.crankRPM) + { + //Possibly look at doing special handling for cranking in the future, but for now just use the standard method + tempRPM = stdGetRPM(720); + } + else + { + tempRPM = stdGetRPM(720); + } + return tempRPM; +} + +int getCrankAngle_420a() +{ + //This is the current angle ATDC the engine is at. This is the last known position based on what tooth was last 'seen'. It is only accurate to the resolution of the trigger wheel (Eg 36-1 is 10 degrees) + unsigned long tempToothLastToothTime; + int tempToothCurrentCount; + //Grab some variables that are used in the trigger code and assign them to temp variables. + noInterrupts(); + tempToothCurrentCount = toothCurrentCount; + tempToothLastToothTime = toothLastToothTime; + lastCrankAngleCalc = micros(); //micros() is no longer interrupt safe + interrupts(); + + int crankAngle; + crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was. + + //Estimate the number of degrees travelled since the last tooth} + elapsedTime = (lastCrankAngleCalc - tempToothLastToothTime); + crankAngle += timeToAngle(elapsedTime, CRANKMATH_METHOD_INTERVAL_REV); + + if (crankAngle >= 720) { crankAngle -= 720; } + if (crankAngle > CRANK_ANGLE_MAX) { crankAngle -= CRANK_ANGLE_MAX; } + if (crankAngle < 0) { crankAngle += 360; } + + return crankAngle; +} + +void triggerSetEndTeeth_420a() +{ + if(currentStatus.advance < 9) + { + ignition1EndTooth = 1; + ignition2EndTooth = 5; + ignition3EndTooth = 9; + ignition4EndTooth = 13; + } + else + { + ignition1EndTooth = 16; + ignition2EndTooth = 4; + ignition3EndTooth = 8; + ignition4EndTooth = 12; + } + lastToothCalcAdvance = currentStatus.advance; } diff --git a/speeduino/init.ino b/speeduino/init.ino index a1b65ba2..b2e414cd 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -2882,23 +2882,29 @@ void initialiseTriggers() case 17: //36-2-1 - triggerSetup_ThirtySixMinus21(); - triggerHandler = triggerPri_ThirtySixMinus21; - triggerSecondaryHandler = triggerSec_ThirtySixMinus21; + //NOT YET WRITTEN + break; + + case 18: + //DSM 420a + triggerSetup_420a(); + triggerHandler = triggerPri_420a; + triggerSecondaryHandler = triggerSec_420a; decoderHasSecondary = true; - getRPM = getRPM_ThirtySixMinus21; - getCrankAngle = getCrankAngle_ThirtySixMinus21; - triggerSetEndTeeth = triggerSetEndTeeth_ThirtySixMinus21; + getRPM = getRPM_420a; + getCrankAngle = getCrankAngle_420a; + triggerSetEndTeeth = triggerSetEndTeeth_420a; if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering) else { primaryTriggerEdge = FALLING; } - if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; } - else { secondaryTriggerEdge = FALLING; } + secondaryTriggerEdge = FALLING; //Always falling edge attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge); attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge); break; + + default: triggerHandler = triggerPri_missingTooth; getRPM = getRPM_missingTooth;