PDA

View Full Version : Slow code needs a tune up



Tobias
- 5th January 2010, 08:51
16F877A measuring RPM. I have the timer style and PULSIN versions working fine. However my timer style of code is very slow. I toggle an output and on the scope I get 14 hz at 5000 rpm (4 counts/rev) when using the timer code. When I use the Pulsin I get 55 hz. Any ideas why its slower? I was under the impression the timer version would be alot faster than the Pulsin.





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
Gate1 Var PortC.1
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
CursorPS con $45 'Cursor Position

pause 100
SEROUT2 LCD,84, [Prefix, LcdCls]

Include "modedefs.bas" ' Mode definitions for Serout

Low Gate1

OPTION_REG.7 = 0 'Pull Ups enabled
INTCON.7=0
ADCON0.0 =0
ADCON1 =7

Loop:
If RPMInput = 0 then
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
endif

toggle gate1

goto loop


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
Gate1 Var PortC.1
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
CursorPS con $45 'Cursor Position

pause 100
SEROUT2 LCD,84, [Prefix, LcdCls]

Include "modedefs.bas" ' Mode definitions for Serout

Low Gate1

OPTION_REG.7 = 0 'Pull Ups enabled
INTCON.7=0
ADCON0.0 =0
ADCON1 =7

Loop:
If RPMInput = 0 then
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
endif

toggle gate1

goto loop

Acetronics2
- 5th January 2010, 09:22
Hi,

Just curious to know what you use as a sensor ...

Alain

Tobias
- 5th January 2010, 10:08
I am using an ignition simulator that is activating a racing ignition system. In essence the simulator triggers the points input on the ignition system. I am reading the tach output into an opto-isolator.

http://msdignition.com/Products/Ignitions/Drag_Racing/Digital/7530T_-_Programmable_Digital-7_Ignition_Control.aspx

http://msdignition.com/product.aspx?id=4777&terms=8998

HenrikOlsson
- 5th January 2010, 10:38
Tobias,
To me the two versions in your first post looks identical, am I wrong?

/Henrik.

Tobias
- 5th January 2010, 10:45
Yea I screwed that up here is the timer 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
Gate1 Var PortC.1
Gate2 var PortD.1
Gate3 var PortD.2
Gate4 var PortD.3
Gate5 var PortD.6
Gate6 var PortD.7
Gate7 var PortD.5
Gate8 var PortD.4
ADCON0 =0
ADCON1.3=1
ADCON1.2=1
ADCON1.1=1
ADCON1.0=1
TRISE.0=1
TRISE.1=1
CCP1CON = %00000110 ' Enable the CCP1 capture, every 4th rising edge
pause 100
SEROUT2 LCD,84, [Prefix, LcdCls]
low Gate1
Low Gate2
Low Gate3
Low Gate4
Low Gate5
Low Gate6
Low Gate7
Low Gate8
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
'SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM ",#0, " ", #Period]
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*5)

'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

Acetronics2
- 5th January 2010, 13:41
One good reason could be the 2 DIV32 INSIDE the test loop ...

I measured once DIV32 took ~ 700µs ...

this is at least one very good reason for the PULSIN way to show a false result on the scope ... despite calculated RPM value to be right.

Alain

Acetronics2
- 5th January 2010, 14:23
With some little reflexion ....

I'd ask you to scope the signal you use from your gadget ...

Is it really a nice symmetrical square wave ???

Alain

Tobias
- 5th January 2010, 15:05
Its not a perfect function generator type square wave for sure. My scope has a USB output on it. This will be a good reason to learn how to send screen shots to my laptop. I will work on that tonite.