Merge remote-tracking branch 'noisymime/master'

This commit is contained in:
Mike501 2023-06-06 22:09:56 +01:00
commit 58e6e283e6
10 changed files with 499 additions and 84 deletions

View File

@ -502,7 +502,7 @@ page = 4
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", "INVALID", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "INVALID"
useResync = bits, U08, 6,[7:7], "No", "Yes"
sparkDur = scalar, U08, 7, "ms", 0.1, 0, 0, 25.5, 1 ; Spark duration
trigPatternSec = bits,U08, 8,[0:6], "Single tooth cam", "4-1 cam", "Poll level", "Rover 5-3-2 cam", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
trigPatternSec = bits,U08, 8,[0:6], "Single tooth cam", "4-1 cam", "Poll level", "Rover 5-3-2 cam", "Nissan 1-3-4-2", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
PollLevelPol = bits, U08, 8,[7:7], "Low", "High",
;Reset Control
@ -665,7 +665,7 @@ page = 6
useExtBaro = bits, U08, 13, [6:6], "No", "Yes"
boostMode = bits, U08, 13, [7:7], "Simple", "Full"
boostPin = bits, U08, 14, [0:5], "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", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
tachoMode = bits, U08, 14, [6:6], "Fixed Duration", "Match Dwell"
unused_bit = bits, U08, 14, [6:6], "No", "Yes"
useEMAP = bits, U08, 14, [7:7], "No", "Yes"
brvBins = array, U08, 15, [6], "V", 0.1, 0, 6, 24, 1 ; Bins for the battery reference voltage
injBatRates = array, U08, 21, [6], "%", 1, 0, 0, 255, 0 ;Values for injector pulsewidth vs voltage
@ -2355,7 +2355,6 @@ menuDialog = main
battVCorMode = "The Battery Voltage Correction value from the table below can either be applied on the whole injection Pulse Width value, or only on the Open Time value."
dwellTable = "Sets the dwell time in milliseconds based on RPM/load. This can be used to reduce stress/wear on ignition system where long dwell is not needed. And other areas can use longer dwell value if needed for stronger spark. Battery voltage correction is applied for these dwell values."
useDwellMap = "In normal operation mode this is set to No and speeduino will use fixed running dwell value. But if different dwell values are required across engine RPM/load range, this can be set to Yes and separate Dwell table defines running dwell value."
tachoMode = "The output mode for the tacho pulse. Fixed timing will produce a pulse that is always of the same duration, which works better with mode modern digital tachos. Dwell based output creates a pulse that is matched to the coil/s dwell time. If enabled the tacho pulse duration and timing is same as coil dwell and the number of pulses is same as number of ignition events. This can work better on some styles of tacho but note that the pulse duration might become problem on higher cylinder number engines."
canBMWCluster = "Enables CAN broadcasting for BMW E46, E39 and E38 instrument clusters with message ID's 0x316, 0x329 and 0x545"
canVAGCluster = "Enables CAN broadcasting for VAG instrument clusters with message ID's 0x280 and 0x5A0"
caninputEndianess= "Byte ordering for values with two bytes."
@ -2835,7 +2834,7 @@ menuDialog = main
field = "Trigger Pattern", TrigPattern
field = "Primary base teeth", numTeeth, { TrigPattern == 0 || TrigPattern == 2 || TrigPattern == 11 || TrigPattern == 18 || TrigPattern == 19 || TrigPattern == 21 }
field = "Primary trigger speed", TrigSpeed, { TrigPattern == 0 || TrigPattern == 2 }
field = "Missing teeth", missingTeeth, { TrigPattern == 0 }
field = "Missing teeth", missingTeeth, { TrigPattern == 0 || TrigPattern == 2 }
field = "Trigger angle multiplier", TrigAngMul, { TrigPattern == 11 }
field = "Trigger Angle ", TrigAng
field = "This number represents the angle ATDC when "

View File

