jump to navigation

2JZ-GE Cam & Crank Signals 2010/03/14

Posted by Michael in 2JZduino.

The IS300 Overall Wiring diagrams show a camshaft and crankshaft position sensor connected to the ECU.  These sensors are variable_reluctance sensors and provide the ECU with engine position information, which is used for fuel and ignition control.

In preparation for building the electrical circuit and writing the firmware for 2JZduino, an investigation was necessary to identify the nature of these cam and crank sensor signals.  This would have been easiest with an Oscilloscope, but unfortunately I do not have easy access to one of these.  Instead, I built a data acquisition unit using the analog input channels of the Arduino Mega.  I tapped into the cam and crank signals at the ECU, connecting them to analog input channels 6 and 7.  A diode was connected between analog input signal (cathode) and ground (anode) to protect the Arduino against negative voltages generated by the sensors.

An excerpt of the code written to sample analog channels 6 & 7 is posted below.  Data acquisition rate for both channels is ~5,000 Hz, which is limited primarily by the serial port (limiting the speed at which data is extracted from Arduino).  The myDataLogger object (code not shown) has both “Store” and “Transmit” methods.  “Store” places the analog input values into a private member myDataLogger.buffer from within the interrupt service routine.  “Transmit” is called during the main loop of program execution which transmits the data sequentially over serial port to a listening software program which then re-assembles the data for graphing.

void setup()
  // setup ADC
  ADMUX = B01100110;  // AVCC VRef, ADC Left, ch6
  ADCSRB = B00000000; // Analog Input bank 1
  ADCSRA = B11001111; // ADC enable, ADC start
    // manual, interrupt enable, prescaler = 128

ISR(ADC_vect) { // Analog->Digital Conversion Complete
  static byte Channel6 = 0;
  static byte Channel7 = 0;

  char ADCch = ADMUX & B00000111;  // which channel?

  if (ADCch == 6) {
    Channel6 = ADCH;  // store ADC result
    ADMUX = (ADMUX & B11100000) + 7;  // set channel 7
  else if (ADCch == 7) {
    Channel7 = ADCH;  // store ADC result
    ADMUX = (ADMUX & B11100000) + 6;  // set channel 6
    myDataLogger.Store(Channel6, Channel7);

  ADCSRA |= B11000000;  // start next ADC

The charts below show the captured cam and crank signals for my 2JZ-GE during engine cranking and during idle.  Note that these are the positive side of the waveform only because the Arduino analog inputs measure only positive voltages.

The engine idle is about 1300 RPM (this slows to ~700 RPM after the engine is warm).  Analysis reveals that the crank signal arrives for every 10 degrees of engine rotation and is generated 34 times in 360 degrees (there is no crank signal for 20 degrees of the revolution).  The cam signal arrives every 240 degrees of rotation so that there are 3 signals for each 720 degrees of rotation (each complete Otto cycle).  It seems that the stock ECU would identify the beginning of the engine cycle when the falling-edge of the cam signal and the 20 degree gap in the crank signal align.

Also worth noting is the magnitude of the peak signal voltage between startup (< 2 V) and idle (> 4 V).  The low peak-voltage at slow engine speeds will prevent signal detection to be done directly by the Arduino digital inputs.  This will be discussed in more detail when the circuit and acquisition logic design is discussed.



1. David - 2010/03/16

Can you log the VVTI? I’m going to install a VVTI engine in a non-VVTI chassis and I’m sure its just PWM controlled. I’m just curious what the high/low would be.

2. Michael - 2010/03/16

Just to be clear, you’re interested in the peak voltage of the VVTi PWM signal? I’ll try to log that this weekend.

3. David - 2010/03/16

That would be awesome! Peak voltage and if you can get the freq. Which I believe should be under 3k. My hopes is that I would be able to use a Arduino to control the VVTi.

Michael - 2010/03/17

David, I found some time ahead of schedule to datalog the VVTi signal. Hope you find it useful.

4. VVTi Signal « the Delta Echo - 2010/03/17

[…] VVTi Signal 2010/03/17 Posted by Michael in 1. trackback One of my readers asked that I datalog the VVTi signal in a similar way to the Cam and Crank Signals. […]

5. Mark - 2010/06/04

hi, cool project!

I noticed your problem about the signals being low from the sensors when you are near idle. have you considered building an amplifier for this signal – something with a transistor or op-amp? I am not a EE but have been studying electronics starting with my cruise control module.

On my cruise control module the incoming speed sensor signal goes to the base of a transistor and the transistor switches 0V to 5V into the CPU.

I think a circuit would be easier in the long run than switching to ADC.

6. Michael - 2010/06/05

Thanks for the suggestion Mark. Early in my development efforts I did try connecting the VR sensors to the gate of a MOSFET, which had too high of a turn-on voltage (same problem). I never did try a simple BJT, for a couple of reasons…

i) I have limited PCB space remaining. More components is a last resort at this point.
ii) The ADC mode I’ve implemented is actually working quite well. I’ve logged the ADC values for cam and crank sensors and the firmware is accurately replicating the waveform.
iii) Transistor selection might be tricky (I haven’t actually tried to source one) since a VR sensors peak values can be as high as 30v. This might drive additional components to protect the transistor base.
iv) I’m still learning about this problem, but I now believe the issue is on the output side of the cam sensor. At low frequencies the inductor has sufficient time to completely discharge and the output settles at 0v + v_noise. I suspect v_noise is inducing false signals at the stock ECU input.

