Thursday, 10 May 2012

New battery

I got bored of my car not starting so bought a new battery.
This didn't help at all (bit annoying that), but the battery is bigger and seems to make the engine run smoother.  Specifically the voltage is more stable which previously impacted the injection times quite a lot.

The other issue was that turning the lights (HID ones) previously would stop the engine (due to voltage drop) unless the RPM's were up, now the lights or fan have no effect on the engine.

All good stuff.

Battery is a PC680 (with metal jacket), and I have mounted in the passenger footwell, with remote connections in the engine bay.

If only it would stop raining.

2012 Starting again

So, where have I been??

Mostly I have been trying to sort out a garage.  Lots of clearing away shrubs and soil.  Rebuilding walls, planning the building and struggling with the council and their contrived rules.

It looks like the planning permission has gone through so hopefully I should be able to get a garage built before next winter.


Back to my car.
For the longest time I have had problems starting my engine. The issue was that the crank on my engine is lightened to the extreme, and so when cranking the compression effect slows and speeds the cranking rate.  The consequence of this is that the tooth spacings are not equal.  The effect of this when cranking is that the long tooth isn't detected reliably.

The algorithm (in ms2extra) requires the missing tooth (nominally 2x a normal tooth gap) to be 1.5x the tooth before it, and the tooth after the long tooth to be less than 3/4 of the length of the missing tooth.

This is too stringent, which is crap for me.

So, I changed the code slightly.

Now the long tooth has to be >1.5x the tooth before, but the teeth after only have to be 7/8 of the long tooth.  The big risk with this type of code is that if we sync on the wrong tooth then we could end up getting serious detonation and possible engine destruction.

To protect against this I have added additional checks, in this case the 3 teeth after the long tooth all have to be less than 7/8 of the long tooth.


Anyway, here is the code (mostly so I can find it when I next need it!)
ms2_extra_ign_in.c


    /************ missing tooth wheel & missing and 2nd trigger wheel mode *************/
