diff --git a/reference/speeduino.ini b/reference/speeduino.ini index c9446067..dbd776c3 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -424,7 +424,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", "DSM 420a", "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", "Weber-Marelli", "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" @@ -2414,7 +2414,7 @@ menuDialog = main dialog = triggerSettings,"Trigger Settings",4 topicHelp = "https://wiki.speeduino.com/en/decoders" field = "Trigger Pattern", TrigPattern - field = "Primary base teeth", numTeeth, { TrigPattern == 0 || TrigPattern == 2 || TrigPattern == 11 } + field = "Primary base teeth", numTeeth, { TrigPattern == 0 || TrigPattern == 2 || TrigPattern == 11 || TrigPattern == 18 } field = "Primary trigger speed", TrigSpeed, { TrigPattern == 0 } field = "Missing teeth", missingTeeth, { TrigPattern == 0 } field = "Trigger angle multiplier", TrigAngMul, { TrigPattern == 11 } @@ -2426,10 +2426,10 @@ menuDialog = main field = "Note: This is the number of revolutions that will be skipped during" field = "cranking before the injectors and coils are fired" field = "Trigger edge", TrigEdge { TrigPattern != 4 } ;4G63 uses both edges - field = "Secondary trigger edge", TrigEdgeSec, { (TrigPattern == 0 && TrigSpeed == 0) || TrigPattern == 2 || TrigPattern == 9 || TrigPattern == 12 } ;Missing tooth, dual wheel and Miata 9905 + field = "Secondary trigger edge", TrigEdgeSec, { (TrigPattern == 0 && TrigSpeed == 0) || TrigPattern == 2 || TrigPattern == 9 || TrigPattern == 12 || TrigPattern == 18 } ;Missing tooth, dual wheel and Miata 9905 field = "Missing Tooth Secondary type" trigPatternSec, { (TrigPattern == 0&& TrigSpeed == 0) } field = "Trigger Filter", TrigFilter, { TrigPattern != 13 } - field = "Re-sync every cycle", useResync, { TrigPattern == 2 || TrigPattern == 4 || TrigPattern == 7 || TrigPattern == 12 || TrigPattern == 9 || TrigPattern == 13 } ;Dual wheel, 4G63, Audi 135, Nissan 360, Miata 99-05 + field = "Re-sync every cycle", useResync, { TrigPattern == 2 || TrigPattern == 4 || TrigPattern == 7 || TrigPattern == 12 || TrigPattern == 9 || TrigPattern == 13 || TrigPattern == 18 } ;Dual wheel, 4G63, Audi 135, Nissan 360, Miata 99-05 dialog = lockSparkSettings, "Locked timing" field = "Enabled Fixed/Locked timing", fixAngEnable @@ -2451,7 +2451,6 @@ menuDialog = main panel = lockSparkSettings 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 topicHelp = "https://wiki.speeduino.com/en/configuration/Dwell" field = " Cranking dwell", dwellcrank diff --git a/speeduino/decoders.h b/speeduino/decoders.h index bec3dc70..2823baef 100644 --- a/speeduino/decoders.h +++ b/speeduino/decoders.h @@ -154,6 +154,9 @@ uint16_t getRPM_420a(); int getCrankAngle_420a(); void triggerSetEndTeeth_420a(); +void triggerPri_Webber(); +void triggerSec_Webber(); + 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 5686e195..f8ccea40 100644 --- a/speeduino/decoders.ino +++ b/speeduino/decoders.ino @@ -3732,3 +3732,110 @@ void triggerSetEndTeeth_420a() lastToothCalcAdvance = currentStatus.advance; } + +/* ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Name: Weber-Marelli +Desc: 2 wheels, 4 teeth 90deg apart on crank and 2 90deg apart on cam. +Note: It use DualWheel decoders, There can be no missing teeth on the primary wheel +*/ +void triggerPri_Webber() +{ + curTime = micros(); + curGap = curTime - toothLastToothTime; + if ( curGap >= triggerFilterTime ) + { + toothCurrentCount++; //Increment the tooth counter + if (checkSyncToothCount > 0) { checkSyncToothCount++; } + if ( triggerSecFilterTime <= curGap ) { triggerSecFilterTime = curGap + (curGap>>1); } //150% crank tooth + validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters) + + toothLastMinusOneToothTime = toothLastToothTime; + toothLastToothTime = curTime; + + if ( currentStatus.hasSync == true ) + { + if ( (toothCurrentCount == 1) || (toothCurrentCount > configPage4.triggerTeeth) ) + { + toothCurrentCount = 1; + revolutionOne = !revolutionOne; //Flip sequential revolution tracker + toothOneMinusOneTime = toothOneTime; + toothOneTime = curTime; + currentStatus.startRevolutions++; //Counter + } + + setFilter(curGap); //Recalc the new filter value + } + else + { + if ( (secondaryToothCount == 1) && (checkSyncToothCount == 4) ) + { + toothCurrentCount = 2; + currentStatus.hasSync = true; + revolutionOne = 0; //Sequential revolution reset + } + } + + //NEW IGNITION MODE + if( (configPage2.perToothIgn == true) && (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) ) + { + int16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle; + if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (revolutionOne == true) && (configPage4.TrigSpeed == CRANK_SPEED) ) + { + crankAngle += 360; + checkPerToothTiming(crankAngle, (configPage4.triggerTeeth + toothCurrentCount)); + } + else{ checkPerToothTiming(crankAngle, toothCurrentCount); } + } + } //Trigger filter +} + +void triggerSec_Webber() +{ + curTime2 = micros(); + curGap2 = curTime2 - toothLastSecToothTime; + + if ( curGap2 >= triggerSecFilterTime ) + { + toothLastSecToothTime = curTime2; + + if ( (secondaryToothCount == 2) && (checkSyncToothCount == 3) ) + { + if(currentStatus.hasSync == false) + { + toothLastToothTime = micros(); + toothLastMinusOneToothTime = micros() - 1500000; //Fixes RPM at 10rpm until a full revolution has taken place + toothCurrentCount = configPage4.triggerTeeth-1; + + currentStatus.hasSync = true; + } + else + { + if ( (toothCurrentCount != (configPage4.triggerTeeth-1)) && (currentStatus.startRevolutions > 2)) { currentStatus.syncLossCounter++; } //Indicates likely sync loss. + if (configPage4.useResync == 1) { toothCurrentCount = configPage4.triggerTeeth-1; } + } + revolutionOne = 1; //Sequential revolution reset + triggerSecFilterTime = curGap << 2; //4 crank teeth + secondaryToothCount = 1; //Next tooth should be first + } //Running, on first CAM pulse restart crank teet count, on second the counter should be 3 + else if ( (currentStatus.hasSync == false) && (toothCurrentCount >= 3) && (secondaryToothCount == 0) ) + { + toothLastToothTime = micros(); + toothLastMinusOneToothTime = micros() - 1500000; //Fixes RPM at 10rpm until a full revolution has taken place + toothCurrentCount = 1; + revolutionOne = 1; //Sequential revolution reset + + currentStatus.hasSync = true; + } //First start, between gaps on CAM pulses have 2 teeth, sync on first CAM pulse if seen 3 teeth or more + else + { + triggerSecFilterTime = curGap + (curGap>>1); //150% crank tooth + secondaryToothCount++; + checkSyncToothCount = 1; //Tooth 1 considered as already been seen + } //First time might fall here, second CAM tooth will + } + else + { + triggerSecFilterTime = curGap + (curGap>>1); //Noise region, using 150% of crank tooth + checkSyncToothCount = 1; //Reset tooth counter + } //Trigger filter +} diff --git a/speeduino/init.ino b/speeduino/init.ino index 0643f02a..46cfe20e 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -2967,7 +2967,25 @@ void initialiseTriggers() attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge); break; - + case 19: + //Weber-Marelli + triggerSetup_DualWheel(); + triggerHandler = triggerPri_Webber; + triggerSecondaryHandler = triggerSec_Webber; + decoderHasSecondary = true; + getRPM = getRPM_DualWheel; + getCrankAngle = getCrankAngle_DualWheel; + triggerSetEndTeeth = triggerSetEndTeeth_DualWheel; + + 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; } + + attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge); + attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge); + break; + default: triggerHandler = triggerPri_missingTooth;