- Thu Sep 09, 2021 10:58 am
#52998
Hi,
I`m trying to get this flywheel working using the ardustim but I`m having some issues: I`m using the change trigger in the setup and the code below syncs on the wider lobe. So there is a routine checking the width of a lobe compare with the others. When the wider lobe is found, the secondaryToothCount is set to 1. This syncs just fine, no problems.
Next, the toothCurrentCount starts to increase when the upward edge of a lobe is seen. This then starts counting the lobes and their degrees etc. Below, i`ve compensated for the uneven distances between lobes and the RPM works great, using the per-lobe measurement while cranking and the per-rotation when above cranking. The same for the getRPM. If I output the actual degrees for reach lobe and the output of getRPM, the calculations work perfect: the getRPM degrees increase and reach the next lobe degrees when that lobe is seen.
So all should be well. However, when looking at the LED`s on the Ardustim, I can see the led`s flicker when increasing or decreasing RPM. When the RPM is the same, they are lit nicely but flicker once every 1 or 2 seconds. So even though the trigger seems perfect, the ignition and injection routines don't seem to agree. Can anyone point me into a direction where to look? The only thing I haven't changed is the triggerSetEndTeeth so perhaps there`s some modification required there....
Thanks!
I`m trying to get this flywheel working using the ardustim but I`m having some issues: I`m using the change trigger in the setup and the code below syncs on the wider lobe. So there is a routine checking the width of a lobe compare with the others. When the wider lobe is found, the secondaryToothCount is set to 1. This syncs just fine, no problems.
Next, the toothCurrentCount starts to increase when the upward edge of a lobe is seen. This then starts counting the lobes and their degrees etc. Below, i`ve compensated for the uneven distances between lobes and the RPM works great, using the per-lobe measurement while cranking and the per-rotation when above cranking. The same for the getRPM. If I output the actual degrees for reach lobe and the output of getRPM, the calculations work perfect: the getRPM degrees increase and reach the next lobe degrees when that lobe is seen.
So all should be well. However, when looking at the LED`s on the Ardustim, I can see the led`s flicker when increasing or decreasing RPM. When the RPM is the same, they are lit nicely but flicker once every 1 or 2 seconds. So even though the trigger seems perfect, the ignition and injection routines don't seem to agree. Can anyone point me into a direction where to look? The only thing I haven't changed is the triggerSetEndTeeth so perhaps there`s some modification required there....
Thanks!
Code: Select all
void triggerSetup_GM7X()
{
triggerActualTeeth = 6;
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
triggerFilterTime = 0;
secondDerivEnabled = false;
decoderIsSequential = false;
toothCurrentCount = 0; //Default value
decoderHasFixedCrankingTiming = true;
triggerToothAngleIsCorrect = true;
secondaryToothCount = 0;
if(configPage2.nCylinders <= 4) { MAX_STALL_TIME = (1851UL * triggerToothAngle); }//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
else { MAX_STALL_TIME = (3200UL * triggerToothAngle); } //Minimum 50rpm. (3200uS is the time per degree at 50rpm).
toothAngles[1] = 0; //Rising edge of tooth #1
toothAngles[2] = 40; //Rising edge of tooth #2
toothAngles[3] = 110; //Rising edge of tooth #3
toothAngles[4] = 180; //Rising edge of tooth #4
toothAngles[5] = 220; //Rising edge of tooth #5
toothAngles[6] = 290; //Rising edge of tooth #6
}
void triggerPri_GM7X()
{
curTime = micros();
if(READ_PRI_TRIGGER() == false){// Inverted due to vr conditioner.
curGap3 = curTime;
if (secondaryToothCount==1){
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.startRevolutions++; //Counter
toothCurrentCount=1;
}
else if (secondaryToothCount>1) {//Update the counter, but not when it`s zero.
toothCurrentCount++;
}
if( (toothCurrentCount == 1) || (toothCurrentCount == 4 )){
triggerToothAngle = 40;
}
else{
triggerToothAngle = 70;
}
}
else{
targetGap = curTime - curGap3;
if (targetGap > (lastGap * 4)){// Small lobe is 5 degrees, big lobe is 45.
if (secondaryToothCount == 0 || secondaryToothCount == 6){// We measure the width of a lobe so on the end of one, but want to trigger on the beginning to even the events out. Therefore, secondaryToothCount tracks the DOWNWARD events, and toothCurrentCount updates on the upward events.
currentStatus.hasSync = true;
}
else{
currentStatus.syncLossCounter++;
}
secondaryToothCount = 1;
}
else if(secondaryToothCount == 6){
secondaryToothCount = 1;
currentStatus.syncLossCounter++;
}
else{
secondaryToothCount++;
}
lastGap = targetGap;
return;
}
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
if ( configPage4.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
{
endCoil1Charge();
endCoil2Charge();
endCoil3Charge();
endCoil4Charge();
}
if(configPage2.perToothIgn == true)
{
int16_t crankAngle = toothAngles[toothCurrentCount] + configPage4.triggerAngle;
crankAngle = ignitionLimits((crankAngle));
if(toothCurrentCount > (triggerActualTeeth/2) ) { checkPerToothTiming(crankAngle, (toothCurrentCount - (triggerActualTeeth/2))); }
else { checkPerToothTiming(crankAngle, toothCurrentCount); }
}
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
}
void triggerSec_GM7X() { return; } //Not required
uint16_t getRPM_GM7X()
{
uint16_t tempRPM = 0;
//During cranking, RPM is calculated 6 times per revolution, once for each rising/falling of the crank signal.
//Because these signals aren't even (Alternating 70 and 40 degrees), this needs a special function
if(currentStatus.hasSync == true)
{
if( (currentStatus.RPM < currentStatus.crankRPM) )
{
int tempToothAngle;
unsigned long toothTime;
if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { tempRPM = 0; }
else
{
noInterrupts();
tempToothAngle = triggerToothAngle;
toothTime = (toothLastToothTime - toothLastMinusOneToothTime); //Note that trigger tooth angle changes between 70 and 110 depending on the last tooth that was seen (or 70/50 for 6 cylinders)
interrupts();
toothTime = toothTime * 36;
tempRPM = ((unsigned long)tempToothAngle * 6000000UL) / toothTime;
if (toothCurrentCount==1 || toothCurrentCount==4){
tempRPM = tempRPM*1.75;
}
else if (toothCurrentCount==2 || toothCurrentCount==5 ){
tempRPM = tempRPM*0.57;
}
revolutionTime = (10UL * toothTime) / tempToothAngle;
MAX_STALL_TIME = 366667UL; // 50RPM
}
}
else
{
tempRPM = stdGetRPM(360);
MAX_STALL_TIME = revolutionTime << 1; //Set the stall time to be twice the current RPM. This is a safe figure as there should be no single revolution where this changes more than this
if(MAX_STALL_TIME < 366667UL) { MAX_STALL_TIME = 366667UL; } //Check for 50rpm minimum
}
}
return tempRPM;
}
int getCrankAngle_GM7X()
{
//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 = toothAngles[toothCurrentCount] + configPage4.triggerAngle;
//Estimate the number of degrees travelled since the last tooth}
elapsedTime = (lastCrankAngleCalc - tempToothLastToothTime);
// Compensating for the uneven teeth. Sometimes 40/70, sometimes 70/40 and sometimes just 1.
if (toothCurrentCount==1 || toothCurrentCount==4){
crankAngle += timeToAngle(elapsedTime, CRANKMATH_METHOD_INTERVAL_TOOTH)*1.75;
}
else if (toothCurrentCount==2 || toothCurrentCount==5 ){
crankAngle += timeToAngle(elapsedTime, CRANKMATH_METHOD_INTERVAL_TOOTH)*0.57;
}
else{
crankAngle += timeToAngle(elapsedTime, CRANKMATH_METHOD_INTERVAL_TOOTH);
}
if (crankAngle >= 720) { crankAngle -= 720; }
if (crankAngle > CRANK_ANGLE_MAX) { crankAngle -= CRANK_ANGLE_MAX; }
if (crankAngle < 0) { crankAngle += CRANK_ANGLE_MAX; }
return crankAngle;
}
void triggerSetEndTeeth_GM7X()
{
int tempEndAngle = (ignition1EndAngle - configPage4.triggerAngle);
tempEndAngle = ignitionLimits((tempEndAngle));
if( (tempEndAngle > 180) || (tempEndAngle <= 0) )
{
ignition1EndTooth = 2;
ignition2EndTooth = 1;
}
else
{
ignition1EndTooth = 1;
ignition2EndTooth = 2;
}
lastToothCalcAdvance = currentStatus.advance;
}