Using a 16F877A to measure engine rpm. I have a rpm simulator that connects to a racing ignition system and fires a test plug. The simulator has two outputs, one will fire the ignition system and the other is just a simple square wave. When I use the following Pulsin code I get good data using the square wave and also when making sparks.

Code:
DEFINE OSC 20
RPM             var     word
period          var     Word
HRPM            var     word
LRPM            var     word      
RPM_Total       VAR     Word
LCD             VAR     PortC.6    'LCD output  
RPMInput        var     PortC.2
Prefix          con      $FE             ' needed before each command
LcdCls          CON      $51             ' clear LCD (use PAUSE 5 after)
CursorPS        con      $45             'Cursor Position

loop: 
  Pulsin RPMInput, 0, LRPM
  PULSIN RPMInput, 1, HRPM
  RPM_Total = HRPM + LRPM 
  RPM = 1000
  RPM = RPM * RPM
  RPM = DIV32 RPM_Total   ' 1,000,000 / Pulse_Total
  RPM = RPM * 60            ' Per minute
  RPM = Div32 8            ' 4 pulses per rev
  pause 100
  SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM ",dec5 RPM]
goto loop
When I use the interrupt code I get data that matches the simulator but I get some problems when I create a spark. Once in a while on my LCD I see the correct value however most of the time I get data that is extremely high. What can I do to fix this deal? Initially I was thinking it was purely hardware so I put a 0.1uf cap on the output of the opto-isolator that connects to the RPM pin. It really didn't solve the problem. I have the standard caps on the VDD of the PIC. I am pulling the RPM pin high with a 10k resistor and using the opto to ground the pin. Any ideas?

Code:
DEFINE OSC 20
Prefix          con      $FE             ' needed before each command
LcdCls          CON      $51             ' clear LCD (use PAUSE 5 after)
CursorPS        con      $45             'Cursor Position
Capture         VAR     PIR1.2		      ' CCP1 capture flag
Overflow        VAR     PIR1.0	    	' Timer1 overflow flag
RPM             var     word
period          var     Word
LCD             VAR     PortC.6    'LCD output

CCP1CON = %00000110   			' Enable the CCP1 capture, every 4th rising edge
pause 50
SEROUT2 LCD,84, [Prefix, LcdCls]
pause 50
SEROUT2 LCD,84, [Prefix,CursorPS,0,"**** ",#RPM, " ", #Period]
pause 200
loop:
T1CON = %00100000 ' TMR1 prescale=1:2 Timer OFF
'11 = 1:8 prescale value
'10 = 1:4 prescale value
'01 = 1:2 prescale value
'00 = 1:1 prescale value
TMR1H = 0                               ' Zero the Timer
TMR1L = 0
capture = 0

Start:

	IF capture = 0 Then 
    goto Start	' Wait here for the first capture
  endif
 
 T1CON.0 = 1             ' Start the Timer
 capture = 0             ' Reset  the capture flag
  
CaptureLoop:
	IF capture = 0 Then 
    goto CaptureLoop	' Wait here until captured
  endif
  
period.lowbyte = CCPR1L		' Store the captured value in
period.highbyte = CCPR1H	' period variable

period = period / 2
RPM = 10000
RPM = RPM * RPM ' 100,000,000
RPM = DIV32 period ' 100,000,000 / RevCount
RPM = RPM * 60 ' Per minute
RPM = DIV32 400
RPM = (RPM /10)*25'+25

pause 100
SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM ",dec5 RPM, " ", #Period]

gosub cleartimer1    

GoTo loop					' Do it forever
    	
ClearTimer1:
IF (capture = 0) Then 
  goto cleartimer1	' Wait for beginning of next period
endif

TMR1L = 0					    ' Clear Timer1 low register
TMR1H = 0					    ' Clear Timer1 high register
capture = 0					    ' Clear capture flag
overflow = 0				    ' Clear overflow flagReturn
return