Monday, April 23, 2012

Reading the Cam Angle - Part 1 (Signal Conversion)

If you understand the basics of a 4 stroke engine you'll know that there are 4 states that a cylinder can be in: intake, compression, power, exhaust. Of course there's always the informal: suck, squish, bang, blow if you prefer. If we read the sensors attached to the cam, then we can know when each event happens since the cam position is what determines the state of each cylinder.

On my car the cam sensors are built into the distributor. The first thing I needed was a way to easily intercept the signals and determine their type. I chose to replace part of the wiring with DB9 connectors. This allowed me to easily connect the distributor as standard into the car electrical system or break the connection and attach each DB9 plug to my own circuitry and intercept the signals.

There are two signals which I'll refer to as "inner loop" and "outer loop". The outer loop will pulse once per cam revolution. The inner loop will pulse 4 times per cam revolution. When the inner and outer loop signal offset(phase) is changed, the result is a change in the spark timing. So, when the inner loop pulses occur later in time compared to the outer loop pulses, the spark timing will occur at a later point in each engine revolution.

The Outer Loop
From what I can figure out, it looks like the outer loop signal is generated from a hall effect sensor. The sensor is switched on/off by a small magnet that moves past it on each rotation.

The result is a 0-12v square wave signal that looks like this. The signal is a bit noisy, but I'm not too fussed at the moment.

The microcontroller works with TTL logic levels (0v-0.8v for low/0 and 2.6v-5v for high/1). At first it looks like a simple voltage divider will do what I need. The only problem with that is the assumption that you're always working with 12v, but the voltage output could change anywhere between 8v and 14v mostly depending on how much power the battery and alternator can provide vs demand on the car's electrical system (fans, wipers, radio). The solution is to make your voltage divider out of a diode and resistor. I chose a 4.7v zenner diode because that voltage is within the TTL spec.. I've included a circuit diagram here. I've never used circuit design software before, so it's a bit crap. I didn't get exactly what I wanted in 15 minutes of playing around, but for now it should provide you with an understanding of what I'm doing.
Conversion to TTL voltages
VS1 represents the original signal, and TPdv1 is the TTL output. The end result is a 0v-5v square wave that can switch a microcontroller input pin!

The inner loop
This is generated from a reluctor sensor.

Reading the inner loop signal is a bit more involved. It's an AC signal ranging from +11v to -7v P-P. The wave form isn't a nice sine wave, but that shouldn't cause us any problems. Each wave pulse is generated every quarter turn. Obviously the faster it turns, the higher the signal frequency. The only difference is the signal amplitude will also change with engine speed. The +11v to -7v was recorded while the engine was at it's max RPM. At lower engine speeds the signal could range just -2v to 3.5v.

I started out with the same circuit that I used for the outer loop. When the current is flowing forwards (during the first half of the signal), the peak voltage across the zenner diode can't be any more than 4.7v. When current is flowing in reverse (second half) the voltage across the diode will peak at -0.5v. Ideally it should be 0v, but the diode must have a breakdown voltage of just 0.5v. Below you can see the original signal in red, and the converted signal in blue.
Red: Original, Blue: Zenner

The inner loop - digital
While this new signal is now within TTL voltage ranges it will cross into undefined voltages that are neither recognised as 0 or 1. This can cause really weird problems, so the final step should change this into a square wave. I didn't include a circuit diagram here because it would take me far too long to do. I haven't had the time to learn how to properly use 5Spice yet!

The first thing I did was feed the signal into an optocoupler. I chose a 4N25. The inner loop signal is provided across 2 wires. If I were to connect it directly to a TTL IC, then one wire would have to be connected to a ground point common with IC. This would alter the voltage range of the signal. Because the standard ECU is still using this signal, I chose to leave it intact. The optocoupler will isolate the signal from the rest of my circuitry, giving me a mirror version to work with. The first thing I learned was not to feed the signal in directly. Excess current flow caused 2 spectacular  failures. *POP* and the IC shot straight off the breadboard. I never saw it again! Placing a current limiting resistor before the input worked, but the output waveform was changed. At first it just looked inverted, but flipping it over didn't exactly match the input.
Optocoupler output
Optocoupler output inverted

The signal is still usable, but I thought I was doing something wrong and decided to look into it. I played around with measuring input an outputs while feeding constant voltages and saw that the relation between input and output wasn't linear. Googling reveals that it's skewed according to the optocoupler's CTR(current transfer ratio). I found some more info here

Now that I have a signal I can work with, the last step is to convert it to a square wave. My first choice for doing this was to use a voltage comparator. If I were to use a 2.5v reference then any portion of the signal above that will set the comparator output to a solid 5v, and anything below the reference will set the output to a solid 0v (or as close to those voltages as the comparator can output). Digital 1 and 0. I tried using both an LM393 and LM311 and unfortunately I got some really confusing results. The comparator output would either not change at all or oscillate at a very high speed. Of course I measured the signals going in, and tested the IC's by feeding in various test voltages while measuring the output. I can only assume that I've overlooked something or electrical noise was making them go haywire. In the end I succeeded with an OPA2134 op-amp. 
Woohoo! Digital square wave!

To get this signal I had to make one final change, which was to make my reference 4.9v instead of 2.5v. No, 5v wouldn't work and neither would 4.8v. This I don't understand, but it shows that experimentation pays off. At this point I'm assuming that it has something to with how much current the input signals (reference voltage and optocoupler output) can source/sink, but didn't see either being pulled high or low. I'll need to find out more before I deal with this problem again.

End result: Success! & Strange results to look into.

Edit on 2013-10-01: Fixed mislabeled reluctor


  1. gotdamn i didnt understand a lot of this but real interesting dude keep writing.
    real hacker shit