@ -784,20 +784,497 @@ Note: There can be no missing teeth on the primary wheel.
/** Dual Wheel Setup.
*
* */
byte doubleGapHalfTeeth=0;
byte doubleGap1=0, doubleGap2=0;
void triggerSetup_DualWheel(void)
{
// triggerToothAngle = 360 / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth
triggerToothAngle = 360 / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth
if(configPage4.TrigSpeed == CAM_SPEED) { triggerToothAngle = 720 / configPage4.triggerTeeth; } //Account for cam speed
if(configPage4.TrigSpeed == CAM_SPEED) { triggerToothAngle = 720 / configPage4.triggerTeeth; } //Account for cam speed
toothCurrentCount = 255; //Default value
triggerFilterTime = (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 discarded as noise
secondaryToothCount = 0;
triggerFilterTime = (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
triggerSecFilterTime = (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)
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //This is always true for this pattern
BIT_SET(decoderState, BIT_DECODER_HAS_SECONDARY);
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
// MAX_STALL_TIME = 166667 * triggerToothAngle; //1 rpm for testing
targetGap = 100000L; // random value larger than 0 to ensure we start off being less than target
toothLastToothTime = 0;
toothLastMinusOneToothTime = 0;
//------------
checkSyncToothCount = (configPage4.triggerTeeth) >> 2; //25% of the total teeth.
doubleGapHalfTeeth = configPage4.triggerTeeth / 2;
// this is the tooth after the gap
doubleGap1 = doubleGapHalfTeeth+1;
doubleGap2 = configPage4.triggerTeeth+1;
// Serial3.begin (38400);
}
#define toothAfterGap curGap3
void triggerPri_DualWheel_v2()
{
curTime = micros();
curGap = curTime - toothLastToothTime;
if ( curGap >= triggerFilterTime || toothLastMinusOneToothTime == 0) // ensure we do this code until we've seen 2 teeth
{
toothCurrentCount++; //Increment the tooth counter
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
// Serial3.print(" ");
// Serial3.print(toothCurrentCount);
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) )
{
//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 the gap
targetGap = ((toothLastToothTime - toothLastMinusOneToothTime)) * 2; //Multiply by 2 (Checks for a gap 2x greater than the last one)
if ( curGap > targetGap )
{
// Found a missing tooth, need to add additional missing teeth to toothCurrentCount & set missing tooth flag & triggerToothAngleIsCorrect to false
toothCurrentCount = toothCurrentCount + 2;
// Serial3.print(" GAP GAP");
// fake the last gap to ensure when we get to tooth 2 after the gap we don't get a silly large gap due to the missing teeth being part of the maths
curGap = toothLastToothTime - toothLastMinusOneToothTime;
toothLastToothTime = curTime - curGap;
toothLastMinusOneToothTime = toothLastToothTime - curGap;
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
// does the tooth = tooth after gap Should do otherwise lost sync
// all code could be simplifed to "if (toothCurrent == toothAfterGap) hassync else lost sync
if( (configPage2.nCylinders == 4 && toothCurrentCount != 19 && toothCurrentCount != 37 )
|| (configPage2.nCylinders == 6 && toothCurrentCount != 13 && toothCurrentCount != 25 && toothCurrentCount != 37 )
|| (configPage2.nCylinders == 8 && toothCurrentCount != 10 && toothCurrentCount != 19 && toothCurrentCount != 28 && toothCurrentCount != 37 )
)
{
// lost Sync as gap should be at the tooth after gap1 or gap2
// Serial3.print(" LostSYNC1 ");
// Serial3.print(toothCurrentCount);
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
triggerFilterTime = (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
toothLastToothTime = 0;
toothLastMinusOneToothTime = 0;
toothCurrentCount = toothAfterGap;
}
else
{
// now we think we're at the right place on crank, check if the cam is correct as well before calling sync
if ( toothCurrentCount == toothAfterGap )
{
currentStatus.hasSync = true;
}
else
{
// Serial3.print(" LostSYNC2 ");
// Serial3.print(toothAfterGap);
// Serial3.print(":");
// Serial3.print(toothCurrentCount);
// Serial3.print("> ");
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
triggerFilterTime = (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
toothLastToothTime = 0;
toothLastMinusOneToothTime = 0;
toothCurrentCount = toothAfterGap;
}
}
}
else
{
// no gap in trigger wheel, normal tooth
setFilter(curGap); //Recalc the new filter value
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
}
if ( currentStatus.hasSync == true )
{
if( toothCurrentCount > configPage4.triggerTeeth )
{
// Serial3.println(" ROT ");
toothCurrentCount = toothCurrentCount - configPage4.triggerTeeth ;
if( toothCurrentCount != 1)
{
// Serial3.print(" LostSYNC3");
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
toothCurrentCount = 1;
}
revolutionOne = !revolutionOne; //Flip sequential revolution tracker
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.startRevolutions++; //Counter
}
}
else
{
// no sync or not seen enough teeth - can't let trigger wheel tooth counter get greater than teeth on wheel
if (toothCurrentCount > configPage4.triggerTeeth)
{
toothCurrentCount = 1;
}
}
}
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
//NEW IGNITION MODE
if( (configPage2.perToothIgn == true) && (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
{
int16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
// crankAngle = ignitionLimits(crankAngle);
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
}
/** Dual Wheel Secondary.
*
* */
void triggerSec_DualWheel_v2()
{
curTime2 = micros();
curGap2 = curTime2 - toothLastSecToothTime;
if ( curGap2 >= triggerFilterTime) // filter at same rate as crank on assumption more teeth on crank than cam. Due to variable tooth gaps on cam this seems safer implementation of filtering
{
toothLastMinusOneSecToothTime = toothLastSecToothTime;
toothLastSecToothTime = curTime2;
switch(configPage4.trigPatternSec)
{
case SEC_TRIGGER_SINGLE:
if( (currentStatus.hasSync == false) || (currentStatus.startRevolutions <= configPage4.StgCycles) )
{
// no sync & only just started the engine and first time we've seen cam
toothLastToothTime = micros();
toothLastMinusOneToothTime = micros() - (6000000 / configPage4.triggerTeeth); //Fixes RPM at 10rpm until a full revolution has taken place
toothCurrentCount = configPage4.triggerTeeth;
triggerFilterTime = 0; //Need to turn the filter off here otherwise the first primary tooth after achieving sync is ignored
currentStatus.hasSync = true;
}
else
{
if ( (toothCurrentCount != configPage4.triggerTeeth) && (currentStatus.startRevolutions > 2)) { currentStatus.syncLossCounter++; } //Indicates likely sync loss.
if (configPage4.useResync == 1) { toothCurrentCount = configPage4.triggerTeeth; }
}
toothAfterGap = 1;
revolutionOne = 1; //Sequential revolution reset
//Record the VVT Angle
if( (configPage6.vvtEnabled > 0) && (revolutionOne == 1) )
{
int16_t curAngle;
curAngle = getCrankAngle();
while(curAngle > 360) { curAngle -= 360; }
curAngle -= configPage4.triggerAngle; //Value at TDC
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage10.vvtCL0DutyAng; }
currentStatus.vvt1Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt1Angle);
}
break;
case SEC_TRIGGER_NISSAN_1_3_4_2:
targetGap2 = targetGap * 4; // target gap to identify large gap between teeth. Assumes 4 is a reasonable size. Works for Nissan engine with this trigger pattern
if ( curGap2 >= targetGap2 )
{
// had a large gap betwen teeth and then seen a tooth. Use the counter to work out which tooth we've seen after the gap then reset the gap counter
// remember this is the cam tooth AFTER the tooth counted.
switch( secondaryToothCount)
{
case 2: //315 degrees on 4 cylinder
// is detected at the first tooth of the 1 tooth cam
revolutionOne = 0; //Sequential revolution reset
switch (configPage2.nCylinders)
{
case 4:
case 6:
case 8:
toothAfterGap = 37;
break;
}
break;
case 1: //135 degrees on 4 cylinder
// is detected at the first tooth of the 3 tooth cam pattern
revolutionOne = 0; //Sequential revolution reset
switch (configPage2.nCylinders)
{
case 4:
case 8:
toothAfterGap = 19;
break;
case 6:
toothAfterGap = 17;
break;
}
break;
case 3: //334.5 degrees on 4 cylinder
// is detected at the first tooth of the 4 tooth cam
revolutionOne = 1; //Sequential revolution reset
switch (configPage2.nCylinders)
{
case 4:
case 8:
case 6:
toothAfterGap = 37;
break;
}
break;
case 4: //155 degrees on 4 cylinder
// is detected at the first tooth of the 2 tooth cam
revolutionOne = 1; //Sequential revolution reset
switch (configPage2.nCylinders)
{
case 4:
case 8:
toothAfterGap = 19;
break;
case 6:
toothAfterGap = 17;
break;
}
if( (configPage6.vvtEnabled > 0) )
{
int16_t curAngle;
curAngle = getCrankAngle();
while(curAngle > 360) { curAngle -= 360; }
curAngle -= configPage4.triggerAngle; //Value at TDC
if( configPage6.vvtMode == VVT_MODE_CLOSED_LOOP ) { curAngle -= configPage10.vvtCL0DutyAng; }
currentStatus.vvt1Angle = ANGLE_FILTER( (curAngle << 1), configPage4.ANGLEFILTER_VVT, currentStatus.vvt1Angle);
}
break;
}
secondaryToothCount = 1;
}
else
{
secondaryToothCount++;
}
break;
default:
// have a cam selected that we don't have a decoder for.
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
break;
}
} //Trigger filter
}
void triggerSetEndTeeth_DualWheel_v2()
{
//The toothAdder variable is used for when a setup is running sequentially, but the primary wheel is running at crank speed. This way the count of teeth will go up to 2* the number of primary teeth to allow for a sequential count.
byte toothAdder = 0;
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (configPage4.TrigSpeed == CRANK_SPEED) ) { toothAdder = configPage4.triggerTeeth; }
int16_t tempIgnition1EndTooth;
tempIgnition1EndTooth = ( (ignition1EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition1EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition1EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition1EndTooth <= 0) { tempIgnition1EndTooth += (configPage4.triggerTeeth + toothAdder); }
int16_t tempIgnition2EndTooth;
tempIgnition2EndTooth = ( (ignition2EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition2EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition2EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition2EndTooth <= 0) { tempIgnition2EndTooth += (configPage4.triggerTeeth + toothAdder); }
int16_t tempIgnition3EndTooth;
tempIgnition3EndTooth = ( (ignition3EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition3EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition3EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition3EndTooth <= 0) { tempIgnition3EndTooth += (configPage4.triggerTeeth + toothAdder); }
int16_t tempIgnition4EndTooth;
tempIgnition4EndTooth = ( (ignition4EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition4EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition4EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition4EndTooth <= 0) { tempIgnition4EndTooth += (configPage4.triggerTeeth + toothAdder); }
#if IGN_CHANNELS >= 5
int16_t tempIgnition5EndTooth;
tempIgnition5EndTooth = ( (ignition5EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition5EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition5EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition5EndTooth <= 0) { tempIgnition5EndTooth += (configPage4.triggerTeeth + toothAdder); }
#endif
#if IGN_CHANNELS >= 6
int16_t tempIgnition6EndTooth;
tempIgnition6EndTooth = ( (ignition6EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition6EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition6EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition6EndTooth <= 0) { tempIgnition6EndTooth += (configPage4.triggerTeeth + toothAdder); }
#endif
#if IGN_CHANNELS >= 7
int16_t tempIgnition7EndTooth;
tempIgnition7EndTooth = ( (ignition7EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition7EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition7EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition7EndTooth <= 0) { tempIgnition7EndTooth += (configPage4.triggerTeeth + toothAdder); }
#endif
#if IGN_CHANNELS >= 8
int16_t tempIgnition8EndTooth;
tempIgnition8EndTooth = ( (ignition8EndAngle - configPage4.triggerAngle) / (int16_t)(triggerToothAngle) );
if(tempIgnition8EndTooth > (configPage4.triggerTeeth + toothAdder)) { tempIgnition8EndTooth -= (configPage4.triggerTeeth + toothAdder); }
if(tempIgnition8EndTooth <= 0) { tempIgnition8EndTooth += (configPage4.triggerTeeth + toothAdder); }
#endif
// take into account the missing teeth on the flywheels
if( configPage4.triggerMissingTeeth == 0)
{
ignition1EndTooth = tempIgnition1EndTooth;
ignition2EndTooth = tempIgnition2EndTooth;
ignition3EndTooth = tempIgnition3EndTooth;
ignition4EndTooth = tempIgnition4EndTooth;
#if IGN_CHANNELS >= 5
ignition5EndTooth = tempIgnition5EndTooth;
#endif
#if IGN_CHANNELS >= 6
ignition6EndTooth = tempIgnition6EndTooth;
#endif
#if IGN_CHANNELS >= 7
ignition7EndTooth = tempIgnition7EndTooth;
#endif
#if IGN_CHANNELS >= 8
ignition8EndTooth = tempIgnition8EndTooth;
#endif
}
else if (configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
{
// check the calculated trigger tooth exists, if it doesn't use the previous tooth
// nb the toothAngles[x] holds the tooth after the gap, hence the '-1' to see if it matches a gap
if( tempIgnition1EndTooth < configPage4.triggerTeeth) { ignition1EndTooth = triggerToothCalc_v2 (tempIgnition1EndTooth,0); } // 0 to 360 degrees
else { ignition1EndTooth = triggerToothCalc_v2 (tempIgnition1EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
if( tempIgnition2EndTooth < configPage4.triggerTeeth) { ignition2EndTooth = triggerToothCalc_v2 (tempIgnition2EndTooth,0); } // 0 to 360 degrees
else { ignition2EndTooth = triggerToothCalc_v2 (tempIgnition2EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
if( tempIgnition3EndTooth < configPage4.triggerTeeth) { ignition3EndTooth = triggerToothCalc_v2 (tempIgnition3EndTooth,0); } // 0 to 360 degrees
else { ignition3EndTooth = triggerToothCalc_v2 (tempIgnition3EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
if( tempIgnition4EndTooth < configPage4.triggerTeeth) { ignition4EndTooth = triggerToothCalc_v2 (tempIgnition4EndTooth,0); } // 0 to 360 degrees
else { ignition4EndTooth = triggerToothCalc_v2 (tempIgnition4EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
#if IGN_CHANNELS >= 5
if( tempIgnition5EndTooth < configPage4.triggerTeeth) { ignition5EndTooth = triggerToothCalc_v2 (tempIgnition5EndTooth,0); } // 0 to 360 degrees
else { ignition5EndTooth = triggerToothCalc_v2 (tempIgnition5EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
#endif
#if IGN_CHANNELS >= 6
if( tempIgnition6EndTooth < configPage4.triggerTeeth) { ignition6EndTooth = triggerToothCalc_v2 (tempIgnition6EndTooth,0); } // 0 to 360 degrees
else { ignition6EndTooth = triggerToothCalc_v2 (tempIgnition6EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
#endif
#if IGN_CHANNELS >= 7
if( tempIgnition7EndTooth < configPage4.triggerTeeth) { ignition7EndTooth = triggerToothCalc_v2 (tempIgnition7EndTooth,0); } // 0 to 360 degrees
else { ignition7EndTooth = triggerToothCalc_v2 (tempIgnition7EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
#endif
#if IGN_CHANNELS >= 8
if( tempIgnition8EndTooth < configPage4.triggerTeeth) { ignition8EndTooth = triggerToothCalc_v2 (tempIgnition8EndTooth,0); } // 0 to 360 degrees
else { ignition8EndTooth = triggerToothCalc_v2 (tempIgnition8EndTooth,configPage4.triggerTeeth); } // tooth is on the 360 to 720 degrees
#endif
}
else
{
ignition1EndTooth = triggerToothCalc_v2 (tempIgnition1EndTooth,0);
ignition2EndTooth = triggerToothCalc_v2 (tempIgnition2EndTooth,0);
ignition3EndTooth = triggerToothCalc_v2 (tempIgnition3EndTooth,0);
ignition4EndTooth = triggerToothCalc_v2 (tempIgnition4EndTooth,0);
#if IGN_CHANNELS >= 5
ignition5EndTooth = triggerToothCalc_v2 (tempIgnition5EndTooth,0); // 0 to 360 degrees
#endif
#if IGN_CHANNELS >= 6
ignition6EndTooth = triggerToothCalc_v2 (tempIgnition6EndTooth,0); // 0 to 360 degrees
#endif
#if IGN_CHANNELS >= 7
ignition7EndTooth = triggerToothCalc_v2 (tempIgnition7EndTooth,0); // 0 to 360 degrees
#endif
#if IGN_CHANNELS >= 8
ignition8EndTooth = triggerToothCalc_v2 (tempIgnition8EndTooth,0); // 0 to 360 degrees
#endif
}
lastToothCalcAdvance = currentStatus.advance;
}
char triggerToothCalc_v2(int16_t tempIgnitionEndTooth, byte tempSequentialTooth)
{
switch(configPage2.nCylinders)
{
case 4:
if(tempIgnitionEndTooth == 17 || tempIgnitionEndTooth == 18)
{ tempIgnitionEndTooth = 16;}
else if (tempIgnitionEndTooth == 35 || tempIgnitionEndTooth == 36)
{ tempIgnitionEndTooth = 34;}
break;
case 6:
if(tempIgnitionEndTooth == 11 || tempIgnitionEndTooth == 12)
{ tempIgnitionEndTooth = 10;}
else if (tempIgnitionEndTooth == 23 || tempIgnitionEndTooth == 24)
{ tempIgnitionEndTooth = 22;}
else if (tempIgnitionEndTooth == 35 || tempIgnitionEndTooth == 36)
{ tempIgnitionEndTooth = 34;}
break;
case 8:
if(tempIgnitionEndTooth == 8 || tempIgnitionEndTooth == 9)
{ tempIgnitionEndTooth = 7;}
else if (tempIgnitionEndTooth == 17 || tempIgnitionEndTooth == 18)
{ tempIgnitionEndTooth = 16;}
else if (tempIgnitionEndTooth == 26 || tempIgnitionEndTooth == 27)
{ tempIgnitionEndTooth = 25;}
else if (tempIgnitionEndTooth == 35 || tempIgnitionEndTooth == 36)
{ tempIgnitionEndTooth = 34;}
break;
}
return tempIgnitionEndTooth;
}
/** Dual Wheel Primary.
*
* */
@ -4808,7 +5285,6 @@ void triggerPri_Vmax(void)
toothOneTime = curTime;
currentStatus.hasSync = true;
setFilter((curGap/1.75));//Angle to this tooth is 70, next is in 40, compensating.
currentStatus.startRevolutions++; //Counter
}
else if (toothCurrentCount==2)
{
@ -4842,6 +5318,7 @@ void triggerPri_Vmax(void)
}
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
currentStatus.startRevolutions++; //Counter
if (triggerFilterTime > 50000){//The first pulse seen
triggerFilterTime = 0;
}

View File

@ -288,6 +288,7 @@
#define SEC_TRIGGER_4_1 1
#define SEC_TRIGGER_POLL 2
#define SEC_TRIGGER_5_3_2 3
#define SEC_TRIGGER_NISSAN_1_3_4_2 4
#define ROTARY_IGN_FC 0
#define ROTARY_IGN_FD 1
@ -1056,7 +1057,7 @@ struct config6 {
byte useExtBaro : 1;
byte boostMode : 1; /// Boost control mode: 0=Simple (BOOST_MODE_SIMPLE) or 1=full (BOOST_MODE_FULL)
byte boostPin : 6;
byte tachoMode : 1; /// Whether to use fixed tacho pulse duration or match to dwell duration
byte unused_bit : 1; //Previously was VVTasOnOff
byte useEMAP : 1; ///< Enable EMAP
byte voltageCorrectionBins[6]; //X axis bins for voltage correction tables
byte injVoltageCorrectionValues[6]; //Correction table for injector PW vs battery voltage

View File

@ -1953,7 +1953,6 @@ void setPinMapping(byte boardID)
pinTrigger3 = 20; //The Cam sensor 2 pin
pinTPS = A2;//TPS input pin
pinMAP = A3; //MAP sensor pin
pinEMAP = A15; //EMAP sensor pin
pinIAT = A0; //IAT sensor pin
pinCLT = A1; //CLT sensor pin
pinO2 = A8; //O2 Sensor pin
@ -1975,11 +1974,6 @@ void setPinMapping(byte boardID)
pinFlex = 2; // Flex sensor
pinResetControl = 43; //Reset control output
pinVSS = 3; //VSS input pin
pinWMIEmpty = 31; //(placeholder)
pinWMIIndicator = 33; //(placeholder)
pinWMIEnabled = 35; //(placeholder)
pinIdleUp = 37; //(placeholder)
pinCTPS = A6; //(placeholder)
#elif defined(STM32F407xx)
pinInjector1 = PB15; //Output pin injector 1
pinInjector2 = PB14; //Output pin injector 2
@ -2001,7 +1995,6 @@ void setPinMapping(byte boardID)
pinTrigger2 = PD4; //The Cam Sensor pin
pinTPS = PA2;//TPS input pin
pinMAP = PA3; //MAP sensor pin
pinEMAP = PC5; //EMAP sensor pin
pinIAT = PA0; //IAT sensor pin
pinCLT = PA1; //CLS sensor pin
pinO2 = PB0; //O2 Sensor pin
@ -2023,11 +2016,6 @@ void setPinMapping(byte boardID)
pinFlex = PD7; // Flex sensor
pinResetControl = PB7; //Reset control output
pinVSS = PB6; //VSS input pin
pinWMIEmpty = PD15; //(placeholder)
pinWMIIndicator = PD13; //(placeholder)
pinWMIEnabled = PE15; //(placeholder)
pinIdleUp = PE14; //(placeholder)
pinCTPS = PA6; //(placeholder)
#endif
break;
@ -2388,52 +2376,6 @@ void setPinMapping(byte boardID)
#endif
break;
case 56:
#if defined(CORE_TEENSY)
//Pin mappings for the Bear Cub (Teensy 4.1)
pinInjector1 = 6;
pinInjector2 = 7;
pinInjector3 = 9;
pinInjector4 = 8;
pinInjector5 = 0; //Not used
pinCoil1 = 2;
pinCoil2 = 3;
pinCoil3 = 4;
pinCoil4 = 5;
pinTrigger = 20; //The CAS pin
pinTrigger2 = 21; //The Cam Sensor pin
pinFlex = 37; // Flex sensor
pinMAP = A5; //MAP sensor pin
pinBaro = A4; //Baro sensor pin
pinBat = A15; //Battery reference voltage pin
pinTPS = A3; //TPS input pin
pinIAT = A0; //IAT sensor pin
pinCLT = A1; //CLS sensor pin
pinO2 = A2; //O2 Sensor pin
pinLaunch = 36;
pinSpareTemp1 = A16; //spare Analog input 1
pinSpareTemp2 = A17; //spare Analog input 2
pinTachOut = 38; //Tacho output pin
pinIdle1 = 27; //Single wire idle control
pinIdle2 = 26; //2 wire idle control. Shared with Spare 1 output
pinFuelPump = 10; //Fuel pump output
pinVVT_1 = 28; //Default VVT output
pinStepperDir = 32; //Direction pin for DRV8825 driver
pinStepperStep = 31; //Step pin for DRV8825 driver
pinStepperEnable = 30; //Enable pin for DRV8825 driver
pinBoost = 24; //Boost control
pinSpareLOut1 = 29; //low current output spare1
pinSpareLOut2 = 26; //low current output spare2
pinSpareLOut3 = 28; //low current output spare3
pinSpareLOut4 = 29; //low current output spare4
pinFan = 25; //Pin for the fan output
pinResetControl = 46; //Reset control output PLACEHOLDER value for now
#endif
break;
@ -3186,13 +3128,13 @@ void initialiseTriggers(void)
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
break;
case 2:
case DECODER_DUAL_WHEEL:
triggerSetup_DualWheel();
triggerHandler = triggerPri_DualWheel;
triggerSecondaryHandler = triggerSec_DualWheel;
getRPM = getRPM_DualWheel;
triggerHandler = triggerPri_DualWheel_v2;
triggerSecondaryHandler = triggerSec_DualWheel_v2;
getCrankAngle = getCrankAngle_DualWheel;
triggerSetEndTeeth = triggerSetEndTeeth_DualWheel;
triggerSetEndTeeth = triggerSetEndTeeth_DualWheel_v2;
getRPM = getRPM_DualWheel;
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
else { primaryTriggerEdge = FALLING; }

View File

@ -52,6 +52,9 @@ unsigned long EMAPrunningValue; //As above but for EMAP
unsigned int MAPcount; //Number of samples taken in the current MAP cycle
uint32_t MAPcurRev; //Tracks which revolution we're sampling on
bool auxIsEnabled;
byte TPSlast; /**< The previous TPS reading */
unsigned long TPS_time; //The time the TPS sample was taken
unsigned long TPSlast_time; //The time the previous TPS sample was taken
uint16_t MAPlast; /**< The previous MAP reading */
unsigned long MAP_time; //The time the MAP sample was taken
unsigned long MAPlast_time; //The time the previous MAP sample was taken

View File

@ -399,7 +399,8 @@ static inline void readMAP(void)
void readTPS(bool useFilter)
{
currentStatus.TPSlast = currentStatus.TPS;
TPSlast = currentStatus.TPS;
TPSlast_time = TPS_time;
#if defined(ANALOG_ISR)
byte tempTPS = fastMap1023toX(AnChannel[pinTPS-A0], 255); //Get the current raw TPS ADC value and map it into a byte
#else
@ -440,6 +441,7 @@ void readTPS(bool useFilter)
else { currentStatus.CTPSActive = digitalRead(pinCTPS); } //Inverted mode (5v activates closed throttle position sensor)
}
else { currentStatus.CTPSActive = 0; }
TPS_time = micros();
}
void readCLT(bool useFilter)

View File

@ -491,7 +491,7 @@ void doUpdates(void)
configPage10.TrigEdgeThrd = 0;
//Old use as On/Off selection is removed, so change VVT mode to On/Off based on that
if(configPage6.tachoMode == 1) { configPage6.vvtMode = VVT_MODE_ONOFF; }
if(configPage6.unused_bit == 1) { configPage6.vvtMode = VVT_MODE_ONOFF; }
//Closed loop VVT improvements. Set safety limits to max/min working values and filter to minimum.
configPage10.vvtCLMinAng = 0;
@ -619,7 +619,6 @@ void doUpdates(void)
}
configPage9.hardRevMode = 1; //Set hard rev limiter to Fixed mode
configPage6.tachoMode = 0;
//CAN broadcast introduced
configPage2.canBMWCluster = 0;

View File

@ -1,6 +1,5 @@
#include <Arduino.h>
#include <globals.h>
#include <unity.h>
#include "missing_tooth/missing_tooth.h"

View File

@ -8,7 +8,6 @@ void testCorrections()
{
test_corrections_WUE();
test_corrections_dfco();
test_corrections_TAE(); //TPS based accel enrichment corrections
/*
RUN_TEST(test_corrections_cranking); //Not written yet
RUN_TEST(test_corrections_ASE); //Not written yet
@ -141,7 +140,7 @@ void setup_DFCO_on()
correctionDFCO();
dfcoTaper = 20;
}
//**********************************************************************************************************************
void test_corrections_dfco_on(void)
{
//Test under ideal conditions that DFCO goes active
@ -186,11 +185,6 @@ void test_corrections_dfco()
RUN_TEST(test_corrections_dfco_off_TPS);
RUN_TEST(test_corrections_dfco_off_delay);
}
//**********************************************************************************************************************
//Setup a basic TAE enrichment curve, threshold etc that are common to all tests. Specifica values maybe updated in each individual test
void test_corrections_TAE_setup()
{
configPage2.aeMode = AE_MODE_TPS; //Set AE to TPS
configPage4.taeValues[0] = 70;
configPage4.taeValues[1] = 103;

View File

@ -9,5 +9,4 @@ void test_corrections_bat(void);
void test_corrections_iatdensity(void);
void test_corrections_baro(void);
void test_corrections_launch(void);
void test_corrections_dfco(void);
void test_corrections_TAE(void);
void test_corrections_dfco(void);