SPKMODE4:
    if ((flash4.spk_config & 0xc) == 0x8) {
        goto SPKMODE4B;
    }
    /* this is the "find missing" step */
    // look for missing tooth (subtract last tooth time from this tooth
    // count taking overflow into account, and then multiply previous
    // tooth time by 1.5 and see


    if (firstsync_iter == 0) {
        /* Here we will look for missing */


        temp1 = tooth_diff_last + (tooth_diff_last >> 1);


        if (tooth_diff_this > temp1) {
            firstsync_iter = 1;
        }
        return;
    } else if (firstsync_iter == 1) {
        /* tooth after what we thought was missing, lets make sure this one is short
         * on the first sync, we miss tooth #1, but that's ok as long as we catch it next time
         * split this into 2 operations so compiler doesn't call subroutine
         */
        temp1 = (tooth_diff_last >> 1); /* 1/2 of last value */
        temp1 = temp1 >> 1; /* 1/4th of last value */
        temp1 = temp1 >> 1; /* 1/8th of last value MDR ADDED */


        //temp1 = tooth_diff_last - temp1; /* 3/4ths of last value */
        temp1 = tooth_diff_last - temp1; /* 7/8ths of last value MDR ADDED */


        if (tooth_diff_this >= temp1) {
            /* this wasn't really the missing tooth... */
            firstsync_iter = 0;
            return;
        }


        firstsync_iter = 2;
        /* flagbyte4 |= flagbyte4_found_miss; DONT THINK WE WANT THIS YET */
        set_count = 1;
    } else if (firstsync_iter == 2) {
/*Check the next tooth as well so as to be sure */
/* tooth after what we thought was missing, lets make sure this one is short
* on the first sync, we miss tooth #1, but that's ok as long as we catch it next time
* split this into 2 operations so compiler doesn't call subroutine
*/
temp1 = (tooth_diff_last_1 >> 1); /* 1/2 of last value */
temp1 = temp1 >> 1; /* 1/4th of last value */
temp1 = temp1 >> 1; /* 1/8th of last value MDR ADDED */


temp1 = tooth_diff_last_1 - temp1; /* 7/8ths of long tooth MDR ADDED */


if (tooth_diff_this >= temp1) {
   /* this wasn't really the missing tooth... */
   firstsync_iter = 0;
   return;
}


firstsync_iter = 3;
/* flagbyte4 |= flagbyte4_found_miss; */
        set_count = 2;  /* Guessed that this should be 2,  needs checking */
   } else if (firstsync_iter == 3) {
/*Check the next tooth as well so as to be sure */
/* tooth after what we thought was missing, lets make sure this one is short
    * on the first sync, we miss tooth #1, but that's ok as long as we catch it next time
* split this into 2 operations so compiler doesn't call subroutine
*/
temp1 = (tooth_diff_last_2 >> 1); /* 1/2 of last value */
temp1 = temp1 >> 1; /* 1/4th of last value */
temp1 = temp1 >> 1; /* 1/8th of last value MDR ADDED */


temp1 = tooth_diff_last_2 - temp1; /* 7/8ths of long tooth MDR ADDED */


if (tooth_diff_this >= temp1) {
  /* this wasn't really the missing tooth... */
  firstsync_iter = 0;
  return;
}


  firstsync_iter = 4;
  flagbyte4 |= flagbyte4_found_miss;
       set_count = 3;  /* Guessed that this should be 3,  needs checking */
    } else if (firstsync_iter == 4) {
        if (tooth_no == 0) { // this should not happen, so reset
            outpc.syncreason = 1;
            ign_reset();  // note that this sequence of setting reason, resetting ign and incrementing counter is
            return;
    }




            if ((tooth_no == last_tooth) ||
                (((flash4.spk_config & 0xc) == 0xc) && (tooth_no == mid_last_tooth))) {
                /* this means we should have the last tooth here, so check for missing */
                temp1 = tooth_diff_last + (tooth_diff_last >> 1); /* 1.5 * last tooth */


                if (tooth_diff_this <= temp1) {
               firstsync_iter = 0;
                    flagbyte4 &= ~flagbyte4_found_miss;
                    outpc.syncreason = 2;
                    ign_reset();
                    return;
                }


                flagbyte4 |= flagbyte4_found_miss;
                set_count = 0;
            }
        }


        if (tooth_no == 1) {
            /* check to make sure this tooth is < 3/4th's of last tooth*/
            temp1 = (tooth_diff_last >> 1);
            temp1 = temp1 >> 1;
            temp1 = temp1 >> 1; /* Make it 7/8th's not 3/4 MDR ADDED */
            temp1 = tooth_diff_last - temp1;
            if (tooth_diff_this >= temp1) {
                /* lost sync */
                firstsync_iter = 0;
                outpc.syncreason = 5;  /* First tooth failure labelled as 5 */
                ign_reset();
                return;
            }
        }


        if (tooth_no == 2) {
           /* check to make sure this tooth is < 3/4th's of last tooth */
           temp1 = (tooth_diff_last_1 >> 1);
           temp1 = temp1 >> 1;
           temp1 = temp1 >> 1; /* Make it 7/8th's not 3/4 MDR ADDED */
           temp1 = tooth_diff_last_1 - temp1;
           if (tooth_diff_this >= temp1) {
               /* lost sync */
               firstsync_iter = 0;
               outpc.syncreason = 6; /* Check this and label as 6 MDR ADDED */
               ign_reset();
               return;
           }
        }


        if (tooth_no == 3) {
           /* check to make sure this tooth is < 7/8th's of last tooth  */
           temp1 = (tooth_diff_last_2 >> 1);
           temp1 = temp1 >> 1;
           temp1 = temp1 >> 1; /* Make it 7/8th's not 3/4 MDR ADDED */
           temp1 = tooth_diff_last_2 - temp1;
           if (tooth_diff_this >= temp1) {
               /* lost sync */
               firstsync_iter = 0;
               outpc.syncreason = 7; /* Check this and label as 6 MDR ADDED */
               ign_reset();
               return;
           }
        }


    if (flagbyte4 & flagbyte4_found_miss) {


        flagbyte4 &= ~flagbyte4_found_miss;


// found the missing tooth
if ((flash4.spk_config & 0xc) == 0xc) {
   if (!(flagbyte1 & flagbyte1_trig2active) && !(synch & SYNC_SYNCED)) {
goto common_wheel;
   }
}


        synch |= SYNC_SYNCED;


        if (synch & SYNC_FIRST) {
            syncfirst();
        }


        outpc.status1 |= status1_syncok; /* have sync */


if ((flash4.spk_config & 0xc) != 0xc) {
   tooth_no = set_count;
} else {
   if (flagbyte1 & flagbyte1_trig2active) {
tooth_no = set_count;
flagbyte1 &= ~flagbyte1_trig2active;
   } else {
tooth_no += flash4.No_Miss_Teeth;
   }
}
    }
    goto common_wheel;
 
