PDA

View Full Version : Encoder problem



precision
- 10th September 2006, 06:50
Hi all

I am using 900 ppr encoder for length measurements. i using 595 chip to show display and rs232 output for x,y plotting. when encoder rotate on 5 rpm, it is work. But when encoder run above 5 rpm, pulses are missing.
Where my codes are wrong ?
'---- chip 16F877 i/p 20 MHZ ---"
DEFINE OSC 12
INCLUDE "MODEDEFS.BAS"
ADCON1 = 7
INPUT PORTA.0
TRISA=0
TRISD = 0
TRISC = 0
TRISE =0
OUTPUT PORTD.2
OUTPUT PORTD.3
OUTPUT PORTD.4
OUTPUT PORTC.4

Symbol HC_latch = PORTE.0 ' pin 8
symbol HC_Data = PORTE.1 ' pin 9
SYMBOL HC_Clk = PORTE.2 ' pin 10


B1 VAR BYTE
B2 VAR BYTE
B3 VAR BYTE
B4 VAR BYTE
B5 VAR BYTE



DIGIT1 VAR BYTE
DIGIT2 VAR BYTE
DIGIT3 VAR BYTE
DIGIT4 VAR BYTE
DIGIT5 VAR BYTE
DIGIT6 VAR BYTE

MASK VAR BYTE

B1 = 0
B2 = 0
B3 = 0
B4 = 0
B5 = 0


E1 VAR BYTE
E2 VAR BYTE
E3 VAR BYTE
E4 VAR BYTE
E5 VAR BYTE

OPTION_REG = %00000000
On Interrupt Goto myint
INTCON = $90


IF PORTA.0 = 1 THEN NINE
LOOP: serOUT PORTC.6,T9600,[#b5,#b4,#b3,#b2,#b1,13]


'------------------------------------------
DIGIT1 = B1
LOOKUP DIGIT1,[$7E,$18,$6D,$3D,$1B,$37,$77,$1C,$7F,$3F],MASK
E1 = MASK
'------------------------------------------
DIGIT2 = B2
LOOKUP DIGIT2,[$7E,$18,$6D,$3D,$1B,$37,$77,$1C,$7F,$3F],MASK
E2 = MASK
'-------------------------------------------
DIGIT3 = B3
LOOKUP DIGIT3,[$7E,$18,$6D,$3D,$1B,$37,$77,$1C,$7F,$3F],MASK
E3 = MASK
'----------------------------------------
DIGIT4 = B4
LOOKUP DIGIT4,[$7E,$18,$6D,$3D,$1B,$37,$77,$1C,$7F,$3F],MASK
E4 = MASK
'---------------------------------------
DIGIT5 = B5
LOOKUP DIGIT5,[$7E,$18,$6D,$3D,$1B,$37,$77,$1C,$7F,$3F],MASK
E5 = MASK
'---------------------------------------

HC_Latch=0
shiftout HC_data, HC_Clk, LSBFIRST,[E1,E2,E3,E4,E5,$7E]
pauseus 1
HC_Latch=1

'---------------------------------------

GOTO LOOP


Disable
myint:

FF: B1 = B1 + 1
IF B1 > 9 THEN TWO
goto HH

TWO: B1=0
B2 = B2+1
IF B2 > 9 THEN THREE
goto HH

THREE: B1 = 0
B2 = 0
B3 = B3+1
IF B3 > 9 THEN FOUR
goto HH

FOUR: B1 = 0
B2 = 0
B3 = 0
B4 = B4+1
IF B4 > 9 THEN FIVE
goto HH

FIVE: B1 = 0
B2 = 0
B3 = 0
B4 = 0
B5 = B5+1
IF B5 > 9 THEN NINE
goto HH

NINE: B1 = 0
B2 = 0
B3 = 0
B4 = 0
B5 = 0
goto HH
HH:
serOUT PORTC.6,T9600,[#b5,#b4,#b3,#b2,#b1,13]

INTCON.1 = 0
resume
Enable

sayzer
- 10th September 2006, 08:04
You are getting the same problems here under this post;
http://www.picbasic.co.uk/forum/showthread.php?t=4610

Check the links and the suggestions...


Regards.

precision
- 10th September 2006, 13:21
Hi sayzer,

Thanks for the reply.
But i don't using eny pause in my code. I also using Intrrupt for high age detect from encoder and count.
Thanks

sayzer
- 10th September 2006, 14:42
Np.

Why don't you use 20Mhz Xtall ?

Your DEFINE is 12Mhz, are you using 12Mhz Xtall ?



Regards.

mister_e
- 10th September 2006, 18:04
My rules:
Don't use Serout when the PIC have an internal USART, use HSEROUT instead.
use Timer as counter when hardware allow
keep ISR as short as possible to avoid latency etc etc

In this case, i guess, you could remove the interrupt and do the job by reading the Timer register. Working 'round the multiple if/then statement you can improve it.

also...


OPTION_REG = %00000000
On Interrupt Goto myint
INTCON = $90


IF PORTA.0 = 1 THEN NINE
LOOP: serOUT PORTC.6,T9600,[#b5,#b4,#b3,#b2,#b1,13]

When you start the PIC and IF PORTA.0=1 you make it jump to the ISR? Bad practice :(

precision
- 12th September 2006, 14:36
Thanks mister_e ,

this is my code, i use timer as counter.
but it count upto 256 and reset to 0, I see datasheet timer0 is 8 bit
how i set to tomer1 on pic16f877

'-------- PIC16F84A -----------------------
DEFINE OSC 16 ' use 16 MHZ oscillator
INCLUDE "MYLCD.BAS" ' LCD ON PORTB

input PORTA.4

OPTION_REG = %10110000 ' TMR0 clock source : RA4/T0CKI
' increment on low to high transition
' Prescaler assign to WDT
' WDT rate 1:1


INTCON = %10100000 ' Enable global interrupt
' Enable TMR0 overflow interrupt

ClockInput var PORTA.4 ' Input pin for signal
COUNTER var word ' Result of count to be send to 7 segment display
OverFlowVar var word


COUNTER = 0 ' set initial value of count
TMR0 = 0 ' reset prescaller
on interrupt goto MyInit



LOOP:
lcdout $fe,1
lcdout "count ", dec5 COUNTER
pause 20

COUNTER = OverFlowVar+ TMR0
OverFlowVar = 0 ' Reset OverFlowVar
goto Loop


disable
MyInit:

OverFlowVar = OverFlowVar + 65535
INTCON.2 = 0 ' clear overflow flag
TMR0 = 0 ' reload TMR0
resume
enable

mister_e
- 12th September 2006, 22:21
As per the datasheet you'll have to use the PORTC.0 pin.


T1CON=%00000110 ' Prescaller 1:1
' osc=off
' no synchro
' ClockSource external PORTC.0