Any general discussion around the firmware, what is does, how it does it etc.
So id like to use the speeduino in my 97 2.5L wrangler but the Jeep 2000 is meant for the 4.0L which has different spacing of the notches on the flywheel/flexplate than the 2.5L. it also has a different but similar trigger wheel for the sequential injection in the distributor.

here is the 4.0L flywheel
jeep2000-ang.jpg (97.51 KiB) Viewed 6829 times
here is the 2.5 (sorry for the odd angle.... its the only pic i could find)
jeep 2_5 flywheel .jpg
jeep 2_5 flywheel .jpg (149.26 KiB) Viewed 6829 times
here are the differences in angles between the notches between the 2.5 and 4.0L
cpsdiagramm.gif (21.78 KiB) Viewed 6829 times
I compared what was in the decoder code for the 4.0L and the images that I had and made some changes to what i think would work given the comments in the code and the differences in trigger wheel patterns.

think this will work?
Code: Select all
void triggerSetup_Jeep2000()// BB Modified for the 2.5L Jeep 4 Cyl with the similar style, but less pulses on the crank trigger and distributor/cam wheel. 
  triggerToothAngle = 0; //The number of degrees that passes from tooth to tooth (primary)
  toothAngles[0] = 294;
  toothAngles[1] = 314;
  toothAngles[2] = 334;
  toothAngles[3] = 354;
  toothAngles[4] = 474;
  toothAngles[5] = 494;
  toothAngles[6] = 514;
  toothAngles[7] = 534;

  MAX_STALL_TIME = (3333UL * 120); //Minimum 50rpm. (3333uS is the time per degree at 50rpm). Largest gap between teeth is 60 degrees. (BB, I put 120 instead of 60 because the gap between the pulse groups is 120??)
  if(initialisationComplete == false) { toothCurrentCount = 9; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
  secondDerivEnabled = false;
  decoderIsSequential = false;
  triggerToothAngleIsCorrect = true;

void triggerPri_Jeep2000()
  if(toothCurrentCount == 9) { currentStatus.hasSync = false; } //Indicates sync has not been achieved (Still waiting for 1 revolution of the crank to take place) (BB changed)
    curTime = micros();
    curGap = curTime - toothLastToothTime;
    if ( curGap >= triggerFilterTime )
      if(toothCurrentCount == 0)
         toothCurrentCount = 1; //Reset the counter
         toothOneMinusOneTime = toothOneTime;
         toothOneTime = curTime;
         currentStatus.hasSync = true;
         currentStatus.startRevolutions++; //Counter
         triggerToothAngle = 120; //There are groups of 4 pulses (Each 20 degrees apart), with each group being 60 degrees apart. Hence #1 is always 60 (BB Changed)
        toothCurrentCount++; //Increment the tooth counter
        triggerToothAngle = toothAngles[(toothCurrentCount-1)] - toothAngles[(toothCurrentCount-2)]; //Calculate the last tooth gap in degrees

      setFilter(curGap); //Recalc the new filter value

      validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)

      toothLastMinusOneToothTime = toothLastToothTime;
      toothLastToothTime = curTime;
    } //Trigger filter
  } //Sync check
void triggerSec_Jeep2000()
  toothCurrentCount = 0; //All we need to do is reset the tooth count back to zero, indicating that we're at the beginning of a new revolution

uint16_t getRPM_Jeep2000()
   return stdGetRPM(360);
int getCrankAngle_Jeep2000()
    //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.
    tempToothCurrentCount = toothCurrentCount;
    tempToothLastToothTime = toothLastToothTime;
    lastCrankAngleCalc = micros(); //micros() is no longer interrupt safe

    int crankAngle;
    if (toothCurrentCount == 0) { crankAngle = 236 + configPage4.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. BB Change 236 is the angle at which the crank tooth goes high.
    else { 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_Jeep2000()

  lastToothCalcAdvance = currentStatus.advance;
The things Im a little foggy on are where I changed the 60 degree values to 120 degree values based on the difference in degrees between the notch groups.


Brian Bucar
I put $100 USD down for someone to write up code to use MAP signal for sequential cycle sync.

It was apparently not enough money or no one had any interest at all.

So I will be trying a second MAP sensor connected to only cylinder 1 ITB and wire it to the VR2 input as that "may" work.
yeah i am going to do that. im waiting on some multi colored wiring so I can make a harness. then ill tap into the crank and cam signals and see if it syncs and reads RPM.

worst case it probably wont sync or show RPM. it wont hurt anything.

I just have 2 constants that I changed that im not sure if i changed them correctly. (the ones that I changed from 60-120.)


Thanks for the post. Any progress? I can mostly only provide moral support. What coil / plug setup does the 1997 have and are you running something different? You mentioned logic level coils in another post. Any progress? I have 1994 YJ 4cyl which still has a distributor so I am planning to use Basic Distributor decoder. I will consider COP someday but for now I am seeing how simple/cheap it can be done. I am also running v0.4 DetonationEMS 1.3 and will be using your tinkercad file.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 9

Away on trips and attending wedding/funeral so won[…]

J35a4 Triggers

I did speak to someone about a j30 decoder, but […]


&gt;&gt; One thing to know is, that the […]

awesome, if you need guinea pig for the road testi[…]

Still can't find what you're looking for?