Having said all that, in hindsight if I were to start again with the knowledge I have now, I would and design for and reserve space for Schmitt triggers at the input and the output of 2JZduino both to cleanly detect the zero crossing points for the sensors, and to generate clean and stable zero crossing points for the stock ECU.

Mark - 2010/06/05

I see you knowledge probably exceeds mine by quite a bit. I’ll probably just troll some more and come back after I learn some more! I am an M.E. trying to learn some electronics. I guess one more thought is that you may get some help with schematics on the arduino forums if you feel you need it..

7. Michael - 2010/06/05

I too am a mechie that finds himself playing with these fictitious “electrons”… I’m still not convinced they even exist ;)

Appreciate your thoughts!

8. Nik - 2010/08/20

Hey mate i was very pleased to find this page of yours while searching for info on cam/crank sensors :) I am thinking of building an ignition controller for the 2JZGE to provide the spark reference to run individual coil setup from another vehicle (maybe from a 7MGTE in waste spark). I wanted to pick up the NE and G signals from the distributor to use for cam and crank reference but am concerned about the amount of electrical noise in the engine bay. Have you tried doing this with an arduino in the engine bay? Also with regard to the actual signal from the sensors, do you know if the stock ECU reads the rising edge, falling edge or zero crossing of the pulse? I assume that with a couple of shmitt triggers I can turn the pulse into a nice square wave, although I know the stock ECU has “signal conditioning” mentioned in its process diagram so who knows what they are doing to it in there. Finally do you find the input speed of the arduino to be sufficient to read and count cam events as you say 34 per revolution so if the engine is at 6000 rpm that is quite a lot of pulses. Sorry for asking so many questions :) I’ll be happy to share my developments on the ignition components with you when I get the ball rolling.

Michael - 2010/08/20

Hi Nik,

Not sure I’m clear on all your questions. Have I tried running the 2JZduino in my engine bay? Yes. Have I tried anything with the distributor signals? No.

I can confirm from my R&D that the 2JZGE ECU looks for zero-crossing (an early version watched for rising edge only and then simulated an approximate falling-edge… it had all sorts of problems until I introduced logic assuming zero-crossing was the critical characteristic).

I’ve got another post on here that describes how I detect and process the incoming signals (without Schmitt triggers, although I admit this would be the preferred solution).

