Cam Angle Sensor

 

This is a graph of the outputs from a Nissan cam angle sensor (CAS) . I will need to perform timing events on the falling edge of the wave since the cylinder reset wave length is variable. The timing trigger has 360 waves per rotation. Since the sensor is on the camshaft of a 4-stroke engine (camshafts rotate at half crank speed), there are 180 waves per engine revolution. AT 9000 RPM, that is 270 KHz (9000 / 2 * 60 / 1000). To account for fractions, we need a clock speed much higher than this (270 KHz is bare minimum). A 1 Mhz (~4x minimum) clock for the FPGA should be more than enough 99.9% of the time.

At the falling edge of each timing signal, increment a counter. Lets call this variable i. this counter is not used to calculate angle and is not limited to 360. After variable i is incremented, we check the state of the cylinder reset signal. If the signal just went high, then we initialize another counter( variable r) to 0. We will also increment variable r on the falling edge of the timing signal whenever the cylinder reset signal is high.

On the falling edge of cylinder reset, we compare the value of variable r (pulse width of the cylinder reset wave) to known values to figure out which cylinder# just reset, and set variable p to the degree at which that cylinder is at top dead center (TDC) at the first stroke divided by 2 (since the camshaft moves at half engine speed). If cylinder1 just reset, we will set variable p to 0 (0 degrees).

So now we have everything we need to time sequential fuel injection and sequential ignition. However if we timed these events to the falling edge of the timing signal, we could only adjust timing in 2 degree increments, unacceptable! I want at least 0.1 degree resolution. To remedy this situation, we need to know the RPM. This will need to be an average, and a minute is too long of a sampling time obviously. Sampling time needs to short enough for the system to detect engine acceleration quick enough. at 60rpm (1 revolution per second) there are 1000000 clocks per revolution or 2000000 clocks per complete engine cycle. One missed timing sync signal with a 1 second sample would be an error rate of approx (1 / 180) 0.5% or +- 3 rpm at 600rpm, and +- 0.01 degrees accuracy of crank rotation. Earlier I stated I wanted 0.1 degrees of resolution, which means I would need 10 Hz RPM sampling. 10 Hz on a 1 MHz clock is 100,000 clocks. So lets create variable r for rpm, and variable b for the counter. Every clock we need to increment b. Every 100,000 clocks we need to set r to the value of b, and set b to 0. We will need a counter to count to 100,000 clocks as well, lets call it variable a.

 

 

Here is some psuedo code to help illustrate:

if(++a > 100000)
{
    s = b;
    b = 0;
    t = 0;
    a = 0;
}

if(timing_pin)
{
    i++;
}
else
{
    if(i)
    {
        t++;
        p = p + (1 * 10;)

        if(cylinder_reset)
        {
            r++;
        }
        else
        {
            if(r)
            {
                if(r == 10)        // cylinder 1 tdc
                {
                    p = 0;
                }
                else if(r == 20)    // cylinder 2 tdc
                {
                    p = 540 * 10;
                }
                else if(r == 30)    // cylinder 3 tdc
                {
                    p = 180 * 10;
                }
                else if(r == 40)    // cylinder 4 tdc
                {
                    p = 360 * 10;
                }
                else            // error
                {
                }
                r = 0;
            }
        }
        e = p;
        i = 0;
    }
}

Leave a Reply