PDA

View Full Version : Pulsin vs. Interrupt RPM measurement



Tobias
- 30th December 2009, 04:48
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.


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?


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

Tobias
- 31st December 2009, 01:29
Using a 18F4620 configured for a 20MHZ external OSC. When I generate spark with my ignition the OSC pins go low and spike with ignition firing. Any ideas?