Vehicle RPM Calculations Using the Arduino

  1. What is CycleOnOrOff? Your posted code doesn't define it. (It looks like it should be just Cycle and you forgot to change it in one instance.)

  2. You can optimize by using type boolean for variable Cycle. Then void RPMPulse() becomes this...

void RPMPulse() {
  if (Cycle)                // Check to see if start pulse
  {
    PulseStartTime = millis();  // stores start time
    // CycleOnOrOff = 1;           // not defined.  Maybe this should be just "Cycle = true;" ??sets counter for start of pulse
  }
  else // otherwise it must be end pulse
  {
    detachInterrupt(0);         // Turns off inturrupt for calculations
    PulseEndTime = millis();    // stores end time
    Cycle = false;                  // resets counter for pulse cycle
    calcRPM();                  // call to calculate pulse time
  }
}
  1. Serial.print is very slow. At 9600 bps, to serial.print "PulseTime =" is 88 bits which is almost 10 ms just to clock out the data. I think you're probably getting some revolutions while the interrupt is detached and thus missing the pulse.
  • of all things I'm listing here I think this is the most likely cause for the garbage data you're seeing.
  1. An engine running at 3000 RPM = 50 Hz has a period of only 20 ms. If you're using millis(); to measure the period you have a quantization error of ~140 RPM (21 ms period = 2857 RPM). Is that precise enough? Calculate this at your redline too.

  2. You could optimize RPMPulse() to this (untested)...

void RPMPulse() {
  static unsigned long event_time = 0;
  unsigned long this_time = micros();

  RPM = 60000000 / (this_time - event_time);
  event_time = this_time;
}