The great thing is that the engine now start "on the button", first time everytime.  I am very excited as it takes my car from being a liability to an actual car.


Tuesday, 11 October 2011

Starter problem



Removed the dB killer, topped up with coolant.

Went to start car. Didn't fire, noticed the LED on the MS showing cold engine wasn't lit. Assumed I had dislodged a spade connector from the temperature sensor. Carried on cranking.

Engine missfired. Stopped cranking.

Tried cranking again and starter just whirred. Damn, hit it with hammer, just whirred.

Turns out that the ECU thought the engine was warm, so supplied less fuel on startup. This cause missfire which resulted in the engine trying to go the wrong way which broke a gear on the back of the clutch (starter gear).

Had to take out the clutch (actually took out 3 clutches as needed to find a replacement gear), not difficult on a motorcycle engine with air-tools. You can even do it with the engine oil in place as long as you can tip the engine a few degrees.

Anyway, it is all back together now. Also removing the dB killer has sorted out the boost. Getting a nice 8psi from 6kRPM (better than the 7kRPMbefore), and this can be controlled nicely with the boost controller. Aim now is to get a steady 8.25psi (155kPa) from 6kRPM to the red line with sensible fueling. Then need to work on the ignition timing and on the acceleration enrichment (which is rubbish at the moment).


Monday, 3 October 2011

Of course its the dB killer

The boost was dropping off at high RPM. I asked around and it appeared that this was probably due to pressure from the gases acting on the newly ported wastegate.

So, I put in a stiffer spring, and messed with the boost solenoid control. Both of these things helped, but it seemed difficult to stop it dropping off. Really I want 8psi from 6kRPM to the red-line, maybe dropping slightly at peak RPM to avoid running the injectors at 100% duty cycle. At the moment I get 8psi at 7kRPM, but it trails off linearly with RPM ending around 5psi.

Anyway, I will remove the baffle (dB killer) tonight and see if that does the job. I am pretty confident that things will spin up even bit quicker and that the boost drop will go away as that was the characteristic before I put the baffle in.

Once it is all stable I might see if the engine (clutch really) can handle an atmosphere of boost, which is my personal target.

Sunday, 25 September 2011

Turbo update



I spent ages trying to optimise the EAE algorithm values. This is a clever "wall wetting" algorithm. But I just couldn't get it to work properly, so I gave up and tuned using the normal MAPdot and TPdot parameters. It isn't perfect, but it seems to work.

I also installed a boost controller, and added a second spring to the present wastegate spring.

Here is a screenshot from tonights datalog. The acceleration enrichment isn't perfect but the car drives well enough, and it is nicely controlled under full throttle so it is safe. Presently I am running a cautious AFR of around 11.5, but all in all the tune is pretty decent and gradually improving.

Boost duty controls how much the pressure comes from the turbo pressure and how much comes from the atmosphere. Confusingly 100% means use the outlet turbo pressure. 0% will allow loads of the control pressure to leach out. This would allow the wastegate to stay closed longer and so build up more boost.

If you look at the log, for low RPM I try to keep the wastegate closed for as long as possible to get the turbo spinning up quickly. After about 7kRPM the boost controller goes to 100% so that the boost is controlled purely by the spring. The thing is that there are forces from the exhaust gases that push the wastegate open and so the boost drops off with RPM.

I should be able to maintain the boost after 7kRPM by playing with the Boost Duty Table.



Now the problems:
1) oil leak, but I know where it is and it should be easy to fix
2) water leak into oil. This is the big one, but I have a plan.
3) starting, is still a nightmare. I think this is related to low battery and sub-optimal values, but it is annoying.




Tuesday, 26 July 2011

Everything I ever needed to know about Volvo turbos

Really useful video. If only I had seen this earlier!



Basically explaining how the wastegate works on a volvo turbo charger and how the boost control system works. Yeah, I know a bit dull.