Speeduino is now on Github Sponsors (Rather than Patreon): https://github.com/sponsors/noisymime
Any general discussion around the firmware, what is does, how it does it etc.
By frase29
#31281
Hi guys,

I'm new to speeduino though have spent a fair while on megasquirt and done a small amount of arduino code before... I'm currently looking at coding in the Rover 36-1-1-1-1 trigger pattern code - detail here - and I think I've got it working fairly robustly (it's entirely possible I'm totally off the mark with it, but it seems to work from an Ardustim!).

Couple of things to note first - I've not yet twigged how to modify the .ini and other required code to make it a selectable option in tunerstudio, and pointers on this would be very helpful! This is why at the moment I've got it down as the subaru 36-2-2-2 code, as this is the decoder that's most similar to what i want so was a sensible base, obviously needs changed in the long run...

If anyone's able to give it a quick skim and give me any pointers (especially on how to make it a separate option!) that would be great.

So far in testing with a stim it seems robust, has sensible error checking for missing tooth found in the wrong place or tooth found where missing tooth expected etc, will be aiming to test it on the car as soon as I can... The RPM reading is a little off on cranking as it tries to work out rpm per-tooth, but that's not really an issue, and certainly something that could be sorted quickly and easily with a getrpm function similar to the missing tooth one, just with more exceptions for the four missing teeth.

Oh and if anyone can tell me what the ' triggerSetEndTeeth' function actually does that would be great - I expect that is something I'll need to change at some point but at the moment I've no idea what it actually does...
Code: Select all
void triggerSetup_ThirtySixMinus222()
{
  triggerToothAngle = 10; //The number of degrees that passes from tooth to tooth
  triggerActualTeeth = 32; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
  triggerFilterTime = (int)(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
  secondDerivEnabled = false;
  decoderIsSequential = false;
  checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
  toothLastMinusOneToothTime = 0;
  toothCurrentCount = 0;
  toothOneTime = 0;
  toothOneMinusOneTime = 0;
  sinceMiss=4;
  MAX_STALL_TIME = (3333UL * triggerToothAngle * 2 ); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
}

void triggerPri_ThirtySixMinus222()
{
   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
     sinceMiss++; //Increment teeth since missing tooth counter 
     addToothLogEntry(curGap);

     //Begin the missing tooth detection
     //If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after a gap
     
     { targetGap = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) >> 1; } //Multiply by 1.5 (Checks for a gap 2x greater than the last one)


     if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; }

     if ( (curGap > targetGap) )
     {
      if( (currentStatus.hasSync == false) || (toothCurrentCount == 14)|| (toothCurrentCount == 17)|| (toothCurrentCount == 32)|| (toothCurrentCount == 36))
      //checks that missing tooth is in the right place (or sync has not yet been found)
      { 
       {
         if(sinceMiss == 3)
         {
           //This occurs when where at the first tooth after the two missing teeth with three teeth between them
           toothCurrentCount = 1;
           revolutionOne = !revolutionOne; //Flip sequential revolution tracker
           toothOneMinusOneTime = toothOneTime;
           toothOneTime = curTime;
           currentStatus.startRevolutions++; //Counter
           currentStatus.hasSync = true;
         }

         else
         {
           //We've seen a missing tooth, but it's not the specific one we're looking for for sync
           toothCurrentCount++; //Accurately reflect the actual tooth count, including the skipped ones
         }
         
         triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
         triggerFilterTime = 0; //This is used to prevent a condition where serious intermitent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
         sinceMiss = 0; //Resets the counter
       }
     }
     else  //enters this if missing tooth found at the wrong time 
     {
      currentStatus.hasSync = false;
      currentStatus.syncLossCounter++;
     }
     }
     
     
     
     else //enters this code if a normal tooth is found, checks it is not where a missing tooth was expected, if currently in sync
     {
      if ((currentStatus.hasSync == true) &&( (toothCurrentCount == 14)|| (toothCurrentCount == 17)|| (toothCurrentCount == 32)|| (toothCurrentCount == 36)))
      {
        currentStatus.hasSync = false;
        currentStatus.syncLossCounter++;
      }


       //Filter can only be recalc'd for the regular teeth, not the missing one.
       setFilter(curGap);

       triggerToothAngleIsCorrect = true;
  
     }

     toothLastMinusOneToothTime = toothLastToothTime;
     toothLastToothTime = curTime;

     //EXPERIMENTAL!
     if(configPage2.perToothIgn == true)
     {
       uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
       checkPerToothTiming(crankAngle, toothCurrentCount);
     }

   }
}