I’ve also posted (very early) about the Arduino’s capability to process the quantity of signals arriving from an engine. In short, yes the Arduino is quite capable to deal with the rate of crank signals that arrive (you wrote “cam”, but I believe you meant “crank”).

Read the applicable posts under this link and you’ll likely have a lot of your questions answered (and maybe you’ll come up with a few more).

9. Nik - 2010/11/08

hey michael, just reviving this old post which i made a long time ago when it was all hypothetical and i hadn’t really thought about it much :) after re-reading this page I think your calculations may be a bit off.
according to the service specs, the GE distributor has 24 teeth and a 2 coil 1 tooth CPS. This would yield one NE pulse for every 15 degrees. However the distributor turns at half crank speed so that gives 30 degrees per pulse. This put the two cam position sensors at 360 degrees apart from each other. You may verify this by counting the teeth on the signal rotor in the GE distributor. I don’t have access to one myself.
This would mean that by measuring a period containing 3 cam signals this wasn’t 720 degrees but rather 1080 degrees of rotation.

Michael - 2010/11/08

Hi Nik,

Which vehicle service specs are you referencing? The GE came in a few configurations I think (e.g. VVTI and non-VVTI). The Ne/G signal wheels may have been different for each variant for all I know. For the IS300 I’m very confident in my findings… If you look at the datalog for engine idle above you’ll see the crank signal is a very regular 34 pulses followed by a gap that is 2-pulses wide; 3 cam pulses arrive for every 720 degs of crank angle. Plus, when connected the 2JZDuino LCD readout and tachometer in the instrument cluster agree very closely.

I’m not really sure how (as you describe) a cam signal that arrives every 360 deg of crank rotation is good for anything. It doesn’t allow you to figure out when cylinder 1 is at TDC because cylinder 3 looks the same. But if it is a “1-tooth” CPS then it is possible. I’m not sure what a “2 coil” CPS refers to. Do you mean there are 2 VR sensors?

10. Nik - 2010/11/08

I am just going off the general toyota ignition system documentation. But when my arduino parts arrive and I actually build a prototype I’ll be testing it out on a jza80 supra 2jzge.

As the engine cycle is 720 degrees, then having a pulse every 360 degrees allows the ECU to know when cylinder #1 and cylinder #6 are approaching TDC on compression stroke.

The setup is very similar to the 7MGTE CPS and Supra owners have successfully replaced the distributor with the CPS (which basically looks just like the supra distributor but is capped off and has no leads going to the plugs).

I think you will love this PDF of Toyota Ignition Control. It has scope outputs of the different sensors and I think it will be very valuable for both of our projects :)


Michael - 2010/11/09

Great link Nik, thanks. Looks like this pre-dates the 2JZs, but still contains a lot of good material.

11. Ali_SC3 - 2015/03/05

good info here. To clear up a few things the 7m cps and the 2jzge non-vvti distributor base basically work the same way as far as crank and cam signals go. They both have a 24 tooth crank wheel and a 1 tooth cam wheel but in different arrangement. There are 2 VR sensors for the cams G1 and G2, one for TDC cyl #1 and one for TDC cyl #6. There is a third VR sensor on the crank wheel puts out signal NE.

What happened is in 96-97 the “GE” motor got a secondary “misfire” crank sensor that was a 36-2 type of trigger wheel (36 teeth missing 2 as confirmed by your results above) in addition to the distributor 24 tooth setup. Primary EFI is run off the distributor, and secondary sensor was only used to detect misfires to comply with obd2 better.

Then when the GE went to vvti in ’98+ they removed the distributor, kept the 36-2 crank sensor setup, and added a single cam sensor to the head (not 2 like the Gte non-vvti had). Since the VVti uses wasted spark coils, you only really need 1 cam sensor signal and that is how they arrived at a 36-2 wheel and a single cam sensor on the head as all the vvti motors got vvti waste spark coils.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: