Measuring engine RPM with Arduino

You can measure engine RPM using the negative terminal of the coil, however you need to isolate the 12v circuit of the coil, from the 5v levels used in the Arduino. This can be done using an optical isolator circuit as detailed below.

The following schematic shows how to connect the circuit:

RPM Module Schematic

Assembly List

The following components, or their equivalent are required to build the RPM module.

Label Part Type Properties
4n25 DIP – 6 pins package DIP (Dual Inline) [THT]; hole size 1.0mm,0.508mm; true; chip label IC; pins 6; pin spacing 300mil
Arduino Arduino Uno (Rev3) type Arduino UNO (Rev3)
C1 Ceramic Capacitor package 100 mil [THT, multilayer]; capacitance 100nF; voltage 6.3V
C2 Ceramic Capacitor package 100 mil [THT, multilayer]; capacitance 100nF; voltage 6.3V
D1 Rectifier Diode package 300 mil [THT]; type Rectifier; part # 1N4001
D2 Zener Diode package Melf DO-213 AB [SMD]; breakdown voltage 5.1V; type Zener; power dissipation 0.5W; part # 1N4732A
R1 390 Ω Resistor package THT; tolerance ±5%; bands 4; resistance 390Ω; pin spacing 400 mil
R2 4.7k Ω Resistor package THT; tolerance ±5%; bands 4; resistance 4.7kΩ; pin spacing 400 mil

Example Code

volatile unsigned long timePointsOpen, timePointsClosed, lastChange;
volatile unsigned int numBangs;

void pointsOpening(){
    unsigned long t;
    t = millis();
    if (lastChange > 0){
        timePointsClosed += (t - lastChange);
    }
    lastChange = t;
    ++numBangs;
}

void setup(){
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
}

void loop(){
  // Number of coil pulses
  numBangs = 0;
  attachInterrupt(0, pointsOpening, RISING);
  delay(50);
  detachInterrupt(0);
  numBangs = ((60000/50)*numBangs)/2;
  Serial.print("RPM: ");
  Serial.println(numBangs);
}