void triggerSec_ThirtySixMinus222()
{
  //NOT USED - This pattern uses the missing tooth version of this function
}

int getCrankAngle_ThirtySixMinus222()
{
    //NOT USED - This pattern uses the missing tooth version of this function
    return 0;
}

void triggerSetEndTeeth_ThirtySixMinus222() //no idea what this means, guess I should work it out at some point
{
  if(currentStatus.advance < 10) { ignition1EndTooth = 36; }
  else if(currentStatus.advance < 20) { ignition1EndTooth = 35; }
  else if(currentStatus.advance < 30) { ignition1EndTooth = 34; }
  else { ignition1EndTooth = 31; }

  if(currentStatus.advance < 30) { ignition2EndTooth = 16; }
  else { ignition2EndTooth = 13; }

  lastToothCalcAdvance = currentStatus.advance;
}
By KLAS
#31465
just to push it a bit ;)

if i would like to try it, do i just replace the 36-2-2-2 code part with yours?
will timing be correct as factory? or would i have to adjust it?
By frase29
#31468
You'll need to copy that code over the 36-2-2-2 code, and you'll have to add the line 'volatile int sinceMiss;' into decoders.h, I put it near the bottom but this is just setup so doesn't really matter where you put it, I don't think!

Timing definitely won't be correct to factory - I *think* you'll want to set the trigger angle in tunerstudio to around -90, but this will definitely need checking and setting up with a timing light before you try and run it - I could be totally wrong as I've not tried it on a car yet, please go carefully!

Would be great if you could give it a go, even just trying cranking with no fuel or ignition hooked up to see if it syncs! I've got very little time to fiddle with cars outside of uni holidays, but hopefully will be able to get my own going in the next few weeks... What car are you using it on?
By KLAS
#31477
great, sounds like I could handle that.
I have some time at hand ATM, but no clue about coding, but copy and paste should work for me.
I have a 1999 Rover 214, one of the few here in Germany
By ADVN_SYS
#34144
Hi frase29,

I have tested your code with some fix it work fine on ardustim and it sync on mems 3 but for the trigger angle i think for MG TF , you should set atdc angle at 315 (45btdc) but i'm not sure. I have already tried at 305 (55btdc) ,320(40 btdc) 325(35btdc) with no success. I know my injector and spark work because of the ecu work on ardustim.

If i can help or anyone have solution i'm here :D .Thanks
By frase29
#34145
yeah recent updates to the overall speeduino code have meant there need to be a couple of changes to the above code! Have you tested the code on a car? I've still not got round to doing it but seems to work fine on ardustim, firing injector and ignition LEDs. What exactly is the issue you're having? changing the angle shouldn't make the difference between having spark or not, it'll only affect when the spark is fired (and so whether or not the engine runs/runs correctly)
By ADVN_SYS
#34164
I have tested it on my car, I have spark i have fuel, sync is good, sometimes it backfire but no starting.I think if the trigger angle is the correct angle ,it should starting up.
By frase29
#34242
Great to know it syncs on a car - it's really best to check timing with a timing light, as otherwise you're just guessing blind, have you tried one? If everything is spot on with a tune you might get away with just keeping trying a full 360 sweep of trigger angle, but it's a lot easier, and quicker, to test and properly adjust with a timing light, and then chase down any other issues that might be stopping it from running!
By ADVN_SYS
#34809
Hi frase29,
I have start up yesterday so the trigger angle for MEMS 3 K series (CKP position at 55 BTDC) is around 235 degres ATDC in speeduino.
I will post your correct base code with the update soon.

Thank for your BIG help :D !

Sounds like you have a short! Undo the sensor amen[…]

Ive not looked at the log, but you probably need t[…]

ATmega2561?

2561 also has its advantages Nice video! BTW wha[…]

blitzbox

The BlitzBox does already exist in a first testin[…]

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